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/dom/DocumentMarkerController.h" | 8 #include "core/dom/DocumentMarkerController.h" |
9 #include "core/dom/RenderedDocumentMarker.h" | 9 #include "core/dom/RenderedDocumentMarker.h" |
10 #include "core/editing/CompositionUnderline.h" | 10 #include "core/editing/CompositionUnderline.h" |
(...skipping 25 matching lines...) Expand all Loading... |
36 | 36 |
37 static TextBlobPtr* addToTextBlobCache(InlineTextBox& inlineTextBox) | 37 static TextBlobPtr* addToTextBlobCache(InlineTextBox& inlineTextBox) |
38 { | 38 { |
39 if (!gTextBlobCache) | 39 if (!gTextBlobCache) |
40 gTextBlobCache = new InlineTextBoxBlobCacheMap; | 40 gTextBlobCache = new InlineTextBoxBlobCacheMap; |
41 return &gTextBlobCache->add(&inlineTextBox, nullptr).storedValue->value; | 41 return &gTextBlobCache->add(&inlineTextBox, nullptr).storedValue->value; |
42 } | 42 } |
43 | 43 |
44 void InlineTextBoxPainter::paint(const PaintInfo& paintInfo, const LayoutPoint&
paintOffset) | 44 void InlineTextBoxPainter::paint(const PaintInfo& paintInfo, const LayoutPoint&
paintOffset) |
45 { | 45 { |
46 if (m_inlineTextBox.isLineBreak() || !paintInfo.shouldPaintWithinRoot(&m_inl
ineTextBox.renderer()) || m_inlineTextBox.renderer().style()->visibility() != VI
SIBLE | 46 if (m_inlineTextBox.isLineBreak() || !paintInfo.shouldPaintWithinRoot(&m_inl
ineTextBox.layoutObject()) || m_inlineTextBox.layoutObject().style()->visibility
() != VISIBLE |
47 || m_inlineTextBox.truncation() == cFullTruncation || paintInfo.phase ==
PaintPhaseOutline || !m_inlineTextBox.len()) | 47 || m_inlineTextBox.truncation() == cFullTruncation || paintInfo.phase ==
PaintPhaseOutline || !m_inlineTextBox.len()) |
48 return; | 48 return; |
49 | 49 |
50 ASSERT(paintInfo.phase != PaintPhaseSelfOutline && paintInfo.phase != PaintP
haseChildOutlines); | 50 ASSERT(paintInfo.phase != PaintPhaseSelfOutline && paintInfo.phase != PaintP
haseChildOutlines); |
51 | 51 |
52 LayoutRect logicalVisualOverflow = m_inlineTextBox.logicalOverflowRect(); | 52 LayoutRect logicalVisualOverflow = m_inlineTextBox.logicalOverflowRect(); |
53 LayoutUnit logicalStart = logicalVisualOverflow.x() + (m_inlineTextBox.isHor
izontal() ? paintOffset.x() : paintOffset.y()); | 53 LayoutUnit logicalStart = logicalVisualOverflow.x() + (m_inlineTextBox.isHor
izontal() ? paintOffset.x() : paintOffset.y()); |
54 LayoutUnit logicalExtent = logicalVisualOverflow.width(); | 54 LayoutUnit logicalExtent = logicalVisualOverflow.width(); |
55 | 55 |
56 LayoutUnit paintEnd = m_inlineTextBox.isHorizontal() ? paintInfo.rect.maxX()
: paintInfo.rect.maxY(); | 56 LayoutUnit paintEnd = m_inlineTextBox.isHorizontal() ? paintInfo.rect.maxX()
: paintInfo.rect.maxY(); |
57 LayoutUnit paintStart = m_inlineTextBox.isHorizontal() ? paintInfo.rect.x()
: paintInfo.rect.y(); | 57 LayoutUnit paintStart = m_inlineTextBox.isHorizontal() ? paintInfo.rect.x()
: paintInfo.rect.y(); |
58 | 58 |
59 // We round the y-axis to ensure consistent line heights. | 59 // We round the y-axis to ensure consistent line heights. |
60 LayoutPoint adjustedPaintOffset = LayoutPoint(paintOffset.x(), paintOffset.y
().round()); | 60 LayoutPoint adjustedPaintOffset = LayoutPoint(paintOffset.x(), paintOffset.y
().round()); |
61 | 61 |
62 if (logicalStart >= paintEnd || logicalStart + logicalExtent <= paintStart) | 62 if (logicalStart >= paintEnd || logicalStart + logicalExtent <= paintStart) |
63 return; | 63 return; |
64 | 64 |
65 bool isPrinting = m_inlineTextBox.renderer().document().printing(); | 65 bool isPrinting = m_inlineTextBox.layoutObject().document().printing(); |
66 | 66 |
67 // Determine whether or not we're selected. | 67 // Determine whether or not we're selected. |
68 bool haveSelection = !isPrinting && paintInfo.phase != PaintPhaseTextClip &&
m_inlineTextBox.selectionState() != LayoutObject::SelectionNone; | 68 bool haveSelection = !isPrinting && paintInfo.phase != PaintPhaseTextClip &&
m_inlineTextBox.selectionState() != LayoutObject::SelectionNone; |
69 if (!haveSelection && paintInfo.phase == PaintPhaseSelection) { | 69 if (!haveSelection && paintInfo.phase == PaintPhaseSelection) { |
70 // When only painting the selection, don't bother to paint if there is n
one. | 70 // When only painting the selection, don't bother to paint if there is n
one. |
71 return; | 71 return; |
72 } | 72 } |
73 | 73 |
74 // The text clip phase already has a DrawingRecorder. Text clips are initiat
ed only in BoxPainter::paintLayerExtended, which is already | 74 // The text clip phase already has a DrawingRecorder. Text clips are initiat
ed only in BoxPainter::paintLayerExtended, which is already |
75 // within a DrawingRecorder. | 75 // within a DrawingRecorder. |
76 OwnPtr<DrawingRecorder> drawingRecorder; | 76 OwnPtr<DrawingRecorder> drawingRecorder; |
77 if (RuntimeEnabledFeatures::slimmingPaintEnabled() && paintInfo.phase != Pai
ntPhaseTextClip) { | 77 if (RuntimeEnabledFeatures::slimmingPaintEnabled() && paintInfo.phase != Pai
ntPhaseTextClip) { |
78 LayoutRect paintRect = logicalVisualOverflow; | 78 LayoutRect paintRect = logicalVisualOverflow; |
79 paintRect.moveBy(adjustedPaintOffset); | 79 paintRect.moveBy(adjustedPaintOffset); |
80 drawingRecorder = adoptPtr(new DrawingRecorder(paintInfo.context, m_inli
neTextBox.displayItemClient(), DisplayItem::paintPhaseToDrawingType(paintInfo.ph
ase), paintRect)); | 80 drawingRecorder = adoptPtr(new DrawingRecorder(paintInfo.context, m_inli
neTextBox.displayItemClient(), DisplayItem::paintPhaseToDrawingType(paintInfo.ph
ase), paintRect)); |
81 if (drawingRecorder->canUseCachedDrawing()) | 81 if (drawingRecorder->canUseCachedDrawing()) |
82 return; | 82 return; |
83 } | 83 } |
84 | 84 |
85 if (m_inlineTextBox.truncation() != cNoTruncation) { | 85 if (m_inlineTextBox.truncation() != cNoTruncation) { |
86 if (m_inlineTextBox.renderer().containingBlock()->style()->isLeftToRight
Direction() != m_inlineTextBox.isLeftToRightDirection()) { | 86 if (m_inlineTextBox.layoutObject().containingBlock()->style()->isLeftToR
ightDirection() != m_inlineTextBox.isLeftToRightDirection()) { |
87 // Make the visible fragment of text hug the edge closest to the res
t of the run by moving the origin | 87 // Make the visible fragment of text hug the edge closest to the res
t of the run by moving the origin |
88 // at which we start drawing text. | 88 // at which we start drawing text. |
89 // e.g. In the case of LTR text truncated in an RTL Context, the cor
rect behavior is: | 89 // e.g. In the case of LTR text truncated in an RTL Context, the cor
rect behavior is: |
90 // |Hello|CBA| -> |...He|CBA| | 90 // |Hello|CBA| -> |...He|CBA| |
91 // In order to draw the fragment "He" aligned to the right edge of i
t's box, we need to start drawing | 91 // In order to draw the fragment "He" aligned to the right edge of i
t's box, we need to start drawing |
92 // farther to the right. | 92 // farther to the right. |
93 // NOTE: WebKit's behavior differs from that of IE which appears to
just overlay the ellipsis on top of the | 93 // NOTE: WebKit's behavior differs from that of IE which appears to
just overlay the ellipsis on top of the |
94 // truncated string i.e. |Hello|CBA| -> |...lo|CBA| | 94 // truncated string i.e. |Hello|CBA| -> |...lo|CBA| |
95 LayoutUnit widthOfVisibleText = m_inlineTextBox.renderer().width(m_i
nlineTextBox.start(), m_inlineTextBox.truncation(), m_inlineTextBox.textPos(), m
_inlineTextBox.isLeftToRightDirection() ? LTR : RTL, m_inlineTextBox.isFirstLine
Style()); | 95 LayoutUnit widthOfVisibleText = m_inlineTextBox.layoutObject().width
(m_inlineTextBox.start(), m_inlineTextBox.truncation(), m_inlineTextBox.textPos(
), m_inlineTextBox.isLeftToRightDirection() ? LTR : RTL, m_inlineTextBox.isFirst
LineStyle()); |
96 LayoutUnit widthOfHiddenText = m_inlineTextBox.logicalWidth() - widt
hOfVisibleText; | 96 LayoutUnit widthOfHiddenText = m_inlineTextBox.logicalWidth() - widt
hOfVisibleText; |
97 // FIXME: The hit testing logic also needs to take this translation
into account. | 97 // FIXME: The hit testing logic also needs to take this translation
into account. |
98 LayoutSize truncationOffset(m_inlineTextBox.isLeftToRightDirection()
? widthOfHiddenText : -widthOfHiddenText, 0); | 98 LayoutSize truncationOffset(m_inlineTextBox.isLeftToRightDirection()
? widthOfHiddenText : -widthOfHiddenText, 0); |
99 adjustedPaintOffset.move(m_inlineTextBox.isHorizontal() ? truncation
Offset : truncationOffset.transposedSize()); | 99 adjustedPaintOffset.move(m_inlineTextBox.isHorizontal() ? truncation
Offset : truncationOffset.transposedSize()); |
100 } | 100 } |
101 } | 101 } |
102 | 102 |
103 GraphicsContext* context = paintInfo.context; | 103 GraphicsContext* context = paintInfo.context; |
104 const LayoutStyle& styleToUse = m_inlineTextBox.renderer().styleRef(m_inline
TextBox.isFirstLineStyle()); | 104 const LayoutStyle& styleToUse = m_inlineTextBox.layoutObject().styleRef(m_in
lineTextBox.isFirstLineStyle()); |
105 | 105 |
106 FloatPoint boxOrigin = m_inlineTextBox.locationIncludingFlipping().toFloatPo
int(); | 106 FloatPoint boxOrigin = m_inlineTextBox.locationIncludingFlipping().toFloatPo
int(); |
107 boxOrigin.move(adjustedPaintOffset.x().toFloat(), adjustedPaintOffset.y().to
Float()); | 107 boxOrigin.move(adjustedPaintOffset.x().toFloat(), adjustedPaintOffset.y().to
Float()); |
108 FloatRect boxRect(boxOrigin, FloatSize(m_inlineTextBox.logicalWidth(), m_inl
ineTextBox.logicalHeight())); | 108 FloatRect boxRect(boxOrigin, FloatSize(m_inlineTextBox.logicalWidth(), m_inl
ineTextBox.logicalHeight())); |
109 | 109 |
110 bool shouldRotate = false; | 110 bool shouldRotate = false; |
111 LayoutTextCombine* combinedText = nullptr; | 111 LayoutTextCombine* combinedText = nullptr; |
112 if (!m_inlineTextBox.isHorizontal()) { | 112 if (!m_inlineTextBox.isHorizontal()) { |
113 if (styleToUse.hasTextCombine() && m_inlineTextBox.renderer().isCombineT
ext()) { | 113 if (styleToUse.hasTextCombine() && m_inlineTextBox.layoutObject().isComb
ineText()) { |
114 combinedText = &toLayoutTextCombine(m_inlineTextBox.renderer()); | 114 combinedText = &toLayoutTextCombine(m_inlineTextBox.layoutObject()); |
115 if (!combinedText->isCombined()) | 115 if (!combinedText->isCombined()) |
116 combinedText = nullptr; | 116 combinedText = nullptr; |
117 } | 117 } |
118 if (combinedText) { | 118 if (combinedText) { |
119 combinedText->updateFont(); | 119 combinedText->updateFont(); |
120 boxRect.setWidth(combinedText->inlineWidthForLayout()); | 120 boxRect.setWidth(combinedText->inlineWidthForLayout()); |
121 } else { | 121 } else { |
122 shouldRotate = true; | 122 shouldRotate = true; |
123 context->concatCTM(TextPainter::rotation(boxRect, TextPainter::Clock
wise)); | 123 context->concatCTM(TextPainter::rotation(boxRect, TextPainter::Clock
wise)); |
124 } | 124 } |
125 } | 125 } |
126 | 126 |
127 // Determine whether or not we have composition underlines to draw. | 127 // Determine whether or not we have composition underlines to draw. |
128 bool containsComposition = m_inlineTextBox.renderer().node() && m_inlineText
Box.renderer().frame()->inputMethodController().compositionNode() == m_inlineTex
tBox.renderer().node(); | 128 bool containsComposition = m_inlineTextBox.layoutObject().node() && m_inline
TextBox.layoutObject().frame()->inputMethodController().compositionNode() == m_i
nlineTextBox.layoutObject().node(); |
129 bool useCustomUnderlines = containsComposition && m_inlineTextBox.renderer()
.frame()->inputMethodController().compositionUsesCustomUnderlines(); | 129 bool useCustomUnderlines = containsComposition && m_inlineTextBox.layoutObje
ct().frame()->inputMethodController().compositionUsesCustomUnderlines(); |
130 | 130 |
131 // Determine text colors. | 131 // Determine text colors. |
132 TextPainter::Style textStyle = TextPainter::textPaintingStyle(m_inlineTextBo
x.renderer(), styleToUse, paintInfo.forceBlackText(), isPrinting); | 132 TextPainter::Style textStyle = TextPainter::textPaintingStyle(m_inlineTextBo
x.layoutObject(), styleToUse, paintInfo.forceBlackText(), isPrinting); |
133 TextPainter::Style selectionStyle = TextPainter::selectionPaintingStyle(m_in
lineTextBox.renderer(), haveSelection, paintInfo.forceBlackText(), isPrinting, t
extStyle); | 133 TextPainter::Style selectionStyle = TextPainter::selectionPaintingStyle(m_in
lineTextBox.layoutObject(), haveSelection, paintInfo.forceBlackText(), isPrintin
g, textStyle); |
134 bool paintSelectedTextOnly = (paintInfo.phase == PaintPhaseSelection); | 134 bool paintSelectedTextOnly = (paintInfo.phase == PaintPhaseSelection); |
135 bool paintSelectedTextSeparately = !paintSelectedTextOnly && textStyle != se
lectionStyle; | 135 bool paintSelectedTextSeparately = !paintSelectedTextOnly && textStyle != se
lectionStyle; |
136 | 136 |
137 // Set our font. | 137 // Set our font. |
138 const Font& font = styleToUse.font(); | 138 const Font& font = styleToUse.font(); |
139 | 139 |
140 FloatPoint textOrigin = FloatPoint(boxOrigin.x(), boxOrigin.y() + font.fontM
etrics().ascent()); | 140 FloatPoint textOrigin = FloatPoint(boxOrigin.x(), boxOrigin.y() + font.fontM
etrics().ascent()); |
141 | 141 |
142 // 1. Paint backgrounds behind text if needed. Examples of such backgrounds
include selection | 142 // 1. Paint backgrounds behind text if needed. Examples of such backgrounds
include selection |
143 // and composition highlights. | 143 // and composition highlights. |
144 if (paintInfo.phase != PaintPhaseSelection && paintInfo.phase != PaintPhaseT
extClip && !isPrinting) { | 144 if (paintInfo.phase != PaintPhaseSelection && paintInfo.phase != PaintPhaseT
extClip && !isPrinting) { |
145 if (containsComposition) { | 145 if (containsComposition) { |
146 paintCompositionBackgrounds(context, boxOrigin, styleToUse, font, us
eCustomUnderlines); | 146 paintCompositionBackgrounds(context, boxOrigin, styleToUse, font, us
eCustomUnderlines); |
147 } | 147 } |
148 | 148 |
149 paintDocumentMarkers(context, boxOrigin, styleToUse, font, true); | 149 paintDocumentMarkers(context, boxOrigin, styleToUse, font, true); |
150 | 150 |
151 if (haveSelection && !useCustomUnderlines) { | 151 if (haveSelection && !useCustomUnderlines) { |
152 if (combinedText) | 152 if (combinedText) |
153 paintSelection<InlineTextBoxPainter::PaintOptions::CombinedText>
(context, boxRect, styleToUse, font, selectionStyle.fillColor, combinedText); | 153 paintSelection<InlineTextBoxPainter::PaintOptions::CombinedText>
(context, boxRect, styleToUse, font, selectionStyle.fillColor, combinedText); |
154 else | 154 else |
155 paintSelection<InlineTextBoxPainter::PaintOptions::Normal>(conte
xt, boxRect, styleToUse, font, selectionStyle.fillColor); | 155 paintSelection<InlineTextBoxPainter::PaintOptions::Normal>(conte
xt, boxRect, styleToUse, font, selectionStyle.fillColor); |
156 } | 156 } |
157 } | 157 } |
158 | 158 |
159 // 2. Now paint the foreground, including text and decorations like underlin
e/overline (in quirks mode only). | 159 // 2. Now paint the foreground, including text and decorations like underlin
e/overline (in quirks mode only). |
160 int length = m_inlineTextBox.len(); | 160 int length = m_inlineTextBox.len(); |
161 StringView string = m_inlineTextBox.renderer().text().createView(); | 161 StringView string = m_inlineTextBox.layoutObject().text().createView(); |
162 ASSERT(m_inlineTextBox.start() + length <= string.length()); | 162 ASSERT(m_inlineTextBox.start() + length <= string.length()); |
163 if (static_cast<unsigned>(length) != string.length() || m_inlineTextBox.star
t()) | 163 if (static_cast<unsigned>(length) != string.length() || m_inlineTextBox.star
t()) |
164 string.narrow(m_inlineTextBox.start(), length); | 164 string.narrow(m_inlineTextBox.start(), length); |
165 int maximumLength = m_inlineTextBox.renderer().textLength() - m_inlineTextBo
x.start(); | 165 int maximumLength = m_inlineTextBox.layoutObject().textLength() - m_inlineTe
xtBox.start(); |
166 | 166 |
167 StringBuilder charactersWithHyphen; | 167 StringBuilder charactersWithHyphen; |
168 TextRun textRun = m_inlineTextBox.constructTextRun(styleToUse, font, string,
maximumLength, m_inlineTextBox.hasHyphen() ? &charactersWithHyphen : 0); | 168 TextRun textRun = m_inlineTextBox.constructTextRun(styleToUse, font, string,
maximumLength, m_inlineTextBox.hasHyphen() ? &charactersWithHyphen : 0); |
169 if (m_inlineTextBox.hasHyphen()) | 169 if (m_inlineTextBox.hasHyphen()) |
170 length = textRun.length(); | 170 length = textRun.length(); |
171 | 171 |
172 int selectionStart = 0; | 172 int selectionStart = 0; |
173 int selectionEnd = 0; | 173 int selectionEnd = 0; |
174 if (paintSelectedTextOnly || paintSelectedTextSeparately) | 174 if (paintSelectedTextOnly || paintSelectedTextSeparately) |
175 m_inlineTextBox.selectionStartEnd(selectionStart, selectionEnd); | 175 m_inlineTextBox.selectionStartEnd(selectionStart, selectionEnd); |
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
230 paintDecoration(context, boxOrigin, textDecorations); | 230 paintDecoration(context, boxOrigin, textDecorations); |
231 if (combinedText) | 231 if (combinedText) |
232 context->concatCTM(TextPainter::rotation(boxRect, TextPainter::Count
erclockwise)); | 232 context->concatCTM(TextPainter::rotation(boxRect, TextPainter::Count
erclockwise)); |
233 } | 233 } |
234 | 234 |
235 if (paintInfo.phase == PaintPhaseForeground) { | 235 if (paintInfo.phase == PaintPhaseForeground) { |
236 paintDocumentMarkers(context, boxOrigin, styleToUse, font, false); | 236 paintDocumentMarkers(context, boxOrigin, styleToUse, font, false); |
237 | 237 |
238 // Paint custom underlines for compositions. | 238 // Paint custom underlines for compositions. |
239 if (useCustomUnderlines) { | 239 if (useCustomUnderlines) { |
240 const Vector<CompositionUnderline>& underlines = m_inlineTextBox.ren
derer().frame()->inputMethodController().customCompositionUnderlines(); | 240 const Vector<CompositionUnderline>& underlines = m_inlineTextBox.lay
outObject().frame()->inputMethodController().customCompositionUnderlines(); |
241 CompositionUnderlineRangeFilter filter(underlines, m_inlineTextBox.s
tart(), m_inlineTextBox.end()); | 241 CompositionUnderlineRangeFilter filter(underlines, m_inlineTextBox.s
tart(), m_inlineTextBox.end()); |
242 for (CompositionUnderlineRangeFilter::ConstIterator it = filter.begi
n(); it != filter.end(); ++it) { | 242 for (CompositionUnderlineRangeFilter::ConstIterator it = filter.begi
n(); it != filter.end(); ++it) { |
243 if (it->color == Color::transparent) | 243 if (it->color == Color::transparent) |
244 continue; | 244 continue; |
245 paintCompositionUnderline(context, boxOrigin, *it); | 245 paintCompositionUnderline(context, boxOrigin, *it); |
246 } | 246 } |
247 } | 247 } |
248 } | 248 } |
249 | 249 |
250 if (shouldRotate) | 250 if (shouldRotate) |
(...skipping 10 matching lines...) Expand all Loading... |
261 unsigned paintEnd = std::min(m_inlineTextBox.end() + 1, underline.endOffset)
; // end() points at the last char, not past it. | 261 unsigned paintEnd = std::min(m_inlineTextBox.end() + 1, underline.endOffset)
; // end() points at the last char, not past it. |
262 if (m_inlineTextBox.truncation() != cNoTruncation) | 262 if (m_inlineTextBox.truncation() != cNoTruncation) |
263 paintEnd = std::min(paintEnd, static_cast<unsigned>(m_inlineTextBox.star
t() + m_inlineTextBox.truncation())); | 263 paintEnd = std::min(paintEnd, static_cast<unsigned>(m_inlineTextBox.star
t() + m_inlineTextBox.truncation())); |
264 return paintEnd; | 264 return paintEnd; |
265 } | 265 } |
266 | 266 |
267 void InlineTextBoxPainter::paintCompositionBackgrounds(GraphicsContext* pt, cons
t FloatPoint& boxOrigin, const LayoutStyle& style, const Font& font, bool useCus
tomUnderlines) | 267 void InlineTextBoxPainter::paintCompositionBackgrounds(GraphicsContext* pt, cons
t FloatPoint& boxOrigin, const LayoutStyle& style, const Font& font, bool useCus
tomUnderlines) |
268 { | 268 { |
269 if (useCustomUnderlines) { | 269 if (useCustomUnderlines) { |
270 // Paint custom background highlights for compositions. | 270 // Paint custom background highlights for compositions. |
271 const Vector<CompositionUnderline>& underlines = m_inlineTextBox.rendere
r().frame()->inputMethodController().customCompositionUnderlines(); | 271 const Vector<CompositionUnderline>& underlines = m_inlineTextBox.layoutO
bject().frame()->inputMethodController().customCompositionUnderlines(); |
272 CompositionUnderlineRangeFilter filter(underlines, m_inlineTextBox.start
(), m_inlineTextBox.end()); | 272 CompositionUnderlineRangeFilter filter(underlines, m_inlineTextBox.start
(), m_inlineTextBox.end()); |
273 for (CompositionUnderlineRangeFilter::ConstIterator it = filter.begin();
it != filter.end(); ++it) { | 273 for (CompositionUnderlineRangeFilter::ConstIterator it = filter.begin();
it != filter.end(); ++it) { |
274 if (it->backgroundColor == Color::transparent) | 274 if (it->backgroundColor == Color::transparent) |
275 continue; | 275 continue; |
276 paintSingleCompositionBackgroundRun(pt, boxOrigin, style, font, it->
backgroundColor, underlinePaintStart(*it), underlinePaintEnd(*it)); | 276 paintSingleCompositionBackgroundRun(pt, boxOrigin, style, font, it->
backgroundColor, underlinePaintStart(*it), underlinePaintEnd(*it)); |
277 } | 277 } |
278 | 278 |
279 } else { | 279 } else { |
280 paintSingleCompositionBackgroundRun(pt, boxOrigin, style, font, LayoutTh
eme::theme().platformDefaultCompositionBackgroundColor(), | 280 paintSingleCompositionBackgroundRun(pt, boxOrigin, style, font, LayoutTh
eme::theme().platformDefaultCompositionBackgroundColor(), |
281 m_inlineTextBox.renderer().frame()->inputMethodController().composit
ionStart(), | 281 m_inlineTextBox.layoutObject().frame()->inputMethodController().comp
ositionStart(), |
282 m_inlineTextBox.renderer().frame()->inputMethodController().composit
ionEnd()); | 282 m_inlineTextBox.layoutObject().frame()->inputMethodController().comp
ositionEnd()); |
283 } | 283 } |
284 } | 284 } |
285 | 285 |
286 void InlineTextBoxPainter::paintSingleCompositionBackgroundRun(GraphicsContext*
context, const FloatPoint& boxOrigin, const LayoutStyle& style, const Font& font
, Color backgroundColor, int startPos, int endPos) | 286 void InlineTextBoxPainter::paintSingleCompositionBackgroundRun(GraphicsContext*
context, const FloatPoint& boxOrigin, const LayoutStyle& style, const Font& font
, Color backgroundColor, int startPos, int endPos) |
287 { | 287 { |
288 int sPos = std::max(startPos - static_cast<int>(m_inlineTextBox.start()), 0)
; | 288 int sPos = std::max(startPos - static_cast<int>(m_inlineTextBox.start()), 0)
; |
289 int ePos = std::min(endPos - static_cast<int>(m_inlineTextBox.start()), stat
ic_cast<int>(m_inlineTextBox.len())); | 289 int ePos = std::min(endPos - static_cast<int>(m_inlineTextBox.start()), stat
ic_cast<int>(m_inlineTextBox.len())); |
290 if (sPos >= ePos) | 290 if (sPos >= ePos) |
291 return; | 291 return; |
292 | 292 |
293 int deltaY = m_inlineTextBox.renderer().style()->isFlippedLinesWritingMode()
? m_inlineTextBox.root().selectionBottom() - m_inlineTextBox.logicalBottom() :
m_inlineTextBox.logicalTop() - m_inlineTextBox.root().selectionTop(); | 293 int deltaY = m_inlineTextBox.layoutObject().style()->isFlippedLinesWritingMo
de() ? m_inlineTextBox.root().selectionBottom() - m_inlineTextBox.logicalBottom(
) : m_inlineTextBox.logicalTop() - m_inlineTextBox.root().selectionTop(); |
294 int selHeight = m_inlineTextBox.root().selectionHeight(); | 294 int selHeight = m_inlineTextBox.root().selectionHeight(); |
295 FloatPoint localOrigin(boxOrigin.x(), boxOrigin.y() - deltaY); | 295 FloatPoint localOrigin(boxOrigin.x(), boxOrigin.y() - deltaY); |
296 context->drawHighlightForText(font, m_inlineTextBox.constructTextRun(style,
font), localOrigin, selHeight, backgroundColor, sPos, ePos); | 296 context->drawHighlightForText(font, m_inlineTextBox.constructTextRun(style,
font), localOrigin, selHeight, backgroundColor, sPos, ePos); |
297 } | 297 } |
298 | 298 |
299 void InlineTextBoxPainter::paintDocumentMarkers(GraphicsContext* pt, const Float
Point& boxOrigin, const LayoutStyle& style, const Font& font, bool background) | 299 void InlineTextBoxPainter::paintDocumentMarkers(GraphicsContext* pt, const Float
Point& boxOrigin, const LayoutStyle& style, const Font& font, bool background) |
300 { | 300 { |
301 if (!m_inlineTextBox.renderer().node()) | 301 if (!m_inlineTextBox.layoutObject().node()) |
302 return; | 302 return; |
303 | 303 |
304 DocumentMarkerVector markers = m_inlineTextBox.renderer().document().markers
().markersFor(m_inlineTextBox.renderer().node()); | 304 DocumentMarkerVector markers = m_inlineTextBox.layoutObject().document().mar
kers().markersFor(m_inlineTextBox.layoutObject().node()); |
305 DocumentMarkerVector::const_iterator markerIt = markers.begin(); | 305 DocumentMarkerVector::const_iterator markerIt = markers.begin(); |
306 | 306 |
307 // Give any document markers that touch this run a chance to draw before the
text has been drawn. | 307 // Give any document markers that touch this run a chance to draw before the
text has been drawn. |
308 // Note end() points at the last char, not one past it like endOffset and ra
nges do. | 308 // Note end() points at the last char, not one past it like endOffset and ra
nges do. |
309 for ( ; markerIt != markers.end(); ++markerIt) { | 309 for ( ; markerIt != markers.end(); ++markerIt) { |
310 DocumentMarker* marker = *markerIt; | 310 DocumentMarker* marker = *markerIt; |
311 | 311 |
312 // Paint either the background markers or the foreground markers, but no
t both | 312 // Paint either the background markers or the foreground markers, but no
t both |
313 switch (marker->type()) { | 313 switch (marker->type()) { |
314 case DocumentMarker::Grammar: | 314 case DocumentMarker::Grammar: |
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
360 return GraphicsContext::DocumentMarkerGrammarLineStyle; | 360 return GraphicsContext::DocumentMarkerGrammarLineStyle; |
361 default: | 361 default: |
362 ASSERT_NOT_REACHED(); | 362 ASSERT_NOT_REACHED(); |
363 return GraphicsContext::DocumentMarkerSpellingLineStyle; | 363 return GraphicsContext::DocumentMarkerSpellingLineStyle; |
364 } | 364 } |
365 } | 365 } |
366 | 366 |
367 void InlineTextBoxPainter::paintDocumentMarker(GraphicsContext* pt, const FloatP
oint& boxOrigin, DocumentMarker* marker, const LayoutStyle& style, const Font& f
ont, bool grammar) | 367 void InlineTextBoxPainter::paintDocumentMarker(GraphicsContext* pt, const FloatP
oint& boxOrigin, DocumentMarker* marker, const LayoutStyle& style, const Font& f
ont, bool grammar) |
368 { | 368 { |
369 // Never print spelling/grammar markers (5327887) | 369 // Never print spelling/grammar markers (5327887) |
370 if (m_inlineTextBox.renderer().document().printing()) | 370 if (m_inlineTextBox.layoutObject().document().printing()) |
371 return; | 371 return; |
372 | 372 |
373 if (m_inlineTextBox.truncation() == cFullTruncation) | 373 if (m_inlineTextBox.truncation() == cFullTruncation) |
374 return; | 374 return; |
375 | 375 |
376 float start = 0; // start of line to draw, relative to tx | 376 float start = 0; // start of line to draw, relative to tx |
377 float width = m_inlineTextBox.logicalWidth(); // how much line to draw | 377 float width = m_inlineTextBox.logicalWidth(); // how much line to draw |
378 | 378 |
379 // Determine whether we need to measure text | 379 // Determine whether we need to measure text |
380 bool markerSpansWholeBox = true; | 380 bool markerSpansWholeBox = true; |
381 if (m_inlineTextBox.start() <= marker->startOffset()) | 381 if (m_inlineTextBox.start() <= marker->startOffset()) |
382 markerSpansWholeBox = false; | 382 markerSpansWholeBox = false; |
383 if ((m_inlineTextBox.end() + 1) != marker->endOffset()) // end points at the
last char, not past it | 383 if ((m_inlineTextBox.end() + 1) != marker->endOffset()) // end points at the
last char, not past it |
384 markerSpansWholeBox = false; | 384 markerSpansWholeBox = false; |
385 if (m_inlineTextBox.truncation() != cNoTruncation) | 385 if (m_inlineTextBox.truncation() != cNoTruncation) |
386 markerSpansWholeBox = false; | 386 markerSpansWholeBox = false; |
387 | 387 |
388 if (!markerSpansWholeBox || grammar) { | 388 if (!markerSpansWholeBox || grammar) { |
389 int startPosition = std::max<int>(marker->startOffset() - m_inlineTextBo
x.start(), 0); | 389 int startPosition = std::max<int>(marker->startOffset() - m_inlineTextBo
x.start(), 0); |
390 int endPosition = std::min<int>(marker->endOffset() - static_cast<int>(m
_inlineTextBox.start()), m_inlineTextBox.len()); | 390 int endPosition = std::min<int>(marker->endOffset() - static_cast<int>(m
_inlineTextBox.start()), m_inlineTextBox.len()); |
391 | 391 |
392 if (m_inlineTextBox.truncation() != cNoTruncation) | 392 if (m_inlineTextBox.truncation() != cNoTruncation) |
393 endPosition = std::min<int>(endPosition, m_inlineTextBox.truncation(
)); | 393 endPosition = std::min<int>(endPosition, m_inlineTextBox.truncation(
)); |
394 | 394 |
395 // Calculate start & width | 395 // Calculate start & width |
396 int deltaY = m_inlineTextBox.renderer().style()->isFlippedLinesWritingMo
de() ? m_inlineTextBox.root().selectionBottom() - m_inlineTextBox.logicalBottom(
) : m_inlineTextBox.logicalTop() - m_inlineTextBox.root().selectionTop(); | 396 int deltaY = m_inlineTextBox.layoutObject().style()->isFlippedLinesWriti
ngMode() ? m_inlineTextBox.root().selectionBottom() - m_inlineTextBox.logicalBot
tom() : m_inlineTextBox.logicalTop() - m_inlineTextBox.root().selectionTop(); |
397 int selHeight = m_inlineTextBox.root().selectionHeight(); | 397 int selHeight = m_inlineTextBox.root().selectionHeight(); |
398 FloatPoint startPoint(boxOrigin.x(), boxOrigin.y() - deltaY); | 398 FloatPoint startPoint(boxOrigin.x(), boxOrigin.y() - deltaY); |
399 TextRun run = m_inlineTextBox.constructTextRun(style, font); | 399 TextRun run = m_inlineTextBox.constructTextRun(style, font); |
400 | 400 |
401 // FIXME: Convert the document markers to float rects. | 401 // FIXME: Convert the document markers to float rects. |
402 IntRect markerRect = enclosingIntRect(font.selectionRectForText(run, sta
rtPoint, selHeight, startPosition, endPosition)); | 402 IntRect markerRect = enclosingIntRect(font.selectionRectForText(run, sta
rtPoint, selHeight, startPosition, endPosition)); |
403 start = markerRect.x() - startPoint.x(); | 403 start = markerRect.x() - startPoint.x(); |
404 width = markerRect.width(); | 404 width = markerRect.width(); |
405 | 405 |
406 // Store rendered rects for bad grammar markers, so we can hit-test agai
nst it elsewhere in order to | 406 // Store rendered rects for bad grammar markers, so we can hit-test agai
nst it elsewhere in order to |
407 // display a toolTip. We don't do this for misspelling markers. | 407 // display a toolTip. We don't do this for misspelling markers. |
408 if (grammar) { | 408 if (grammar) { |
409 markerRect.move(-boxOrigin.x(), -boxOrigin.y()); | 409 markerRect.move(-boxOrigin.x(), -boxOrigin.y()); |
410 markerRect = m_inlineTextBox.renderer().localToAbsoluteQuad(FloatRec
t(markerRect)).enclosingBoundingBox(); | 410 markerRect = m_inlineTextBox.layoutObject().localToAbsoluteQuad(Floa
tRect(markerRect)).enclosingBoundingBox(); |
411 toRenderedDocumentMarker(marker)->setRenderedRect(LayoutRect(markerR
ect)); | 411 toRenderedDocumentMarker(marker)->setRenderedRect(LayoutRect(markerR
ect)); |
412 } | 412 } |
413 } | 413 } |
414 | 414 |
415 // IMPORTANT: The misspelling underline is not considered when calculating t
he text bounds, so we have to | 415 // IMPORTANT: The misspelling underline is not considered when calculating t
he text bounds, so we have to |
416 // make sure to fit within those bounds. This means the top pixel(s) of the
underline will overlap the | 416 // make sure to fit within those bounds. This means the top pixel(s) of the
underline will overlap the |
417 // bottom pixel(s) of the glyphs in smaller font sizes. The alternatives ar
e to increase the line spacing (bad!!) | 417 // bottom pixel(s) of the glyphs in smaller font sizes. The alternatives ar
e to increase the line spacing (bad!!) |
418 // or decrease the underline thickness. The overlap is actually the most us
eful, and matches what AppKit does. | 418 // or decrease the underline thickness. The overlap is actually the most us
eful, and matches what AppKit does. |
419 // So, we generally place the underline at the bottom of the text, but in la
rger fonts that's not so good so | 419 // So, we generally place the underline at the bottom of the text, but in la
rger fonts that's not so good so |
420 // we pin to two pixels under the baseline. | 420 // we pin to two pixels under the baseline. |
421 int lineThickness = misspellingLineThickness; | 421 int lineThickness = misspellingLineThickness; |
422 int baseline = m_inlineTextBox.renderer().style(m_inlineTextBox.isFirstLineS
tyle())->fontMetrics().ascent(); | 422 int baseline = m_inlineTextBox.layoutObject().style(m_inlineTextBox.isFirstL
ineStyle())->fontMetrics().ascent(); |
423 int descent = m_inlineTextBox.logicalHeight() - baseline; | 423 int descent = m_inlineTextBox.logicalHeight() - baseline; |
424 int underlineOffset; | 424 int underlineOffset; |
425 if (descent <= (2 + lineThickness)) { | 425 if (descent <= (2 + lineThickness)) { |
426 // Place the underline at the very bottom of the text in small/medium fo
nts. | 426 // Place the underline at the very bottom of the text in small/medium fo
nts. |
427 underlineOffset = m_inlineTextBox.logicalHeight() - lineThickness; | 427 underlineOffset = m_inlineTextBox.logicalHeight() - lineThickness; |
428 } else { | 428 } else { |
429 // In larger fonts, though, place the underline up near the baseline to
prevent a big gap. | 429 // In larger fonts, though, place the underline up near the baseline to
prevent a big gap. |
430 underlineOffset = baseline + 2; | 430 underlineOffset = baseline + 2; |
431 } | 431 } |
432 pt->drawLineForDocumentMarker(FloatPoint(boxOrigin.x() + start, boxOrigin.y(
) + underlineOffset), width, lineStyleForMarkerType(marker->type())); | 432 pt->drawLineForDocumentMarker(FloatPoint(boxOrigin.x() + start, boxOrigin.y(
) + underlineOffset), width, lineStyleForMarkerType(marker->type())); |
433 } | 433 } |
434 | 434 |
435 template <InlineTextBoxPainter::PaintOptions options> | 435 template <InlineTextBoxPainter::PaintOptions options> |
436 void InlineTextBoxPainter::paintSelection(GraphicsContext* context, const FloatR
ect& boxRect, const LayoutStyle& style, const Font& font, Color textColor, Layou
tTextCombine* combinedText) | 436 void InlineTextBoxPainter::paintSelection(GraphicsContext* context, const FloatR
ect& boxRect, const LayoutStyle& style, const Font& font, Color textColor, Layou
tTextCombine* combinedText) |
437 { | 437 { |
438 // See if we have a selection to paint at all. | 438 // See if we have a selection to paint at all. |
439 int sPos, ePos; | 439 int sPos, ePos; |
440 m_inlineTextBox.selectionStartEnd(sPos, ePos); | 440 m_inlineTextBox.selectionStartEnd(sPos, ePos); |
441 if (sPos >= ePos) | 441 if (sPos >= ePos) |
442 return; | 442 return; |
443 | 443 |
444 Color c = m_inlineTextBox.renderer().selectionBackgroundColor(); | 444 Color c = m_inlineTextBox.layoutObject().selectionBackgroundColor(); |
445 if (!c.alpha()) | 445 if (!c.alpha()) |
446 return; | 446 return; |
447 | 447 |
448 // If the text color ends up being the same as the selection background, inv
ert the selection | 448 // If the text color ends up being the same as the selection background, inv
ert the selection |
449 // background. | 449 // background. |
450 if (textColor == c) | 450 if (textColor == c) |
451 c = Color(0xff - c.red(), 0xff - c.green(), 0xff - c.blue()); | 451 c = Color(0xff - c.red(), 0xff - c.green(), 0xff - c.blue()); |
452 | 452 |
453 // If the text is truncated, let the thing being painted in the truncation | 453 // If the text is truncated, let the thing being painted in the truncation |
454 // draw its own highlight. | 454 // draw its own highlight. |
455 int length = m_inlineTextBox.truncation() != cNoTruncation ? m_inlineTextBox
.truncation() : m_inlineTextBox.len(); | 455 int length = m_inlineTextBox.truncation() != cNoTruncation ? m_inlineTextBox
.truncation() : m_inlineTextBox.len(); |
456 StringView string = m_inlineTextBox.renderer().text().createView(); | 456 StringView string = m_inlineTextBox.layoutObject().text().createView(); |
457 | 457 |
458 if (string.length() != static_cast<unsigned>(length) || m_inlineTextBox.star
t()) | 458 if (string.length() != static_cast<unsigned>(length) || m_inlineTextBox.star
t()) |
459 string.narrow(m_inlineTextBox.start(), length); | 459 string.narrow(m_inlineTextBox.start(), length); |
460 | 460 |
461 StringBuilder charactersWithHyphen; | 461 StringBuilder charactersWithHyphen; |
462 bool respectHyphen = ePos == length && m_inlineTextBox.hasHyphen(); | 462 bool respectHyphen = ePos == length && m_inlineTextBox.hasHyphen(); |
463 TextRun textRun = m_inlineTextBox.constructTextRun(style, font, string, m_in
lineTextBox.renderer().textLength() - m_inlineTextBox.start(), respectHyphen ? &
charactersWithHyphen : 0); | 463 TextRun textRun = m_inlineTextBox.constructTextRun(style, font, string, m_in
lineTextBox.layoutObject().textLength() - m_inlineTextBox.start(), respectHyphen
? &charactersWithHyphen : 0); |
464 if (respectHyphen) | 464 if (respectHyphen) |
465 ePos = textRun.length(); | 465 ePos = textRun.length(); |
466 | 466 |
467 GraphicsContextStateSaver stateSaver(*context); | 467 GraphicsContextStateSaver stateSaver(*context); |
468 | 468 |
469 if (options == InlineTextBoxPainter::PaintOptions::CombinedText) { | 469 if (options == InlineTextBoxPainter::PaintOptions::CombinedText) { |
470 ASSERT(combinedText); | 470 ASSERT(combinedText); |
471 // We can't use the height of m_inlineTextBox because LayoutTextCombine'
s inlineTextBox is horizontal within vertical flow | 471 // We can't use the height of m_inlineTextBox because LayoutTextCombine'
s inlineTextBox is horizontal within vertical flow |
472 FloatRect clipRect = boxRect; | 472 FloatRect clipRect = boxRect; |
473 combinedText->transformLayoutRect(clipRect); | 473 combinedText->transformLayoutRect(clipRect); |
474 context->clip(clipRect); | 474 context->clip(clipRect); |
475 combinedText->transformToInlineCoordinates(*context, boxRect); | 475 combinedText->transformToInlineCoordinates(*context, boxRect); |
476 context->drawHighlightForText(font, textRun, boxRect.location(), boxRect
.height(), c, sPos, ePos); | 476 context->drawHighlightForText(font, textRun, boxRect.location(), boxRect
.height(), c, sPos, ePos); |
477 return; | 477 return; |
478 } | 478 } |
479 | 479 |
480 LayoutUnit selectionBottom = m_inlineTextBox.root().selectionBottom(); | 480 LayoutUnit selectionBottom = m_inlineTextBox.root().selectionBottom(); |
481 LayoutUnit selectionTop = m_inlineTextBox.root().selectionTopAdjustedForPrec
edingBlock(); | 481 LayoutUnit selectionTop = m_inlineTextBox.root().selectionTopAdjustedForPrec
edingBlock(); |
482 | 482 |
483 int deltaY = roundToInt(m_inlineTextBox.renderer().style()->isFlippedLinesWr
itingMode() ? selectionBottom - m_inlineTextBox.logicalBottom() : m_inlineTextBo
x.logicalTop() - selectionTop); | 483 int deltaY = roundToInt(m_inlineTextBox.layoutObject().style()->isFlippedLin
esWritingMode() ? selectionBottom - m_inlineTextBox.logicalBottom() : m_inlineTe
xtBox.logicalTop() - selectionTop); |
484 int selHeight = std::max(0, roundToInt(selectionBottom - selectionTop)); | 484 int selHeight = std::max(0, roundToInt(selectionBottom - selectionTop)); |
485 | 485 |
486 FloatPoint localOrigin(boxRect.x(), boxRect.y() - deltaY); | 486 FloatPoint localOrigin(boxRect.x(), boxRect.y() - deltaY); |
487 FloatRect clipRect(localOrigin, FloatSize(m_inlineTextBox.logicalWidth(), se
lHeight)); | 487 FloatRect clipRect(localOrigin, FloatSize(m_inlineTextBox.logicalWidth(), se
lHeight)); |
488 | 488 |
489 context->clip(clipRect); | 489 context->clip(clipRect); |
490 context->drawHighlightForText(font, textRun, localOrigin, selHeight, c, sPos
, ePos); | 490 context->drawHighlightForText(font, textRun, localOrigin, selHeight, c, sPos
, ePos); |
491 } | 491 } |
492 | 492 |
493 static int computeUnderlineOffset(const TextUnderlinePosition underlinePosition,
const FontMetrics& fontMetrics, const InlineTextBox* inlineTextBox, const float
textDecorationThickness) | 493 static int computeUnderlineOffset(const TextUnderlinePosition underlinePosition,
const FontMetrics& fontMetrics, const InlineTextBox* inlineTextBox, const float
textDecorationThickness) |
(...skipping 212 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
706 { | 706 { |
707 GraphicsContextStateSaver stateSaver(*context); | 707 GraphicsContextStateSaver stateSaver(*context); |
708 | 708 |
709 if (m_inlineTextBox.truncation() == cFullTruncation) | 709 if (m_inlineTextBox.truncation() == cFullTruncation) |
710 return; | 710 return; |
711 | 711 |
712 FloatPoint localOrigin = boxOrigin; | 712 FloatPoint localOrigin = boxOrigin; |
713 | 713 |
714 float width = m_inlineTextBox.logicalWidth(); | 714 float width = m_inlineTextBox.logicalWidth(); |
715 if (m_inlineTextBox.truncation() != cNoTruncation) { | 715 if (m_inlineTextBox.truncation() != cNoTruncation) { |
716 width = m_inlineTextBox.renderer().width(m_inlineTextBox.start(), m_inli
neTextBox.truncation(), m_inlineTextBox.textPos(), m_inlineTextBox.isLeftToRight
Direction() ? LTR : RTL, m_inlineTextBox.isFirstLineStyle()); | 716 width = m_inlineTextBox.layoutObject().width(m_inlineTextBox.start(), m_
inlineTextBox.truncation(), m_inlineTextBox.textPos(), m_inlineTextBox.isLeftToR
ightDirection() ? LTR : RTL, m_inlineTextBox.isFirstLineStyle()); |
717 if (!m_inlineTextBox.isLeftToRightDirection()) | 717 if (!m_inlineTextBox.isLeftToRightDirection()) |
718 localOrigin.move(m_inlineTextBox.logicalWidth() - width, 0); | 718 localOrigin.move(m_inlineTextBox.logicalWidth() - width, 0); |
719 } | 719 } |
720 | 720 |
721 // Get the text decoration colors. | 721 // Get the text decoration colors. |
722 LayoutObject::AppliedTextDecoration underline, overline, linethrough; | 722 LayoutObject::AppliedTextDecoration underline, overline, linethrough; |
723 m_inlineTextBox.renderer().getTextDecorations(deco, underline, overline, lin
ethrough, true); | 723 m_inlineTextBox.layoutObject().getTextDecorations(deco, underline, overline,
linethrough, true); |
724 if (m_inlineTextBox.isFirstLineStyle()) | 724 if (m_inlineTextBox.isFirstLineStyle()) |
725 m_inlineTextBox.renderer().getTextDecorations(deco, underline, overline,
linethrough, true, true); | 725 m_inlineTextBox.layoutObject().getTextDecorations(deco, underline, overl
ine, linethrough, true, true); |
726 | 726 |
727 // Use a special function for underlines to get the positioning exactly righ
t. | 727 // Use a special function for underlines to get the positioning exactly righ
t. |
728 bool isPrinting = m_inlineTextBox.renderer().document().printing(); | 728 bool isPrinting = m_inlineTextBox.layoutObject().document().printing(); |
729 | 729 |
730 const LayoutStyle& styleToUse = m_inlineTextBox.renderer().styleRef(m_inline
TextBox.isFirstLineStyle()); | 730 const LayoutStyle& styleToUse = m_inlineTextBox.layoutObject().styleRef(m_in
lineTextBox.isFirstLineStyle()); |
731 int baseline = styleToUse.fontMetrics().ascent(); | 731 int baseline = styleToUse.fontMetrics().ascent(); |
732 | 732 |
733 // Set the thick of the line to be 10% (or something else ?)of the computed
font size and not less than 1px. | 733 // Set the thick of the line to be 10% (or something else ?)of the computed
font size and not less than 1px. |
734 // Using computedFontSize should take care of zoom as well. | 734 // Using computedFontSize should take care of zoom as well. |
735 | 735 |
736 // Update Underline thickness, in case we have Faulty Font Metrics calculati
ng underline thickness by old method. | 736 // Update Underline thickness, in case we have Faulty Font Metrics calculati
ng underline thickness by old method. |
737 float textDecorationThickness = styleToUse.fontMetrics().underlineThickness(
); | 737 float textDecorationThickness = styleToUse.fontMetrics().underlineThickness(
); |
738 int fontHeightInt = (int)(styleToUse.fontMetrics().floatHeight() + 0.5); | 738 int fontHeightInt = (int)(styleToUse.fontMetrics().floatHeight() + 0.5); |
739 if ((textDecorationThickness == 0.f) || (textDecorationThickness >= (fontHei
ghtInt >> 1))) | 739 if ((textDecorationThickness == 0.f) || (textDecorationThickness >= (fontHei
ghtInt >> 1))) |
740 textDecorationThickness = std::max(1.f, styleToUse.computedFontSize() /
10.f); | 740 textDecorationThickness = std::max(1.f, styleToUse.computedFontSize() /
10.f); |
(...skipping 22 matching lines...) Expand all Loading... |
763 void InlineTextBoxPainter::paintCompositionUnderline(GraphicsContext* ctx, const
FloatPoint& boxOrigin, const CompositionUnderline& underline) | 763 void InlineTextBoxPainter::paintCompositionUnderline(GraphicsContext* ctx, const
FloatPoint& boxOrigin, const CompositionUnderline& underline) |
764 { | 764 { |
765 if (m_inlineTextBox.truncation() == cFullTruncation) | 765 if (m_inlineTextBox.truncation() == cFullTruncation) |
766 return; | 766 return; |
767 | 767 |
768 unsigned paintStart = underlinePaintStart(underline); | 768 unsigned paintStart = underlinePaintStart(underline); |
769 unsigned paintEnd = underlinePaintEnd(underline); | 769 unsigned paintEnd = underlinePaintEnd(underline); |
770 | 770 |
771 // start of line to draw, relative to paintOffset. | 771 // start of line to draw, relative to paintOffset. |
772 float start = paintStart == static_cast<unsigned>(m_inlineTextBox.start()) ?
0 : | 772 float start = paintStart == static_cast<unsigned>(m_inlineTextBox.start()) ?
0 : |
773 m_inlineTextBox.renderer().width(m_inlineTextBox.start(), paintStart - m
_inlineTextBox.start(), m_inlineTextBox.textPos(), m_inlineTextBox.isLeftToRight
Direction() ? LTR : RTL, m_inlineTextBox.isFirstLineStyle()); | 773 m_inlineTextBox.layoutObject().width(m_inlineTextBox.start(), paintStart
- m_inlineTextBox.start(), m_inlineTextBox.textPos(), m_inlineTextBox.isLeftToR
ightDirection() ? LTR : RTL, m_inlineTextBox.isFirstLineStyle()); |
774 // how much line to draw | 774 // how much line to draw |
775 float width = (paintStart == static_cast<unsigned>(m_inlineTextBox.start())
&& paintEnd == static_cast<unsigned>(m_inlineTextBox.end()) + 1) ? m_inlineTextB
ox.logicalWidth().toFloat() : | 775 float width = (paintStart == static_cast<unsigned>(m_inlineTextBox.start())
&& paintEnd == static_cast<unsigned>(m_inlineTextBox.end()) + 1) ? m_inlineTextB
ox.logicalWidth().toFloat() : |
776 m_inlineTextBox.renderer().width(paintStart, paintEnd - paintStart, m_in
lineTextBox.textPos() + start, m_inlineTextBox.isLeftToRightDirection() ? LTR :
RTL, m_inlineTextBox.isFirstLineStyle()); | 776 m_inlineTextBox.layoutObject().width(paintStart, paintEnd - paintStart,
m_inlineTextBox.textPos() + start, m_inlineTextBox.isLeftToRightDirection() ? LT
R : RTL, m_inlineTextBox.isFirstLineStyle()); |
777 | 777 |
778 // Thick marked text underlines are 2px thick as long as there is room for t
he 2px line under the baseline. | 778 // Thick marked text underlines are 2px thick as long as there is room for t
he 2px line under the baseline. |
779 // All other marked text underlines are 1px thick. | 779 // All other marked text underlines are 1px thick. |
780 // If there's not enough space the underline will touch or overlap character
s. | 780 // If there's not enough space the underline will touch or overlap character
s. |
781 int lineThickness = 1; | 781 int lineThickness = 1; |
782 int baseline = m_inlineTextBox.renderer().style(m_inlineTextBox.isFirstLineS
tyle())->fontMetrics().ascent(); | 782 int baseline = m_inlineTextBox.layoutObject().style(m_inlineTextBox.isFirstL
ineStyle())->fontMetrics().ascent(); |
783 if (underline.thick && m_inlineTextBox.logicalHeight() - baseline >= 2) | 783 if (underline.thick && m_inlineTextBox.logicalHeight() - baseline >= 2) |
784 lineThickness = 2; | 784 lineThickness = 2; |
785 | 785 |
786 // We need to have some space between underlines of subsequent clauses, beca
use some input methods do not use different underline styles for those. | 786 // We need to have some space between underlines of subsequent clauses, beca
use some input methods do not use different underline styles for those. |
787 // We make each line shorter, which has a harmless side effect of shortening
the first and last clauses, too. | 787 // We make each line shorter, which has a harmless side effect of shortening
the first and last clauses, too. |
788 start += 1; | 788 start += 1; |
789 width -= 2; | 789 width -= 2; |
790 | 790 |
791 ctx->setStrokeColor(underline.color); | 791 ctx->setStrokeColor(underline.color); |
792 ctx->setStrokeThickness(lineThickness); | 792 ctx->setStrokeThickness(lineThickness); |
793 ctx->drawLineForText(FloatPoint(boxOrigin.x() + start, boxOrigin.y() + m_inl
ineTextBox.logicalHeight() - lineThickness), width, m_inlineTextBox.renderer().d
ocument().printing()); | 793 ctx->drawLineForText(FloatPoint(boxOrigin.x() + start, boxOrigin.y() + m_inl
ineTextBox.logicalHeight() - lineThickness), width, m_inlineTextBox.layoutObject
().document().printing()); |
794 } | 794 } |
795 | 795 |
796 void InlineTextBoxPainter::paintTextMatchMarker(GraphicsContext* pt, const Float
Point& boxOrigin, DocumentMarker* marker, const LayoutStyle& style, const Font&
font) | 796 void InlineTextBoxPainter::paintTextMatchMarker(GraphicsContext* pt, const Float
Point& boxOrigin, DocumentMarker* marker, const LayoutStyle& style, const Font&
font) |
797 { | 797 { |
798 // Use same y positioning and height as for selection, so that when the sele
ction and this highlight are on | 798 // Use same y positioning and height as for selection, so that when the sele
ction and this highlight are on |
799 // the same word there are no pieces sticking out. | 799 // the same word there are no pieces sticking out. |
800 int deltaY = m_inlineTextBox.renderer().style()->isFlippedLinesWritingMode()
? m_inlineTextBox.root().selectionBottom() - m_inlineTextBox.logicalBottom() :
m_inlineTextBox.logicalTop() - m_inlineTextBox.root().selectionTop(); | 800 int deltaY = m_inlineTextBox.layoutObject().style()->isFlippedLinesWritingMo
de() ? m_inlineTextBox.root().selectionBottom() - m_inlineTextBox.logicalBottom(
) : m_inlineTextBox.logicalTop() - m_inlineTextBox.root().selectionTop(); |
801 int selHeight = m_inlineTextBox.root().selectionHeight(); | 801 int selHeight = m_inlineTextBox.root().selectionHeight(); |
802 | 802 |
803 int sPos = std::max(marker->startOffset() - m_inlineTextBox.start(), (unsign
ed)0); | 803 int sPos = std::max(marker->startOffset() - m_inlineTextBox.start(), (unsign
ed)0); |
804 int ePos = std::min(marker->endOffset() - m_inlineTextBox.start(), m_inlineT
extBox.len()); | 804 int ePos = std::min(marker->endOffset() - m_inlineTextBox.start(), m_inlineT
extBox.len()); |
805 TextRun run = m_inlineTextBox.constructTextRun(style, font); | 805 TextRun run = m_inlineTextBox.constructTextRun(style, font); |
806 | 806 |
807 // Always compute and store the rect associated with this marker. The comput
ed rect is in absolute coordinates. | 807 // Always compute and store the rect associated with this marker. The comput
ed rect is in absolute coordinates. |
808 IntRect markerRect = enclosingIntRect(font.selectionRectForText(run, IntPoin
t(m_inlineTextBox.x(), m_inlineTextBox.root().selectionTop()), selHeight, sPos,
ePos)); | 808 IntRect markerRect = enclosingIntRect(font.selectionRectForText(run, IntPoin
t(m_inlineTextBox.x(), m_inlineTextBox.root().selectionTop()), selHeight, sPos,
ePos)); |
809 markerRect = m_inlineTextBox.renderer().localToAbsoluteQuad(FloatRect(marker
Rect)).enclosingBoundingBox(); | 809 markerRect = m_inlineTextBox.layoutObject().localToAbsoluteQuad(FloatRect(ma
rkerRect)).enclosingBoundingBox(); |
810 toRenderedDocumentMarker(marker)->setRenderedRect(LayoutRect(markerRect)); | 810 toRenderedDocumentMarker(marker)->setRenderedRect(LayoutRect(markerRect)); |
811 | 811 |
812 // Optionally highlight the text | 812 // Optionally highlight the text |
813 if (m_inlineTextBox.renderer().frame()->editor().markedTextMatchesAreHighlig
hted()) { | 813 if (m_inlineTextBox.layoutObject().frame()->editor().markedTextMatchesAreHig
hlighted()) { |
814 Color color = marker->activeMatch() ? | 814 Color color = marker->activeMatch() ? |
815 LayoutTheme::theme().platformActiveTextSearchHighlightColor() : | 815 LayoutTheme::theme().platformActiveTextSearchHighlightColor() : |
816 LayoutTheme::theme().platformInactiveTextSearchHighlightColor(); | 816 LayoutTheme::theme().platformInactiveTextSearchHighlightColor(); |
817 GraphicsContextStateSaver stateSaver(*pt); | 817 GraphicsContextStateSaver stateSaver(*pt); |
818 pt->clip(FloatRect(boxOrigin.x(), boxOrigin.y() - deltaY, m_inlineTextBo
x.logicalWidth(), selHeight)); | 818 pt->clip(FloatRect(boxOrigin.x(), boxOrigin.y() - deltaY, m_inlineTextBo
x.logicalWidth(), selHeight)); |
819 pt->drawHighlightForText(font, run, FloatPoint(boxOrigin.x(), boxOrigin.
y() - deltaY), selHeight, color, sPos, ePos); | 819 pt->drawHighlightForText(font, run, FloatPoint(boxOrigin.x(), boxOrigin.
y() - deltaY), selHeight, color, sPos, ePos); |
820 } | 820 } |
821 } | 821 } |
822 | 822 |
823 | 823 |
824 } // namespace blink | 824 } // namespace blink |
OLD | NEW |