Changeset View
Changeset View
Standalone View
Standalone View
layers/selections/text/kpTextSelection_Paint.cpp
Show First 20 Lines • Show All 46 Lines • ▼ Show 20 Line(s) | |||||
47 | #include <QPainter> | 47 | #include <QPainter> | ||
48 | #include <QTextCharFormat> | 48 | #include <QTextCharFormat> | ||
49 | 49 | | |||
50 | //--------------------------------------------------------------------- | 50 | //--------------------------------------------------------------------- | ||
51 | 51 | | |||
52 | void kpTextSelection::drawPreeditString(QPainter &painter, int &x, int y, const kpPreeditText &preeditText) const | 52 | void kpTextSelection::drawPreeditString(QPainter &painter, int &x, int y, const kpPreeditText &preeditText) const | ||
53 | { | 53 | { | ||
54 | int i = 0; | 54 | int i = 0; | ||
55 | QString preeditString = preeditText.preeditString (); | 55 | const QString& preeditString = preeditText.preeditString (); | ||
56 | QString str; | 56 | QString str; | ||
57 | foreach (const QInputMethodEvent::Attribute &attr, preeditText.textFormatList ()) | 57 | for (const auto &attr : preeditText.textFormatList ()) | ||
58 | { | 58 | { | ||
59 | int start = attr.start; | 59 | int start = attr.start; | ||
60 | int length = attr.length; | 60 | int length = attr.length; | ||
61 | QTextCharFormat format = qvariant_cast<QTextFormat> (attr.value).toCharFormat (); | 61 | QTextCharFormat format = qvariant_cast<QTextFormat> (attr.value).toCharFormat (); | ||
62 | 62 | | |||
63 | if (i > start) | 63 | if (i > start) | ||
64 | { | 64 | { | ||
65 | length = length - i + start; | 65 | length = length - i + start; | ||
66 | start = i; | 66 | start = i; | ||
67 | } | 67 | } | ||
68 | if (length <= 0) continue; | 68 | if (length <= 0) { | ||
69 | continue; | ||||
70 | } | ||||
69 | 71 | | |||
70 | if (i < start) | 72 | if (i < start) | ||
71 | { | 73 | { | ||
72 | str = preeditString.mid (i, start - i); | 74 | str = preeditString.mid (i, start - i); | ||
73 | painter.drawText (x, y, str); | 75 | painter.drawText (x, y, str); | ||
74 | x += painter.fontMetrics ().width (str); | 76 | x += painter.fontMetrics ().width (str); | ||
75 | } | 77 | } | ||
76 | 78 | | |||
Show All 36 Lines | |||||
113 | 115 | | |||
114 | // public virtual [kpAbstractSelection] | 116 | // public virtual [kpAbstractSelection] | ||
115 | void kpTextSelection::paint(QImage *destPixmap, const QRect &docRect) const | 117 | void kpTextSelection::paint(QImage *destPixmap, const QRect &docRect) const | ||
116 | { | 118 | { | ||
117 | #if DEBUG_KP_SELECTION | 119 | #if DEBUG_KP_SELECTION | ||
118 | qCDebug(kpLogLayers) << "kpTextSelection::paint() textStyle: fcol=" | 120 | qCDebug(kpLogLayers) << "kpTextSelection::paint() textStyle: fcol=" | ||
119 | << (int *) d->textStyle.foregroundColor ().toQRgb () | 121 | << (int *) d->textStyle.foregroundColor ().toQRgb () | ||
120 | << " bcol=" | 122 | << " bcol=" | ||
121 | << (int *) d->textStyle.backgroundColor ().toQRgb () | 123 | << (int *) d->textStyle.backgroundColor ().toQRgb (); | ||
122 | << endl; | | |||
123 | #endif | 124 | #endif | ||
124 | 125 | | |||
125 | // Drawing text is slow so if the text box will be rendered completely | 126 | // Drawing text is slow so if the text box will be rendered completely | ||
126 | // outside of <destRect>, don't bother rendering it at all. | 127 | // outside of <destRect>, don't bother rendering it at all. | ||
127 | const QRect modifyingRect = docRect.intersected (boundingRect ()); | 128 | const QRect modifyingRect = docRect.intersected (boundingRect ()); | ||
128 | if (modifyingRect.isEmpty ()) | 129 | if (modifyingRect.isEmpty ()) { | ||
129 | return; | 130 | return; | ||
131 | } | ||||
130 | 132 | | |||
131 | 133 | | |||
132 | // Is the text box completely invisible? | 134 | // Is the text box completely invisible? | ||
133 | if (textStyle ().foregroundColor ().isTransparent () && | 135 | if (textStyle ().foregroundColor ().isTransparent () && | ||
134 | textStyle ().backgroundColor ().isTransparent ()) | 136 | textStyle ().backgroundColor ().isTransparent ()) | ||
135 | { | 137 | { | ||
136 | return; | 138 | return; | ||
137 | } | 139 | } | ||
Show All 11 Lines | |||||
149 | const QFontMetrics fontMetrics (theTextStyle.font ()); | 151 | const QFontMetrics fontMetrics (theTextStyle.font ()); | ||
150 | 152 | | |||
151 | #if DEBUG_KP_SELECTION | 153 | #if DEBUG_KP_SELECTION | ||
152 | qCDebug(kpLogLayers) << "kpTextSelection_Paint.cpp:DrawTextHelper"; | 154 | qCDebug(kpLogLayers) << "kpTextSelection_Paint.cpp:DrawTextHelper"; | ||
153 | qCDebug(kpLogLayers) << "\theight=" << fontMetrics.height () | 155 | qCDebug(kpLogLayers) << "\theight=" << fontMetrics.height () | ||
154 | << " leading=" << fontMetrics.leading () | 156 | << " leading=" << fontMetrics.leading () | ||
155 | << " ascent=" << fontMetrics.ascent () | 157 | << " ascent=" << fontMetrics.ascent () | ||
156 | << " descent=" << fontMetrics.descent () | 158 | << " descent=" << fontMetrics.descent () | ||
157 | << " lineSpacing=" << fontMetrics.lineSpacing () | 159 | << " lineSpacing=" << fontMetrics.lineSpacing (); | ||
158 | << endl; | | |||
159 | #endif | 160 | #endif | ||
160 | 161 | | |||
161 | QPainter painter(&floatImage); | 162 | QPainter painter(&floatImage); | ||
162 | 163 | | |||
163 | // Fill in the background using the transparent/opaque tool setting | 164 | // Fill in the background using the transparent/opaque tool setting | ||
164 | if ( theTextStyle.isBackgroundTransparent() ) | 165 | if ( theTextStyle.isBackgroundTransparent() ) { | ||
165 | painter.fillRect(theWholeAreaRect, Qt::transparent); | 166 | painter.fillRect(theWholeAreaRect, Qt::transparent); | ||
166 | else | 167 | } | ||
168 | else { | ||||
167 | painter.fillRect(theWholeAreaRect, theTextStyle.backgroundColor().toQColor()); | 169 | painter.fillRect(theWholeAreaRect, theTextStyle.backgroundColor().toQColor()); | ||
170 | } | ||||
168 | 171 | | |||
169 | painter.setClipRect(theWholeAreaRect); | 172 | painter.setClipRect(theWholeAreaRect); | ||
170 | painter.setPen(theTextStyle.foregroundColor().toQColor()); | 173 | painter.setPen(theTextStyle.foregroundColor().toQColor()); | ||
171 | painter.setFont(theTextStyle.font()); | 174 | painter.setFont(theTextStyle.font()); | ||
172 | 175 | | |||
173 | if ( theTextStyle.foregroundColor().toQColor().alpha() < 255 ) | 176 | if ( theTextStyle.foregroundColor().toQColor().alpha() < 255 ) | ||
174 | { | 177 | { | ||
175 | // if the foreground color has an alpha channel, we want to | 178 | // if the foreground color has an alpha channel, we want to | ||
176 | // see through the background, so we first need to punch holes | 179 | // see through the background, so we first need to punch holes | ||
177 | // into the background where the text is | 180 | // into the background where the text is | ||
178 | painter.setCompositionMode(QPainter::CompositionMode_Clear); | 181 | painter.setCompositionMode(QPainter::CompositionMode_Clear); | ||
179 | 182 | | |||
180 | int baseLine = theTextAreaRect.y () + fontMetrics.ascent (); | 183 | int baseLine = theTextAreaRect.y () + fontMetrics.ascent (); | ||
181 | foreach (const QString &str, theTextLines) | 184 | for (const auto &str : theTextLines) | ||
182 | { | 185 | { | ||
183 | painter.drawText (theTextAreaRect.x (), baseLine, str); | 186 | painter.drawText (theTextAreaRect.x (), baseLine, str); | ||
184 | baseLine += fontMetrics.lineSpacing (); | 187 | baseLine += fontMetrics.lineSpacing (); | ||
185 | 188 | | |||
186 | // if the next textline would already be below the visible text area, stop drawing | 189 | // if the next textline would already be below the visible text area, stop drawing | ||
187 | if ( (baseLine - fontMetrics.ascent()) > (theTextAreaRect.y() + theTextAreaRect.height()) ) | 190 | if ( (baseLine - fontMetrics.ascent()) > (theTextAreaRect.y() + theTextAreaRect.height()) ) { | ||
188 | break; | 191 | break; | ||
189 | } | 192 | } | ||
193 | } | ||||
190 | // the next text drawing will now blend the text foreground color with | 194 | // the next text drawing will now blend the text foreground color with | ||
191 | // what is really below the text background | 195 | // what is really below the text background | ||
192 | painter.setCompositionMode(QPainter::CompositionMode_SourceOver); | 196 | painter.setCompositionMode(QPainter::CompositionMode_SourceOver); | ||
193 | } | 197 | } | ||
194 | 198 | | |||
195 | // Draw a line at a time instead of using QPainter::drawText(QRect,...). | 199 | // Draw a line at a time instead of using QPainter::drawText(QRect,...). | ||
196 | // Else, the line heights become >QFontMetrics::height() if you type Chinese | 200 | // Else, the line heights become >QFontMetrics::height() if you type Chinese | ||
197 | // characters (!) and then the cursor gets out of sync. | 201 | // characters (!) and then the cursor gets out of sync. | ||
Show All 9 Lines | 209 | { | |||
207 | drawPreeditString(painter, x, baseLine, thePreeditText); | 211 | drawPreeditString(painter, x, baseLine, thePreeditText); | ||
208 | } | 212 | } | ||
209 | } | 213 | } | ||
210 | else | 214 | else | ||
211 | { | 215 | { | ||
212 | int i = 0; | 216 | int i = 0; | ||
213 | int row = thePreeditText.position().y(); | 217 | int row = thePreeditText.position().y(); | ||
214 | int col = thePreeditText.position().x(); | 218 | int col = thePreeditText.position().x(); | ||
215 | foreach (const QString &str, theTextLines) | 219 | for (const auto &str : theTextLines) | ||
216 | { | 220 | { | ||
217 | if (row == i && !thePreeditText.isEmpty()) | 221 | if (row == i && !thePreeditText.isEmpty()) | ||
218 | { | 222 | { | ||
219 | QString left = str.left(col); | 223 | QString left = str.left(col); | ||
220 | QString right = str.mid(col); | 224 | QString right = str.mid(col); | ||
221 | int x = theTextAreaRect.x(); | 225 | int x = theTextAreaRect.x(); | ||
222 | painter.drawText(x, baseLine, left); | 226 | painter.drawText(x, baseLine, left); | ||
223 | x += fontMetrics.width(left); | 227 | x += fontMetrics.width(left); | ||
224 | drawPreeditString(painter, x, baseLine, thePreeditText); | 228 | drawPreeditString(painter, x, baseLine, thePreeditText); | ||
225 | 229 | | |||
226 | painter.drawText(x, baseLine, right); | 230 | painter.drawText(x, baseLine, right); | ||
227 | } | 231 | } | ||
228 | else | 232 | else | ||
229 | { | 233 | { | ||
230 | painter.drawText(theTextAreaRect.x (), baseLine, str); | 234 | painter.drawText(theTextAreaRect.x (), baseLine, str); | ||
231 | } | 235 | } | ||
232 | baseLine += fontMetrics.lineSpacing(); | 236 | baseLine += fontMetrics.lineSpacing(); | ||
233 | i++; | 237 | i++; | ||
234 | 238 | | |||
235 | // if the next textline would already be below the visible text area, stop drawing | 239 | // if the next textline would already be below the visible text area, stop drawing | ||
236 | if ( (baseLine - fontMetrics.ascent()) > (theTextAreaRect.y() + theTextAreaRect.height()) ) | 240 | if ( (baseLine - fontMetrics.ascent()) > (theTextAreaRect.y() + theTextAreaRect.height()) ) { | ||
237 | break; | 241 | break; | ||
238 | } | 242 | } | ||
239 | } | 243 | } | ||
244 | } | ||||
240 | 245 | | |||
241 | // ... convert that into "painting" transparent pixels on top of | 246 | // ... convert that into "painting" transparent pixels on top of | ||
242 | // the document. | 247 | // the document. | ||
243 | kpPixmapFX::paintPixmapAt (destPixmap, | 248 | kpPixmapFX::paintPixmapAt (destPixmap, | ||
244 | modifyingRect.topLeft () - docRect.topLeft (), | 249 | modifyingRect.topLeft () - docRect.topLeft (), | ||
245 | floatImage); | 250 | floatImage); | ||
246 | } | 251 | } | ||
247 | 252 | | |||
Show All 22 Lines |