Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "config.h" | 5 #include "config.h" |
| 6 #include "core/paint/InlineTextBoxPainter.h" | 6 #include "core/paint/InlineTextBoxPainter.h" |
| 7 | 7 |
| 8 #include "core/editing/CompositionUnderline.h" | 8 #include "core/editing/CompositionUnderline.h" |
| 9 #include "core/editing/Editor.h" | 9 #include "core/editing/Editor.h" |
| 10 #include "core/editing/markers/DocumentMarkerController.h" | 10 #include "core/editing/markers/DocumentMarkerController.h" |
| (...skipping 138 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 149 bool paintSelectedTextSeparately = !paintSelectedTextOnly && textStyle != se lectionStyle; | 149 bool paintSelectedTextSeparately = !paintSelectedTextOnly && textStyle != se lectionStyle; |
| 150 | 150 |
| 151 // Set our font. | 151 // Set our font. |
| 152 const Font& font = styleToUse.font(); | 152 const Font& font = styleToUse.font(); |
| 153 | 153 |
| 154 LayoutPoint textOrigin(boxOrigin.x(), boxOrigin.y() + font.fontMetrics().asc ent()); | 154 LayoutPoint textOrigin(boxOrigin.x(), boxOrigin.y() + font.fontMetrics().asc ent()); |
| 155 | 155 |
| 156 // 1. Paint backgrounds behind text if needed. Examples of such backgrounds include selection | 156 // 1. Paint backgrounds behind text if needed. Examples of such backgrounds include selection |
| 157 // and composition highlights. | 157 // and composition highlights. |
| 158 if (paintInfo.phase != PaintPhaseSelection && paintInfo.phase != PaintPhaseT extClip && !isPrinting) { | 158 if (paintInfo.phase != PaintPhaseSelection && paintInfo.phase != PaintPhaseT extClip && !isPrinting) { |
| 159 paintDocumentMarkers(context, boxOrigin, styleToUse, font, true); | 159 paintDocumentMarkers(paintInfo, boxOrigin, styleToUse, font, true); |
| 160 | 160 |
| 161 if (haveSelection && !paintsCompositionMarkers(textBoxLayoutObject)) { | 161 if (haveSelection && !paintsCompositionMarkers(textBoxLayoutObject)) { |
| 162 if (combinedText) | 162 if (combinedText) |
| 163 paintSelection<InlineTextBoxPainter::PaintOptions::CombinedText> (context, boxRect, styleToUse, font, selectionStyle.fillColor, combinedText); | 163 paintSelection<InlineTextBoxPainter::PaintOptions::CombinedText> (context, boxRect, styleToUse, font, selectionStyle.fillColor, combinedText); |
| 164 else | 164 else |
| 165 paintSelection<InlineTextBoxPainter::PaintOptions::Normal>(conte xt, boxRect, styleToUse, font, selectionStyle.fillColor); | 165 paintSelection<InlineTextBoxPainter::PaintOptions::Normal>(conte xt, boxRect, styleToUse, font, selectionStyle.fillColor); |
| 166 } | 166 } |
| 167 } | 167 } |
| 168 | 168 |
| 169 // 2. Now paint the foreground, including text and decorations like underlin e/overline (in quirks mode only). | 169 // 2. Now paint the foreground, including text and decorations like underlin e/overline (in quirks mode only). |
| (...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 236 GraphicsContextStateSaver stateSaver(context, false); | 236 GraphicsContextStateSaver stateSaver(context, false); |
| 237 TextPainter::updateGraphicsContext(context, textStyle, m_inlineTextBox.i sHorizontal(), stateSaver); | 237 TextPainter::updateGraphicsContext(context, textStyle, m_inlineTextBox.i sHorizontal(), stateSaver); |
| 238 if (combinedText) | 238 if (combinedText) |
| 239 context.concatCTM(TextPainter::rotation(boxRect, TextPainter::Clockw ise)); | 239 context.concatCTM(TextPainter::rotation(boxRect, TextPainter::Clockw ise)); |
| 240 paintDecoration(paintInfo, boxOrigin, textDecorations); | 240 paintDecoration(paintInfo, boxOrigin, textDecorations); |
| 241 if (combinedText) | 241 if (combinedText) |
| 242 context.concatCTM(TextPainter::rotation(boxRect, TextPainter::Counte rclockwise)); | 242 context.concatCTM(TextPainter::rotation(boxRect, TextPainter::Counte rclockwise)); |
| 243 } | 243 } |
| 244 | 244 |
| 245 if (paintInfo.phase == PaintPhaseForeground) | 245 if (paintInfo.phase == PaintPhaseForeground) |
| 246 paintDocumentMarkers(context, boxOrigin, styleToUse, font, false); | 246 paintDocumentMarkers(paintInfo, boxOrigin, styleToUse, font, false); |
| 247 | 247 |
| 248 if (shouldRotate) | 248 if (shouldRotate) |
| 249 context.concatCTM(TextPainter::rotation(boxRect, TextPainter::Counterclo ckwise)); | 249 context.concatCTM(TextPainter::rotation(boxRect, TextPainter::Counterclo ckwise)); |
| 250 } | 250 } |
| 251 | 251 |
| 252 bool InlineTextBoxPainter::shouldPaintTextBox(const PaintInfo& paintInfo) | 252 bool InlineTextBoxPainter::shouldPaintTextBox(const PaintInfo& paintInfo) |
| 253 { | 253 { |
| 254 // When painting selection, we want to include a highlight when the | 254 // When painting selection, we want to include a highlight when the |
| 255 // selection spans line breaks. In other cases such as invisible elements | 255 // selection spans line breaks. In other cases such as invisible elements |
| 256 // or those with no text that are not line breaks, we can skip painting | 256 // or those with no text that are not line breaks, we can skip painting |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 291 int ePos = std::min(endPos - static_cast<int>(m_inlineTextBox.start()), stat ic_cast<int>(m_inlineTextBox.len())); | 291 int ePos = std::min(endPos - static_cast<int>(m_inlineTextBox.start()), stat ic_cast<int>(m_inlineTextBox.len())); |
| 292 if (sPos >= ePos) | 292 if (sPos >= ePos) |
| 293 return; | 293 return; |
| 294 | 294 |
| 295 int deltaY = m_inlineTextBox.lineLayoutItem().style()->isFlippedLinesWriting Mode() ? m_inlineTextBox.root().selectionBottom() - m_inlineTextBox.logicalBotto m() : m_inlineTextBox.logicalTop() - m_inlineTextBox.root().selectionTop(); | 295 int deltaY = m_inlineTextBox.lineLayoutItem().style()->isFlippedLinesWriting Mode() ? m_inlineTextBox.root().selectionBottom() - m_inlineTextBox.logicalBotto m() : m_inlineTextBox.logicalTop() - m_inlineTextBox.root().selectionTop(); |
| 296 int selHeight = m_inlineTextBox.root().selectionHeight(); | 296 int selHeight = m_inlineTextBox.root().selectionHeight(); |
| 297 FloatPoint localOrigin(boxOrigin.x().toFloat(), boxOrigin.y().toFloat() - de ltaY); | 297 FloatPoint localOrigin(boxOrigin.x().toFloat(), boxOrigin.y().toFloat() - de ltaY); |
| 298 context.drawHighlightForText(font, m_inlineTextBox.constructTextRun(style, f ont), localOrigin, selHeight, backgroundColor, sPos, ePos); | 298 context.drawHighlightForText(font, m_inlineTextBox.constructTextRun(style, f ont), localOrigin, selHeight, backgroundColor, sPos, ePos); |
| 299 } | 299 } |
| 300 | 300 |
| 301 void InlineTextBoxPainter::paintDocumentMarkers(GraphicsContext& context, const LayoutPoint& boxOrigin, const ComputedStyle& style, const Font& font, bool backg round) | 301 void InlineTextBoxPainter::paintDocumentMarkers(const PaintInfo& paintInfo, cons t LayoutPoint& boxOrigin, const ComputedStyle& style, const Font& font, bool bac kground) |
| 302 { | 302 { |
| 303 if (!m_inlineTextBox.lineLayoutItem().node()) | 303 if (!m_inlineTextBox.lineLayoutItem().node()) |
| 304 return; | 304 return; |
| 305 | 305 |
| 306 DocumentMarkerVector markers = m_inlineTextBox.lineLayoutItem().document().m arkers().markersFor(m_inlineTextBox.lineLayoutItem().node()); | 306 DocumentMarkerVector markers = m_inlineTextBox.lineLayoutItem().document().m arkers().markersFor(m_inlineTextBox.lineLayoutItem().node()); |
| 307 DocumentMarkerVector::const_iterator markerIt = markers.begin(); | 307 DocumentMarkerVector::const_iterator markerIt = markers.begin(); |
| 308 | 308 |
| 309 // Give any document markers that touch this run a chance to draw before the text has been drawn. | 309 // Give any document markers that touch this run a chance to draw before the text has been drawn. |
| 310 // Note end() points at the last char, not one past it like endOffset and ra nges do. | 310 // Note end() points at the last char, not one past it like endOffset and ra nges do. |
| 311 for ( ; markerIt != markers.end(); ++markerIt) { | 311 for ( ; markerIt != markers.end(); ++markerIt) { |
| 312 DocumentMarker* marker = *markerIt; | 312 DocumentMarker* marker = *markerIt; |
| 313 | 313 |
| 314 // Paint either the background markers or the foreground markers, but no t both | 314 // Paint either the background markers or the foreground markers, but no t both |
| 315 switch (marker->type()) { | 315 switch (marker->type()) { |
| 316 case DocumentMarker::Grammar: | 316 case DocumentMarker::Grammar: |
| 317 case DocumentMarker::Spelling: | 317 case DocumentMarker::Spelling: |
| 318 if (background) | 318 if (background) |
| 319 continue; | 319 continue; |
| 320 break; | 320 break; |
| 321 case DocumentMarker::TextMatch: | 321 case DocumentMarker::TextMatch: |
| 322 if (!background) | |
| 323 continue; | |
| 324 break; | 322 break; |
|
fs
2015/12/17 10:10:54
Nit: Maybe drop this too now that TextMatch is in
ramya.v
2015/12/18 03:43:32
Done.
| |
| 325 case DocumentMarker::Composition: | 323 case DocumentMarker::Composition: |
| 326 break; | 324 break; |
| 327 default: | 325 default: |
| 328 continue; | 326 continue; |
| 329 } | 327 } |
| 330 | 328 |
| 331 if (marker->endOffset() <= m_inlineTextBox.start()) { | 329 if (marker->endOffset() <= m_inlineTextBox.start()) { |
| 332 // marker is completely before this run. This might be a marker tha t sits before the | 330 // marker is completely before this run. This might be a marker tha t sits before the |
| 333 // first run we draw, or markers that were within runs we skipped du e to truncation. | 331 // first run we draw, or markers that were within runs we skipped du e to truncation. |
| 334 continue; | 332 continue; |
| 335 } | 333 } |
| 336 if (marker->startOffset() > m_inlineTextBox.end()) { | 334 if (marker->startOffset() > m_inlineTextBox.end()) { |
| 337 // marker is completely after this run, bail. A later run will pain t it. | 335 // marker is completely after this run, bail. A later run will pain t it. |
| 338 break; | 336 break; |
| 339 } | 337 } |
| 340 | 338 |
| 341 // marker intersects this run. Paint it. | 339 // marker intersects this run. Paint it. |
| 342 switch (marker->type()) { | 340 switch (marker->type()) { |
| 343 case DocumentMarker::Spelling: | 341 case DocumentMarker::Spelling: |
| 344 m_inlineTextBox.paintDocumentMarker(context, boxOrigin, marker, styl e, font, false); | 342 m_inlineTextBox.paintDocumentMarker(paintInfo.context, boxOrigin, ma rker, style, font, false); |
| 345 break; | 343 break; |
| 346 case DocumentMarker::Grammar: | 344 case DocumentMarker::Grammar: |
| 347 m_inlineTextBox.paintDocumentMarker(context, boxOrigin, marker, styl e, font, true); | 345 m_inlineTextBox.paintDocumentMarker(paintInfo.context, boxOrigin, ma rker, style, font, true); |
| 348 break; | 346 break; |
| 349 case DocumentMarker::TextMatch: | 347 case DocumentMarker::TextMatch: |
| 350 m_inlineTextBox.paintTextMatchMarker(context, boxOrigin, marker, sty le, font); | 348 if (background) |
| 349 m_inlineTextBox.paintTextMatchMarkerBackground(paintInfo, boxOri gin, marker, style, font); | |
| 350 else | |
| 351 m_inlineTextBox.paintTextMatchMarkerForeground(paintInfo, boxOri gin, marker, style, font); | |
| 351 break; | 352 break; |
| 352 case DocumentMarker::Composition: | 353 case DocumentMarker::Composition: |
| 353 { | 354 { |
| 354 CompositionUnderline underline(marker->startOffset(), marker->en dOffset(), marker->underlineColor(), marker->thick(), marker->backgroundColor()) ; | 355 CompositionUnderline underline(marker->startOffset(), marker->en dOffset(), marker->underlineColor(), marker->thick(), marker->backgroundColor()) ; |
| 355 if (background) | 356 if (background) |
| 356 paintSingleCompositionBackgroundRun(context, boxOrigin, styl e, font, underline.backgroundColor, underlinePaintStart(underline), underlinePai ntEnd(underline)); | 357 paintSingleCompositionBackgroundRun(paintInfo.context, boxOr igin, style, font, underline.backgroundColor, underlinePaintStart(underline), un derlinePaintEnd(underline)); |
| 357 else | 358 else |
| 358 paintCompositionUnderline(context, boxOrigin, underline); | 359 paintCompositionUnderline(paintInfo.context, boxOrigin, unde rline); |
| 359 } | 360 } |
| 360 break; | 361 break; |
| 361 default: | 362 default: |
| 362 ASSERT_NOT_REACHED(); | 363 ASSERT_NOT_REACHED(); |
| 363 } | 364 } |
| 364 } | 365 } |
| 365 } | 366 } |
| 366 | 367 |
| 367 static GraphicsContext::DocumentMarkerLineStyle lineStyleForMarkerType(DocumentM arker::MarkerType markerType) | 368 static GraphicsContext::DocumentMarkerLineStyle lineStyleForMarkerType(DocumentM arker::MarkerType markerType) |
| 368 { | 369 { |
| (...skipping 454 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 823 // We need to have some space between underlines of subsequent clauses, beca use some input methods do not use different underline styles for those. | 824 // We need to have some space between underlines of subsequent clauses, beca use some input methods do not use different underline styles for those. |
| 824 // We make each line shorter, which has a harmless side effect of shortening the first and last clauses, too. | 825 // We make each line shorter, which has a harmless side effect of shortening the first and last clauses, too. |
| 825 start += 1; | 826 start += 1; |
| 826 width -= 2; | 827 width -= 2; |
| 827 | 828 |
| 828 context.setStrokeColor(underline.color); | 829 context.setStrokeColor(underline.color); |
| 829 context.setStrokeThickness(lineThickness); | 830 context.setStrokeThickness(lineThickness); |
| 830 context.drawLineForText(FloatPoint(boxOrigin.x() + start, (boxOrigin.y() + m _inlineTextBox.logicalHeight() - lineThickness).toFloat()), width, m_inlineTextB ox.lineLayoutItem().document().printing()); | 831 context.drawLineForText(FloatPoint(boxOrigin.x() + start, (boxOrigin.y() + m _inlineTextBox.logicalHeight() - lineThickness).toFloat()), width, m_inlineTextB ox.lineLayoutItem().document().printing()); |
| 831 } | 832 } |
| 832 | 833 |
| 833 void InlineTextBoxPainter::paintTextMatchMarker(GraphicsContext& context, const LayoutPoint& boxOrigin, DocumentMarker* marker, const ComputedStyle& style, cons t Font& font) | 834 void InlineTextBoxPainter::paintTextMatchMarkerForeground(const PaintInfo& paint Info, const LayoutPoint& boxOrigin, DocumentMarker* marker, const ComputedStyle& style, const Font& font) |
| 834 { | 835 { |
| 836 if (!LineLayoutPaintShim::layoutObjectFrom(m_inlineTextBox.lineLayoutItem()) ->frame()->editor().markedTextMatchesAreHighlighted()) | |
| 837 return; | |
| 838 | |
| 839 // TODO(ramya.v): Extract this into a helper function and share many copies of this code. | |
| 840 int sPos = std::max(marker->startOffset() - m_inlineTextBox.start(), (unsign ed)0); | |
| 841 int ePos = std::min(marker->endOffset() - m_inlineTextBox.start(), m_inlineT extBox.len()); | |
| 842 TextRun run = m_inlineTextBox.constructTextRun(style, font); | |
| 843 | |
| 844 Color textColor = marker->activeMatch() ? | |
|
fs
2015/12/17 10:10:54
Could just pass the predicate as the argument inst
ramya.v
2015/12/18 03:43:32
Done.
| |
| 845 LayoutTheme::theme().platformTextSearchColor(true) : | |
| 846 LayoutTheme::theme().platformTextSearchColor(false); | |
| 847 if (style.visitedDependentColor(CSSPropertyColor) == textColor) | |
| 848 return; | |
| 849 TextPainter::Style textStyle; | |
| 850 // When we use the text as a clip, we only care about the alpha, thus we mak e all the colors black. | |
|
fs
2015/12/17 10:10:54
This comment doesn't appear to make much sense in
ramya.v
2015/12/18 03:43:32
Done.
| |
| 851 textStyle.currentColor = textStyle.fillColor = textStyle.strokeColor = textS tyle.emphasisMarkColor = textColor; | |
| 852 textStyle.strokeWidth = style.textStrokeWidth(); | |
| 853 textStyle.shadow = 0; | |
| 854 | |
| 855 LayoutRect boxRect(boxOrigin, LayoutSize(m_inlineTextBox.logicalWidth(), m_i nlineTextBox.logicalHeight())); | |
| 856 LayoutPoint textOrigin(boxOrigin.x(), boxOrigin.y() + font.fontMetrics().asc ent()); | |
| 857 TextPainter textPainter(paintInfo.context, font, run, textOrigin, boxRect, m _inlineTextBox.isHorizontal()); | |
| 858 | |
| 859 textPainter.paint(sPos, ePos, m_inlineTextBox.len(), textStyle, 0); | |
| 860 } | |
| 861 | |
| 862 void InlineTextBoxPainter::paintTextMatchMarkerBackground(const PaintInfo& paint Info, const LayoutPoint& boxOrigin, DocumentMarker* marker, const ComputedStyle& style, const Font& font) | |
| 863 { | |
| 864 if (!LineLayoutPaintShim::layoutObjectFrom(m_inlineTextBox.lineLayoutItem()) ->frame()->editor().markedTextMatchesAreHighlighted()) | |
| 865 return; | |
| 866 | |
| 835 // Use same y positioning and height as for selection, so that when the sele ction and this highlight are on | 867 // Use same y positioning and height as for selection, so that when the sele ction and this highlight are on |
| 836 // the same word there are no pieces sticking out. | 868 // the same word there are no pieces sticking out. |
| 837 int deltaY = m_inlineTextBox.lineLayoutItem().style()->isFlippedLinesWriting Mode() ? m_inlineTextBox.root().selectionBottom() - m_inlineTextBox.logicalBotto m() : m_inlineTextBox.logicalTop() - m_inlineTextBox.root().selectionTop(); | 869 int deltaY = m_inlineTextBox.lineLayoutItem().style()->isFlippedLinesWriting Mode() ? m_inlineTextBox.root().selectionBottom() - m_inlineTextBox.logicalBotto m() : m_inlineTextBox.logicalTop() - m_inlineTextBox.root().selectionTop(); |
| 838 int selHeight = m_inlineTextBox.root().selectionHeight(); | 870 int selHeight = m_inlineTextBox.root().selectionHeight(); |
| 839 | 871 |
| 840 int sPos = std::max(marker->startOffset() - m_inlineTextBox.start(), (unsign ed)0); | 872 int sPos = std::max(marker->startOffset() - m_inlineTextBox.start(), (unsign ed)0); |
| 841 int ePos = std::min(marker->endOffset() - m_inlineTextBox.start(), m_inlineT extBox.len()); | 873 int ePos = std::min(marker->endOffset() - m_inlineTextBox.start(), m_inlineT extBox.len()); |
| 842 TextRun run = m_inlineTextBox.constructTextRun(style, font); | 874 TextRun run = m_inlineTextBox.constructTextRun(style, font); |
| 843 | 875 |
| 844 // Optionally highlight the text | 876 Color color = marker->activeMatch() ? |
|
fs
2015/12/17 10:10:54
Same suggestion as for the equivalent code above (
ramya.v
2015/12/18 03:43:32
Done.
| |
| 845 if (LineLayoutPaintShim::layoutObjectFrom(m_inlineTextBox.lineLayoutItem())- >frame()->editor().markedTextMatchesAreHighlighted()) { | 877 LayoutTheme::theme().platformTextSearchHighlightColor(true) : |
| 846 Color color = marker->activeMatch() ? | 878 LayoutTheme::theme().platformTextSearchHighlightColor(false); |
| 847 LayoutTheme::theme().platformActiveTextSearchHighlightColor() : | 879 GraphicsContext& pt = paintInfo.context; |
|
fs
2015/12/17 10:10:54
pt -> context
ramya.v
2015/12/18 03:43:32
Done.
| |
| 848 LayoutTheme::theme().platformInactiveTextSearchHighlightColor(); | 880 GraphicsContextStateSaver stateSaver(pt); |
| 849 GraphicsContextStateSaver stateSaver(context); | 881 pt.clip(FloatRect(boxOrigin.x().toFloat(), (boxOrigin.y() - deltaY).toFloat( ), m_inlineTextBox.logicalWidth().toFloat(), selHeight)); |
| 850 context.clip(FloatRect(boxOrigin.x().toFloat(), (boxOrigin.y() - deltaY) .toFloat(), m_inlineTextBox.logicalWidth().toFloat(), selHeight)); | 882 pt.drawHighlightForText(font, run, FloatPoint(boxOrigin.x().toFloat(), (boxO rigin.y() - deltaY).toFloat()), selHeight, color, sPos, ePos); |
| 851 context.drawHighlightForText(font, run, FloatPoint(boxOrigin.x().toFloat (), (boxOrigin.y() - deltaY).toFloat()), selHeight, color, sPos, ePos); | |
| 852 | |
| 853 // Also Highlight the text with color:transparent | |
| 854 if (style.visitedDependentColor(CSSPropertyColor) == Color::transparent) { | |
| 855 int length = m_inlineTextBox.len(); | |
| 856 TextPainter::Style textStyle; | |
| 857 // When we use the text as a clip, we only care about the alpha, thu s we make all the colors black. | |
| 858 textStyle.currentColor = textStyle.fillColor = textStyle.strokeColor = textStyle.emphasisMarkColor = Color::black; | |
| 859 textStyle.strokeWidth = style.textStrokeWidth(); | |
| 860 textStyle.shadow = 0; | |
| 861 | |
| 862 LayoutRect boxRect(boxOrigin, LayoutSize(m_inlineTextBox.logicalWidt h(), m_inlineTextBox.logicalHeight())); | |
| 863 LayoutPoint textOrigin(boxOrigin.x(), boxOrigin.y() + font.fontMetri cs().ascent()); | |
| 864 TextPainter textPainter(context, font, run, textOrigin, boxRect, m_i nlineTextBox.isHorizontal()); | |
| 865 | |
| 866 textPainter.paint(sPos, ePos, length, textStyle, 0); | |
| 867 } | |
| 868 } | |
| 869 } | 883 } |
| 870 | 884 |
| 871 | 885 |
| 872 } // namespace blink | 886 } // namespace blink |
| OLD | NEW |