void CGTextArea::PaintText (CG32bitImage &Dest, const RECT &rcRect) // PaintText // // Paint plain text { // Paint the text if (m_pFont) { // If we haven't justified the text for this size, do it now if (m_cxJustifyWidth != RectWidth(rcRect)) { m_cxJustifyWidth = RectWidth(rcRect); m_Lines.DeleteAll(); m_pFont->BreakText(m_sText, m_cxJustifyWidth, &m_Lines, CG16bitFont::SmartQuotes); } // Compute the rect within which we draw the text RECT rcText = rcRect; if (m_bEditable) { int iVSpacing = (RectHeight(rcRect) - m_pFont->GetHeight()) / 2; rcText.left += iVSpacing; rcText.right -= iVSpacing; rcText.top += iVSpacing; rcText.bottom -= iVSpacing; } // Clip to text rect RECT rcOldClip = Dest.GetClipRect(); Dest.SetClipRect(rcText); // Figure out how many lines fit in the rect int iMaxLineCount = RectHeight(rcText) / m_pFont->GetHeight(); // If there are too many lines, and we're editable, start at the end int iStart = 0; if (m_bEditable && iMaxLineCount < m_Lines.GetCount()) iStart = m_Lines.GetCount() - iMaxLineCount; // Paint each line int x = rcText.left; int y = rcText.top; for (int i = iStart; i < m_Lines.GetCount(); i++) { CString sLine = m_Lines[i]; // Trim the last space in the line, if necessary char *pPos = sLine.GetASCIIZPointer(); if (sLine.GetLength() > 0 && pPos[sLine.GetLength() - 1] == ' ') sLine = strTrimWhitespace(sLine); // Alignment int xLine; if (m_dwStyles & alignCenter) { int cxWidth = m_pFont->MeasureText(sLine); xLine = x + (RectWidth(rcText) - cxWidth) / 2; } else if (m_dwStyles & alignRight) { int cxWidth = m_pFont->MeasureText(sLine); xLine = x + (RectWidth(rcRect) - cxWidth); } else xLine = x; // Paint if (HasEffects()) m_pFont->DrawTextEffect(Dest, xLine, y, m_rgbColor, sLine, GetEffectCount(), GetEffects()); else Dest.DrawText(xLine, y, *m_pFont, m_rgbColor, sLine); // Next y += m_pFont->GetHeight() + m_cyLineSpacing; if (y >= rcText.bottom) break; } // Paint the cursor if (m_bEditable && m_iCursorLine >= iStart) { int cxPos = (m_iCursorLine < m_Lines.GetCount() ? m_pFont->MeasureText(CString(m_Lines[m_iCursorLine].GetASCIIZPointer(), m_iCursorPos, true)) : 0); int y = rcText.top + (m_iCursorLine - iStart) * (m_pFont->GetHeight() + m_cyLineSpacing); int x = rcText.left; if (m_dwStyles & alignCenter) { int cxWidth = (m_iCursorLine < m_Lines.GetCount() ? m_pFont->MeasureText(m_Lines[m_iCursorLine]) : 0); x += ((RectWidth(rcText) - cxWidth) / 2) + cxPos; } else if (m_dwStyles & alignRight) { int cxWidth = (m_iCursorLine < m_Lines.GetCount() ? m_pFont->MeasureText(m_Lines[m_iCursorLine]) : 0); x += (RectWidth(rcText) - cxWidth) + cxPos; } else x += cxPos; if (((m_iTick / 30) % 2) > 0) { Dest.Fill(x, y, 2, m_pFont->GetHeight(), RGB_CURSOR); } } // Restore clip Dest.SetClipRect(rcOldClip); } }