Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(226)

Side by Side Diff: Source/core/rendering/InlineTextBox.cpp

Issue 184023003: Make InlineBox::renderer() and related subclass methods return reference. (Closed) Base URL: https://chromium.googlesource.com/chromium/blink.git@master
Patch Set: No reference reassignment. Created 6 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « Source/core/rendering/InlineTextBox.h ('k') | Source/core/rendering/RenderBlock.cpp » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 /* 1 /*
2 * (C) 1999 Lars Knoll (knoll@kde.org) 2 * (C) 1999 Lars Knoll (knoll@kde.org)
3 * (C) 2000 Dirk Mueller (mueller@kde.org) 3 * (C) 2000 Dirk Mueller (mueller@kde.org)
4 * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Apple Inc. All r ights reserved. 4 * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Apple Inc. All r ights reserved.
5 * 5 *
6 * This library is free software; you can redistribute it and/or 6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Library General Public 7 * modify it under the terms of the GNU Library General Public
8 * License as published by the Free Software Foundation; either 8 * License as published by the Free Software Foundation; either
9 * version 2 of the License, or (at your option) any later version. 9 * version 2 of the License, or (at your option) any later version.
10 * 10 *
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after
99 ASSERT(!knownToHaveNoOverflow()); 99 ASSERT(!knownToHaveNoOverflow());
100 if (!gTextBoxesWithOverflow) 100 if (!gTextBoxesWithOverflow)
101 gTextBoxesWithOverflow = new InlineTextBoxOverflowMap; 101 gTextBoxesWithOverflow = new InlineTextBoxOverflowMap;
102 gTextBoxesWithOverflow->add(this, rect); 102 gTextBoxesWithOverflow->add(this, rect);
103 } 103 }
104 104
105 int InlineTextBox::baselinePosition(FontBaseline baselineType) const 105 int InlineTextBox::baselinePosition(FontBaseline baselineType) const
106 { 106 {
107 if (!isText() || !parent()) 107 if (!isText() || !parent())
108 return 0; 108 return 0;
109 if (parent()->renderer() == renderer()->parent()) 109 if (parent()->renderer() == renderer().parent())
110 return parent()->baselinePosition(baselineType); 110 return parent()->baselinePosition(baselineType);
111 return toRenderBoxModelObject(renderer()->parent())->baselinePosition(baseli neType, isFirstLineStyle(), isHorizontal() ? HorizontalLine : VerticalLine, Posi tionOnContainingLine); 111 return toRenderBoxModelObject(renderer().parent())->baselinePosition(baselin eType, isFirstLineStyle(), isHorizontal() ? HorizontalLine : VerticalLine, Posit ionOnContainingLine);
112 } 112 }
113 113
114 LayoutUnit InlineTextBox::lineHeight() const 114 LayoutUnit InlineTextBox::lineHeight() const
115 { 115 {
116 if (!isText() || !renderer()->parent()) 116 if (!isText() || !renderer().parent())
117 return 0; 117 return 0;
118 if (m_renderer->isBR()) 118 if (renderer().isBR())
119 return toRenderBR(m_renderer)->lineHeight(isFirstLineStyle()); 119 return toRenderBR(renderer()).lineHeight(isFirstLineStyle());
120 if (parent()->renderer() == renderer()->parent()) 120 if (parent()->renderer() == renderer().parent())
121 return parent()->lineHeight(); 121 return parent()->lineHeight();
122 return toRenderBoxModelObject(renderer()->parent())->lineHeight(isFirstLineS tyle(), isHorizontal() ? HorizontalLine : VerticalLine, PositionOnContainingLine ); 122 return toRenderBoxModelObject(renderer().parent())->lineHeight(isFirstLineSt yle(), isHorizontal() ? HorizontalLine : VerticalLine, PositionOnContainingLine) ;
123 } 123 }
124 124
125 LayoutUnit InlineTextBox::selectionTop() 125 LayoutUnit InlineTextBox::selectionTop()
126 { 126 {
127 return root()->selectionTop(); 127 return root()->selectionTop();
128 } 128 }
129 129
130 LayoutUnit InlineTextBox::selectionBottom() 130 LayoutUnit InlineTextBox::selectionBottom()
131 { 131 {
132 return root()->selectionBottom(); 132 return root()->selectionBottom();
133 } 133 }
134 134
135 LayoutUnit InlineTextBox::selectionHeight() 135 LayoutUnit InlineTextBox::selectionHeight()
136 { 136 {
137 return root()->selectionHeight(); 137 return root()->selectionHeight();
138 } 138 }
139 139
140 bool InlineTextBox::isSelected(int startPos, int endPos) const 140 bool InlineTextBox::isSelected(int startPos, int endPos) const
141 { 141 {
142 int sPos = max(startPos - m_start, 0); 142 int sPos = max(startPos - m_start, 0);
143 // The position after a hard line break is considered to be past its end. 143 // The position after a hard line break is considered to be past its end.
144 // See the corresponding code in InlineTextBox::selectionState. 144 // See the corresponding code in InlineTextBox::selectionState.
145 int ePos = min(endPos - m_start, int(m_len) + (isLineBreak() ? 0 : 1)); 145 int ePos = min(endPos - m_start, int(m_len) + (isLineBreak() ? 0 : 1));
146 return (sPos < ePos); 146 return (sPos < ePos);
147 } 147 }
148 148
149 RenderObject::SelectionState InlineTextBox::selectionState() 149 RenderObject::SelectionState InlineTextBox::selectionState()
150 { 150 {
151 RenderObject::SelectionState state = renderer()->selectionState(); 151 RenderObject::SelectionState state = renderer().selectionState();
152 if (state == RenderObject::SelectionStart || state == RenderObject::Selectio nEnd || state == RenderObject::SelectionBoth) { 152 if (state == RenderObject::SelectionStart || state == RenderObject::Selectio nEnd || state == RenderObject::SelectionBoth) {
153 int startPos, endPos; 153 int startPos, endPos;
154 renderer()->selectionStartEnd(startPos, endPos); 154 renderer().selectionStartEnd(startPos, endPos);
155 // The position after a hard line break is considered to be past its end . 155 // The position after a hard line break is considered to be past its end .
156 // See the corresponding code in InlineTextBox::isSelected. 156 // See the corresponding code in InlineTextBox::isSelected.
157 int lastSelectable = start() + len() - (isLineBreak() ? 1 : 0); 157 int lastSelectable = start() + len() - (isLineBreak() ? 1 : 0);
158 158
159 // FIXME: Remove -webkit-line-break: LineBreakAfterWhiteSpace. 159 // FIXME: Remove -webkit-line-break: LineBreakAfterWhiteSpace.
160 int endOfLineAdjustmentForCSSLineBreak = renderer()->style()->lineBreak( ) == LineBreakAfterWhiteSpace ? -1 : 0; 160 int endOfLineAdjustmentForCSSLineBreak = renderer().style()->lineBreak() == LineBreakAfterWhiteSpace ? -1 : 0;
161 bool start = (state != RenderObject::SelectionEnd && startPos >= m_start && startPos <= m_start + m_len + endOfLineAdjustmentForCSSLineBreak); 161 bool start = (state != RenderObject::SelectionEnd && startPos >= m_start && startPos <= m_start + m_len + endOfLineAdjustmentForCSSLineBreak);
162 bool end = (state != RenderObject::SelectionStart && endPos > m_start && endPos <= lastSelectable); 162 bool end = (state != RenderObject::SelectionStart && endPos > m_start && endPos <= lastSelectable);
163 if (start && end) 163 if (start && end)
164 state = RenderObject::SelectionBoth; 164 state = RenderObject::SelectionBoth;
165 else if (start) 165 else if (start)
166 state = RenderObject::SelectionStart; 166 state = RenderObject::SelectionStart;
167 else if (end) 167 else if (end)
168 state = RenderObject::SelectionEnd; 168 state = RenderObject::SelectionEnd;
169 else if ((state == RenderObject::SelectionEnd || startPos < m_start) && 169 else if ((state == RenderObject::SelectionEnd || startPos < m_start) &&
170 (state == RenderObject::SelectionStart || endPos > lastSelectab le)) 170 (state == RenderObject::SelectionStart || endPos > lastSelectab le))
(...skipping 24 matching lines...) Expand all
195 LayoutRect InlineTextBox::localSelectionRect(int startPos, int endPos) 195 LayoutRect InlineTextBox::localSelectionRect(int startPos, int endPos)
196 { 196 {
197 int sPos = max(startPos - m_start, 0); 197 int sPos = max(startPos - m_start, 0);
198 int ePos = min(endPos - m_start, (int)m_len); 198 int ePos = min(endPos - m_start, (int)m_len);
199 199
200 if (sPos > ePos) 200 if (sPos > ePos)
201 return LayoutRect(); 201 return LayoutRect();
202 202
203 FontCachePurgePreventer fontCachePurgePreventer; 203 FontCachePurgePreventer fontCachePurgePreventer;
204 204
205 RenderText* textObj = textRenderer();
206 LayoutUnit selTop = selectionTop(); 205 LayoutUnit selTop = selectionTop();
207 LayoutUnit selHeight = selectionHeight(); 206 LayoutUnit selHeight = selectionHeight();
208 RenderStyle* styleToUse = textObj->style(isFirstLineStyle()); 207 RenderStyle* styleToUse = textRenderer().style(isFirstLineStyle());
209 const Font& font = styleToUse->font(); 208 const Font& font = styleToUse->font();
210 209
211 StringBuilder charactersWithHyphen; 210 StringBuilder charactersWithHyphen;
212 bool respectHyphen = ePos == m_len && hasHyphen(); 211 bool respectHyphen = ePos == m_len && hasHyphen();
213 TextRun textRun = constructTextRun(styleToUse, font, respectHyphen ? &charac tersWithHyphen : 0); 212 TextRun textRun = constructTextRun(styleToUse, font, respectHyphen ? &charac tersWithHyphen : 0);
214 213
215 FloatPoint startingPoint = FloatPoint(logicalLeft(), selTop); 214 FloatPoint startingPoint = FloatPoint(logicalLeft(), selTop);
216 LayoutRect r; 215 LayoutRect r;
217 if (sPos || ePos != static_cast<int>(m_len)) 216 if (sPos || ePos != static_cast<int>(m_len))
218 r = enclosingIntRect(font.selectionRectForText(textRun, startingPoint, s elHeight, sPos, ePos)); 217 r = enclosingIntRect(font.selectionRectForText(textRun, startingPoint, s elHeight, sPos, ePos));
219 else // Avoid computing the font width when the entire line box is selected as an optimization. 218 else // Avoid computing the font width when the entire line box is selected as an optimization.
220 r = enclosingIntRect(FloatRect(startingPoint, FloatSize(m_logicalWidth, selHeight))); 219 r = enclosingIntRect(FloatRect(startingPoint, FloatSize(m_logicalWidth, selHeight)));
221 220
222 LayoutUnit logicalWidth = r.width(); 221 LayoutUnit logicalWidth = r.width();
223 if (r.x() > logicalRight()) 222 if (r.x() > logicalRight())
224 logicalWidth = 0; 223 logicalWidth = 0;
225 else if (r.maxX() > logicalRight()) 224 else if (r.maxX() > logicalRight())
226 logicalWidth = logicalRight() - r.x(); 225 logicalWidth = logicalRight() - r.x();
227 226
228 LayoutPoint topPoint = isHorizontal() ? LayoutPoint(r.x(), selTop) : LayoutP oint(selTop, r.x()); 227 LayoutPoint topPoint = isHorizontal() ? LayoutPoint(r.x(), selTop) : LayoutP oint(selTop, r.x());
229 LayoutUnit width = isHorizontal() ? logicalWidth : selHeight; 228 LayoutUnit width = isHorizontal() ? logicalWidth : selHeight;
230 LayoutUnit height = isHorizontal() ? selHeight : logicalWidth; 229 LayoutUnit height = isHorizontal() ? selHeight : logicalWidth;
231 230
232 return LayoutRect(topPoint, LayoutSize(width, height)); 231 return LayoutRect(topPoint, LayoutSize(width, height));
233 } 232 }
234 233
235 void InlineTextBox::deleteLine() 234 void InlineTextBox::deleteLine()
236 { 235 {
237 toRenderText(renderer())->removeTextBox(this); 236 toRenderText(renderer()).removeTextBox(this);
238 destroy(); 237 destroy();
239 } 238 }
240 239
241 void InlineTextBox::extractLine() 240 void InlineTextBox::extractLine()
242 { 241 {
243 if (extracted()) 242 if (extracted())
244 return; 243 return;
245 244
246 toRenderText(renderer())->extractTextBox(this); 245 toRenderText(renderer()).extractTextBox(this);
247 } 246 }
248 247
249 void InlineTextBox::attachLine() 248 void InlineTextBox::attachLine()
250 { 249 {
251 if (!extracted()) 250 if (!extracted())
252 return; 251 return;
253 252
254 toRenderText(renderer())->attachTextBox(this); 253 toRenderText(renderer()).attachTextBox(this);
255 } 254 }
256 255
257 float InlineTextBox::placeEllipsisBox(bool flowIsLTR, float visibleLeftEdge, flo at visibleRightEdge, float ellipsisWidth, float &truncatedWidth, bool& foundBox) 256 float InlineTextBox::placeEllipsisBox(bool flowIsLTR, float visibleLeftEdge, flo at visibleRightEdge, float ellipsisWidth, float &truncatedWidth, bool& foundBox)
258 { 257 {
259 if (foundBox) { 258 if (foundBox) {
260 m_truncation = cFullTruncation; 259 m_truncation = cFullTruncation;
261 return -1; 260 return -1;
262 } 261 }
263 262
264 // For LTR this is the left edge of the box, for RTL, the right edge in pare nt coordinates. 263 // For LTR this is the left edge of the box, for RTL, the right edge in pare nt coordinates.
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
298 m_truncation = cFullTruncation; 297 m_truncation = cFullTruncation;
299 truncatedWidth += ellipsisWidth; 298 truncatedWidth += ellipsisWidth;
300 return min(ellipsisX, logicalLeft()); 299 return min(ellipsisX, logicalLeft());
301 } 300 }
302 301
303 // Set the truncation index on the text run. 302 // Set the truncation index on the text run.
304 m_truncation = offset; 303 m_truncation = offset;
305 304
306 // If we got here that means that we were only partially truncated and w e need to return the pixel offset at which 305 // If we got here that means that we were only partially truncated and w e need to return the pixel offset at which
307 // to place the ellipsis. 306 // to place the ellipsis.
308 float widthOfVisibleText = toRenderText(renderer())->width(m_start, offs et, textPos(), flowIsLTR ? LTR : RTL, isFirstLineStyle()); 307 float widthOfVisibleText = toRenderText(renderer()).width(m_start, offse t, textPos(), flowIsLTR ? LTR : RTL, isFirstLineStyle());
309 308
310 // The ellipsis needs to be placed just after the last visible character . 309 // The ellipsis needs to be placed just after the last visible character .
311 // Where "after" is defined by the flow directionality, not the inline 310 // Where "after" is defined by the flow directionality, not the inline
312 // box directionality. 311 // box directionality.
313 // e.g. In the case of an LTR inline box truncated in an RTL flow then w e can 312 // e.g. In the case of an LTR inline box truncated in an RTL flow then w e can
314 // have a situation such as |Hello| -> |...He| 313 // have a situation such as |Hello| -> |...He|
315 truncatedWidth += widthOfVisibleText + ellipsisWidth; 314 truncatedWidth += widthOfVisibleText + ellipsisWidth;
316 if (flowIsLTR) 315 if (flowIsLTR)
317 return logicalLeft() + widthOfVisibleText; 316 return logicalLeft() + widthOfVisibleText;
318 else 317 else
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
360 if (mode & TextModeStroke) { 359 if (mode & TextModeStroke) {
361 if (strokeColor != context->strokeColor()) 360 if (strokeColor != context->strokeColor())
362 context->setStrokeColor(strokeColor); 361 context->setStrokeColor(strokeColor);
363 if (strokeThickness != context->strokeThickness()) 362 if (strokeThickness != context->strokeThickness())
364 context->setStrokeThickness(strokeThickness); 363 context->setStrokeThickness(strokeThickness);
365 } 364 }
366 } 365 }
367 366
368 bool InlineTextBox::isLineBreak() const 367 bool InlineTextBox::isLineBreak() const
369 { 368 {
370 return renderer()->isBR() || (renderer()->style()->preserveNewline() && len( ) == 1 && (*textRenderer()->text().impl())[start()] == '\n'); 369 return renderer().isBR() || (renderer().style()->preserveNewline() && len() == 1 && (*textRenderer().text().impl())[start()] == '\n');
371 } 370 }
372 371
373 bool InlineTextBox::nodeAtPoint(const HitTestRequest& request, HitTestResult& re sult, const HitTestLocation& locationInContainer, const LayoutPoint& accumulated Offset, LayoutUnit /* lineTop */, LayoutUnit /*lineBottom*/) 372 bool InlineTextBox::nodeAtPoint(const HitTestRequest& request, HitTestResult& re sult, const HitTestLocation& locationInContainer, const LayoutPoint& accumulated Offset, LayoutUnit /* lineTop */, LayoutUnit /*lineBottom*/)
374 { 373 {
375 if (isLineBreak()) 374 if (isLineBreak())
376 return false; 375 return false;
377 376
378 FloatPoint boxOrigin = locationIncludingFlipping(); 377 FloatPoint boxOrigin = locationIncludingFlipping();
379 boxOrigin.moveBy(accumulatedOffset); 378 boxOrigin.moveBy(accumulatedOffset);
380 FloatRect rect(boxOrigin, size()); 379 FloatRect rect(boxOrigin, size());
381 if (m_truncation != cFullTruncation && visibleToHitTestRequest(request) && l ocationInContainer.intersects(rect)) { 380 if (m_truncation != cFullTruncation && visibleToHitTestRequest(request) && l ocationInContainer.intersects(rect)) {
382 renderer()->updateHitTestResult(result, flipForWritingMode(locationInCon tainer.point() - toLayoutSize(accumulatedOffset))); 381 renderer().updateHitTestResult(result, flipForWritingMode(locationInCont ainer.point() - toLayoutSize(accumulatedOffset)));
383 if (!result.addNodeToRectBasedTestResult(renderer()->node(), request, lo cationInContainer, rect)) 382 if (!result.addNodeToRectBasedTestResult(renderer().node(), request, loc ationInContainer, rect))
384 return true; 383 return true;
385 } 384 }
386 return false; 385 return false;
387 } 386 }
388 387
389 static void paintTextWithShadows(GraphicsContext* context, 388 static void paintTextWithShadows(GraphicsContext* context,
390 const RenderObject* renderer, const Font& font, const TextRun& textRun, 389 const RenderObject& renderer, const Font& font, const TextRun& textRun,
391 const AtomicString& emphasisMark, int emphasisMarkOffset, 390 const AtomicString& emphasisMark, int emphasisMarkOffset,
392 int startOffset, int endOffset, int truncationPoint, 391 int startOffset, int endOffset, int truncationPoint,
393 const FloatPoint& textOrigin, const FloatRect& boxRect, 392 const FloatPoint& textOrigin, const FloatRect& boxRect,
394 const ShadowList* shadowList, bool stroked, bool horizontal) 393 const ShadowList* shadowList, bool stroked, bool horizontal)
395 { 394 {
396 // Text shadows are disabled when printing. http://crbug.com/258321 395 // Text shadows are disabled when printing. http://crbug.com/258321
397 bool hasShadow = shadowList && !context->printing(); 396 bool hasShadow = shadowList && !context->printing();
398 397
399 if (hasShadow) { 398 if (hasShadow) {
400 OwnPtr<DrawLooperBuilder> drawLooperBuilder = DrawLooperBuilder::create( ); 399 OwnPtr<DrawLooperBuilder> drawLooperBuilder = DrawLooperBuilder::create( );
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
445 bool InlineTextBox::getEmphasisMarkPosition(RenderStyle* style, TextEmphasisPosi tion& emphasisPosition) const 444 bool InlineTextBox::getEmphasisMarkPosition(RenderStyle* style, TextEmphasisPosi tion& emphasisPosition) const
446 { 445 {
447 // This function returns true if there are text emphasis marks and they are suppressed by ruby text. 446 // This function returns true if there are text emphasis marks and they are suppressed by ruby text.
448 if (style->textEmphasisMark() == TextEmphasisMarkNone) 447 if (style->textEmphasisMark() == TextEmphasisMarkNone)
449 return false; 448 return false;
450 449
451 emphasisPosition = style->textEmphasisPosition(); 450 emphasisPosition = style->textEmphasisPosition();
452 if (emphasisPosition == TextEmphasisPositionUnder) 451 if (emphasisPosition == TextEmphasisPositionUnder)
453 return true; // Ruby text is always over, so it cannot suppress emphasis marks under. 452 return true; // Ruby text is always over, so it cannot suppress emphasis marks under.
454 453
455 RenderBlock* containingBlock = renderer()->containingBlock(); 454 RenderBlock* containingBlock = renderer().containingBlock();
456 if (!containingBlock->isRubyBase()) 455 if (!containingBlock->isRubyBase())
457 return true; // This text is not inside a ruby base, so it does not have ruby text over it. 456 return true; // This text is not inside a ruby base, so it does not have ruby text over it.
458 457
459 if (!containingBlock->parent()->isRubyRun()) 458 if (!containingBlock->parent()->isRubyRun())
460 return true; // Cannot get the ruby text. 459 return true; // Cannot get the ruby text.
461 460
462 RenderRubyText* rubyText = toRenderRubyRun(containingBlock->parent())->rubyT ext(); 461 RenderRubyText* rubyText = toRenderRubyRun(containingBlock->parent())->rubyT ext();
463 462
464 // The emphasis marks over are suppressed only if there is a ruby text box a nd it not empty. 463 // The emphasis marks over are suppressed only if there is a ruby text box a nd it not empty.
465 return !rubyText || !rubyText->firstLineBox(); 464 return !rubyText || !rubyText->firstLineBox();
466 } 465 }
467 466
468 void InlineTextBox::paint(PaintInfo& paintInfo, const LayoutPoint& paintOffset, LayoutUnit /*lineTop*/, LayoutUnit /*lineBottom*/) 467 void InlineTextBox::paint(PaintInfo& paintInfo, const LayoutPoint& paintOffset, LayoutUnit /*lineTop*/, LayoutUnit /*lineBottom*/)
469 { 468 {
470 if (isLineBreak() || !paintInfo.shouldPaintWithinRoot(renderer()) || rendere r()->style()->visibility() != VISIBLE || 469 if (isLineBreak() || !paintInfo.shouldPaintWithinRoot(&renderer()) || render er().style()->visibility() != VISIBLE
471 m_truncation == cFullTruncation || paintInfo.phase == PaintPhaseOutline || !m_len) 470 || m_truncation == cFullTruncation || paintInfo.phase == PaintPhaseOutli ne || !m_len)
472 return; 471 return;
473 472
474 ASSERT(paintInfo.phase != PaintPhaseSelfOutline && paintInfo.phase != PaintP haseChildOutlines); 473 ASSERT(paintInfo.phase != PaintPhaseSelfOutline && paintInfo.phase != PaintP haseChildOutlines);
475 474
476 LayoutUnit logicalLeftSide = logicalLeftVisualOverflow(); 475 LayoutUnit logicalLeftSide = logicalLeftVisualOverflow();
477 LayoutUnit logicalRightSide = logicalRightVisualOverflow(); 476 LayoutUnit logicalRightSide = logicalRightVisualOverflow();
478 LayoutUnit logicalStart = logicalLeftSide + (isHorizontal() ? paintOffset.x( ) : paintOffset.y()); 477 LayoutUnit logicalStart = logicalLeftSide + (isHorizontal() ? paintOffset.x( ) : paintOffset.y());
479 LayoutUnit logicalExtent = logicalRightSide - logicalLeftSide; 478 LayoutUnit logicalExtent = logicalRightSide - logicalLeftSide;
480 479
481 LayoutUnit paintEnd = isHorizontal() ? paintInfo.rect.maxX() : paintInfo.rec t.maxY(); 480 LayoutUnit paintEnd = isHorizontal() ? paintInfo.rect.maxX() : paintInfo.rec t.maxY();
482 LayoutUnit paintStart = isHorizontal() ? paintInfo.rect.x() : paintInfo.rect .y(); 481 LayoutUnit paintStart = isHorizontal() ? paintInfo.rect.x() : paintInfo.rect .y();
483 482
484 LayoutPoint adjustedPaintOffset = roundedIntPoint(paintOffset); 483 LayoutPoint adjustedPaintOffset = roundedIntPoint(paintOffset);
485 484
486 if (logicalStart >= paintEnd || logicalStart + logicalExtent <= paintStart) 485 if (logicalStart >= paintEnd || logicalStart + logicalExtent <= paintStart)
487 return; 486 return;
488 487
489 bool isPrinting = textRenderer()->document().printing(); 488 bool isPrinting = textRenderer().document().printing();
490 489
491 // Determine whether or not we're selected. 490 // Determine whether or not we're selected.
492 bool haveSelection = !isPrinting && paintInfo.phase != PaintPhaseTextClip && selectionState() != RenderObject::SelectionNone; 491 bool haveSelection = !isPrinting && paintInfo.phase != PaintPhaseTextClip && selectionState() != RenderObject::SelectionNone;
493 if (!haveSelection && paintInfo.phase == PaintPhaseSelection) 492 if (!haveSelection && paintInfo.phase == PaintPhaseSelection)
494 // When only painting the selection, don't bother to paint if there is n one. 493 // When only painting the selection, don't bother to paint if there is n one.
495 return; 494 return;
496 495
497 if (m_truncation != cNoTruncation) { 496 if (m_truncation != cNoTruncation) {
498 if (renderer()->containingBlock()->style()->isLeftToRightDirection() != isLeftToRightDirection()) { 497 if (renderer().containingBlock()->style()->isLeftToRightDirection() != i sLeftToRightDirection()) {
499 // Make the visible fragment of text hug the edge closest to the res t of the run by moving the origin 498 // Make the visible fragment of text hug the edge closest to the res t of the run by moving the origin
500 // at which we start drawing text. 499 // at which we start drawing text.
501 // e.g. In the case of LTR text truncated in an RTL Context, the cor rect behavior is: 500 // e.g. In the case of LTR text truncated in an RTL Context, the cor rect behavior is:
502 // |Hello|CBA| -> |...He|CBA| 501 // |Hello|CBA| -> |...He|CBA|
503 // In order to draw the fragment "He" aligned to the right edge of i t's box, we need to start drawing 502 // In order to draw the fragment "He" aligned to the right edge of i t's box, we need to start drawing
504 // farther to the right. 503 // farther to the right.
505 // NOTE: WebKit's behavior differs from that of IE which appears to just overlay the ellipsis on top of the 504 // NOTE: WebKit's behavior differs from that of IE which appears to just overlay the ellipsis on top of the
506 // truncated string i.e. |Hello|CBA| -> |...lo|CBA| 505 // truncated string i.e. |Hello|CBA| -> |...lo|CBA|
507 LayoutUnit widthOfVisibleText = toRenderText(renderer())->width(m_st art, m_truncation, textPos(), isLeftToRightDirection() ? LTR : RTL, isFirstLineS tyle()); 506 LayoutUnit widthOfVisibleText = toRenderText(renderer()).width(m_sta rt, m_truncation, textPos(), isLeftToRightDirection() ? LTR : RTL, isFirstLineSt yle());
508 LayoutUnit widthOfHiddenText = m_logicalWidth - widthOfVisibleText; 507 LayoutUnit widthOfHiddenText = m_logicalWidth - widthOfVisibleText;
509 // FIXME: The hit testing logic also needs to take this translation into account. 508 // FIXME: The hit testing logic also needs to take this translation into account.
510 LayoutSize truncationOffset(isLeftToRightDirection() ? widthOfHidden Text : -widthOfHiddenText, 0); 509 LayoutSize truncationOffset(isLeftToRightDirection() ? widthOfHidden Text : -widthOfHiddenText, 0);
511 adjustedPaintOffset.move(isHorizontal() ? truncationOffset : truncat ionOffset.transposedSize()); 510 adjustedPaintOffset.move(isHorizontal() ? truncationOffset : truncat ionOffset.transposedSize());
512 } 511 }
513 } 512 }
514 513
515 GraphicsContext* context = paintInfo.context; 514 GraphicsContext* context = paintInfo.context;
516 515
517 RenderObject* rendererToUse = renderer(); 516 RenderObject& rendererToUse = renderer();
518 RenderStyle* styleToUse = rendererToUse->style(isFirstLineStyle()); 517 RenderStyle* styleToUse = rendererToUse.style(isFirstLineStyle());
519 518
520 adjustedPaintOffset.move(0, styleToUse->isHorizontalWritingMode() ? 0 : -log icalHeight()); 519 adjustedPaintOffset.move(0, styleToUse->isHorizontalWritingMode() ? 0 : -log icalHeight());
521 520
522 FloatPoint boxOrigin = locationIncludingFlipping(); 521 FloatPoint boxOrigin = locationIncludingFlipping();
523 boxOrigin.move(adjustedPaintOffset.x(), adjustedPaintOffset.y()); 522 boxOrigin.move(adjustedPaintOffset.x(), adjustedPaintOffset.y());
524 FloatRect boxRect(boxOrigin, LayoutSize(logicalWidth(), logicalHeight())); 523 FloatRect boxRect(boxOrigin, LayoutSize(logicalWidth(), logicalHeight()));
525 524
526 RenderCombineText* combinedText = styleToUse->hasTextCombine() && textRender er()->isCombineText() && toRenderCombineText(textRenderer())->isCombined() ? toR enderCombineText(textRenderer()) : 0; 525 RenderCombineText* combinedText = styleToUse->hasTextCombine() && textRender er().isCombineText() && toRenderCombineText(textRenderer()).isCombined() ? &toRe nderCombineText(textRenderer()) : 0;
527 526
528 bool shouldRotate = !isHorizontal() && !combinedText; 527 bool shouldRotate = !isHorizontal() && !combinedText;
529 if (shouldRotate) 528 if (shouldRotate)
530 context->concatCTM(rotation(boxRect, Clockwise)); 529 context->concatCTM(rotation(boxRect, Clockwise));
531 530
532 // Determine whether or not we have composition underlines to draw. 531 // Determine whether or not we have composition underlines to draw.
533 bool containsComposition = renderer()->node() && renderer()->frame()->inputM ethodController().compositionNode() == renderer()->node(); 532 bool containsComposition = renderer().node() && renderer().frame()->inputMet hodController().compositionNode() == renderer().node();
534 bool useCustomUnderlines = containsComposition && renderer()->frame()->input MethodController().compositionUsesCustomUnderlines(); 533 bool useCustomUnderlines = containsComposition && renderer().frame()->inputM ethodController().compositionUsesCustomUnderlines();
535 534
536 // Determine the text colors and selection colors. 535 // Determine the text colors and selection colors.
537 Color textFillColor; 536 Color textFillColor;
538 Color textStrokeColor; 537 Color textStrokeColor;
539 Color emphasisMarkColor; 538 Color emphasisMarkColor;
540 float textStrokeWidth = styleToUse->textStrokeWidth(); 539 float textStrokeWidth = styleToUse->textStrokeWidth();
541 540
542 // Text shadows are disabled when printing. http://crbug.com/258321 541 // Text shadows are disabled when printing. http://crbug.com/258321
543 const ShadowList* textShadow = (context->printing() || paintInfo.forceBlackT ext()) ? 0 : styleToUse->textShadow(); 542 const ShadowList* textShadow = (context->printing() || paintInfo.forceBlackT ext()) ? 0 : styleToUse->textShadow();
544 543
545 if (paintInfo.forceBlackText()) { 544 if (paintInfo.forceBlackText()) {
546 textFillColor = Color::black; 545 textFillColor = Color::black;
547 textStrokeColor = Color::black; 546 textStrokeColor = Color::black;
548 emphasisMarkColor = Color::black; 547 emphasisMarkColor = Color::black;
549 } else { 548 } else {
550 textFillColor = rendererToUse->resolveColor(styleToUse, CSSPropertyWebki tTextFillColor); 549 textFillColor = rendererToUse.resolveColor(styleToUse, CSSPropertyWebkit TextFillColor);
551 550
552 bool forceBackgroundToWhite = false; 551 bool forceBackgroundToWhite = false;
553 if (isPrinting) { 552 if (isPrinting) {
554 if (styleToUse->printColorAdjust() == PrintColorAdjustEconomy) 553 if (styleToUse->printColorAdjust() == PrintColorAdjustEconomy)
555 forceBackgroundToWhite = true; 554 forceBackgroundToWhite = true;
556 if (textRenderer()->document().settings() && textRenderer()->documen t().settings()->shouldPrintBackgrounds()) 555 if (textRenderer().document().settings() && textRenderer().document( ).settings()->shouldPrintBackgrounds())
557 forceBackgroundToWhite = false; 556 forceBackgroundToWhite = false;
558 } 557 }
559 558
560 // Make the text fill color legible against a white background 559 // Make the text fill color legible against a white background
561 if (forceBackgroundToWhite) 560 if (forceBackgroundToWhite)
562 textFillColor = correctedTextColor(textFillColor, Color::white); 561 textFillColor = correctedTextColor(textFillColor, Color::white);
563 562
564 textStrokeColor = rendererToUse->resolveColor(styleToUse, CSSPropertyWeb kitTextStrokeColor); 563 textStrokeColor = rendererToUse.resolveColor(styleToUse, CSSPropertyWebk itTextStrokeColor);
565 564
566 // Make the text stroke color legible against a white background 565 // Make the text stroke color legible against a white background
567 if (forceBackgroundToWhite) 566 if (forceBackgroundToWhite)
568 textStrokeColor = correctedTextColor(textStrokeColor, Color::white); 567 textStrokeColor = correctedTextColor(textStrokeColor, Color::white);
569 568
570 emphasisMarkColor = rendererToUse->resolveColor(styleToUse, CSSPropertyW ebkitTextEmphasisColor); 569 emphasisMarkColor = rendererToUse.resolveColor(styleToUse, CSSPropertyWe bkitTextEmphasisColor);
571 570
572 // Make the text stroke color legible against a white background 571 // Make the text stroke color legible against a white background
573 if (forceBackgroundToWhite) 572 if (forceBackgroundToWhite)
574 emphasisMarkColor = correctedTextColor(emphasisMarkColor, Color::whi te); 573 emphasisMarkColor = correctedTextColor(emphasisMarkColor, Color::whi te);
575 } 574 }
576 575
577 bool paintSelectedTextOnly = (paintInfo.phase == PaintPhaseSelection); 576 bool paintSelectedTextOnly = (paintInfo.phase == PaintPhaseSelection);
578 bool paintSelectedTextSeparately = false; 577 bool paintSelectedTextSeparately = false;
579 578
580 Color selectionFillColor = textFillColor; 579 Color selectionFillColor = textFillColor;
581 Color selectionStrokeColor = textStrokeColor; 580 Color selectionStrokeColor = textStrokeColor;
582 Color selectionEmphasisMarkColor = emphasisMarkColor; 581 Color selectionEmphasisMarkColor = emphasisMarkColor;
583 float selectionStrokeWidth = textStrokeWidth; 582 float selectionStrokeWidth = textStrokeWidth;
584 const ShadowList* selectionShadow = textShadow; 583 const ShadowList* selectionShadow = textShadow;
585 if (haveSelection) { 584 if (haveSelection) {
586 // Check foreground color first. 585 // Check foreground color first.
587 Color foreground = paintInfo.forceBlackText() ? Color::black : renderer( )->selectionForegroundColor(); 586 Color foreground = paintInfo.forceBlackText() ? Color::black : renderer( ).selectionForegroundColor();
588 if (foreground != selectionFillColor) { 587 if (foreground != selectionFillColor) {
589 if (!paintSelectedTextOnly) 588 if (!paintSelectedTextOnly)
590 paintSelectedTextSeparately = true; 589 paintSelectedTextSeparately = true;
591 selectionFillColor = foreground; 590 selectionFillColor = foreground;
592 } 591 }
593 592
594 Color emphasisMarkForeground = paintInfo.forceBlackText() ? Color::black : renderer()->selectionEmphasisMarkColor(); 593 Color emphasisMarkForeground = paintInfo.forceBlackText() ? Color::black : renderer().selectionEmphasisMarkColor();
595 if (emphasisMarkForeground != selectionEmphasisMarkColor) { 594 if (emphasisMarkForeground != selectionEmphasisMarkColor) {
596 if (!paintSelectedTextOnly) 595 if (!paintSelectedTextOnly)
597 paintSelectedTextSeparately = true; 596 paintSelectedTextSeparately = true;
598 selectionEmphasisMarkColor = emphasisMarkForeground; 597 selectionEmphasisMarkColor = emphasisMarkForeground;
599 } 598 }
600 599
601 if (RenderStyle* pseudoStyle = renderer()->getCachedPseudoStyle(SELECTIO N)) { 600 if (RenderStyle* pseudoStyle = renderer().getCachedPseudoStyle(SELECTION )) {
602 // Text shadows are disabled when printing. http://crbug.com/258321 601 // Text shadows are disabled when printing. http://crbug.com/258321
603 const ShadowList* shadow = (context->printing() || paintInfo.forceBl ackText()) ? 0 : pseudoStyle->textShadow(); 602 const ShadowList* shadow = (context->printing() || paintInfo.forceBl ackText()) ? 0 : pseudoStyle->textShadow();
604 if (shadow != selectionShadow) { 603 if (shadow != selectionShadow) {
605 if (!paintSelectedTextOnly) 604 if (!paintSelectedTextOnly)
606 paintSelectedTextSeparately = true; 605 paintSelectedTextSeparately = true;
607 selectionShadow = shadow; 606 selectionShadow = shadow;
608 } 607 }
609 608
610 float strokeWidth = pseudoStyle->textStrokeWidth(); 609 float strokeWidth = pseudoStyle->textStrokeWidth();
611 if (strokeWidth != selectionStrokeWidth) { 610 if (strokeWidth != selectionStrokeWidth) {
612 if (!paintSelectedTextOnly) 611 if (!paintSelectedTextOnly)
613 paintSelectedTextSeparately = true; 612 paintSelectedTextSeparately = true;
614 selectionStrokeWidth = strokeWidth; 613 selectionStrokeWidth = strokeWidth;
615 } 614 }
616 615
617 Color stroke = paintInfo.forceBlackText() ? Color::black : rendererT oUse->resolveColor(pseudoStyle, CSSPropertyWebkitTextStrokeColor); 616 Color stroke = paintInfo.forceBlackText() ? Color::black : rendererT oUse.resolveColor(pseudoStyle, CSSPropertyWebkitTextStrokeColor);
618 if (stroke != selectionStrokeColor) { 617 if (stroke != selectionStrokeColor) {
619 if (!paintSelectedTextOnly) 618 if (!paintSelectedTextOnly)
620 paintSelectedTextSeparately = true; 619 paintSelectedTextSeparately = true;
621 selectionStrokeColor = stroke; 620 selectionStrokeColor = stroke;
622 } 621 }
623 } 622 }
624 } 623 }
625 624
626 // Set our font. 625 // Set our font.
627 const Font& font = styleToUse->font(); 626 const Font& font = styleToUse->font();
628 627
629 FloatPoint textOrigin = FloatPoint(boxOrigin.x(), boxOrigin.y() + font.fontM etrics().ascent()); 628 FloatPoint textOrigin = FloatPoint(boxOrigin.x(), boxOrigin.y() + font.fontM etrics().ascent());
630 629
631 if (combinedText) 630 if (combinedText)
632 combinedText->adjustTextOrigin(textOrigin, boxRect); 631 combinedText->adjustTextOrigin(textOrigin, boxRect);
633 632
634 // 1. Paint backgrounds behind text if needed. Examples of such backgrounds include selection 633 // 1. Paint backgrounds behind text if needed. Examples of such backgrounds include selection
635 // and composition underlines. 634 // and composition underlines.
636 if (paintInfo.phase != PaintPhaseSelection && paintInfo.phase != PaintPhaseT extClip && !isPrinting) { 635 if (paintInfo.phase != PaintPhaseSelection && paintInfo.phase != PaintPhaseT extClip && !isPrinting) {
637 636
638 if (containsComposition && !useCustomUnderlines) { 637 if (containsComposition && !useCustomUnderlines) {
639 paintCompositionBackground(context, boxOrigin, styleToUse, font, 638 paintCompositionBackground(context, boxOrigin, styleToUse, font,
640 renderer()->frame()->inputMethodController().compositionStart(), 639 renderer().frame()->inputMethodController().compositionStart(),
641 renderer()->frame()->inputMethodController().compositionEnd()); 640 renderer().frame()->inputMethodController().compositionEnd());
642 } 641 }
643 642
644 paintDocumentMarkers(context, boxOrigin, styleToUse, font, true); 643 paintDocumentMarkers(context, boxOrigin, styleToUse, font, true);
645 644
646 if (haveSelection && !useCustomUnderlines) 645 if (haveSelection && !useCustomUnderlines)
647 paintSelection(context, boxOrigin, styleToUse, font, selectionFillCo lor); 646 paintSelection(context, boxOrigin, styleToUse, font, selectionFillCo lor);
648 } 647 }
649 648
650 // 2. Now paint the foreground, including text and decorations like underlin e/overline (in quirks mode only). 649 // 2. Now paint the foreground, including text and decorations like underlin e/overline (in quirks mode only).
651 int length = m_len; 650 int length = m_len;
652 int maximumLength; 651 int maximumLength;
653 StringView string; 652 StringView string;
654 if (!combinedText) { 653 if (!combinedText) {
655 string = textRenderer()->text().createView(); 654 string = textRenderer().text().createView();
656 if (static_cast<unsigned>(length) != string.length() || m_start) 655 if (static_cast<unsigned>(length) != string.length() || m_start)
657 string.narrow(m_start, length); 656 string.narrow(m_start, length);
658 maximumLength = textRenderer()->textLength() - m_start; 657 maximumLength = textRenderer().textLength() - m_start;
659 } else { 658 } else {
660 combinedText->getStringToRender(m_start, string, length); 659 combinedText->getStringToRender(m_start, string, length);
661 maximumLength = length; 660 maximumLength = length;
662 } 661 }
663 662
664 StringBuilder charactersWithHyphen; 663 StringBuilder charactersWithHyphen;
665 TextRun textRun = constructTextRun(styleToUse, font, string, maximumLength, hasHyphen() ? &charactersWithHyphen : 0); 664 TextRun textRun = constructTextRun(styleToUse, font, string, maximumLength, hasHyphen() ? &charactersWithHyphen : 0);
666 if (hasHyphen()) 665 if (hasHyphen())
667 length = textRun.length(); 666 length = textRun.length();
668 667
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after
748 context->concatCTM(rotation(boxRect, Clockwise)); 747 context->concatCTM(rotation(boxRect, Clockwise));
749 paintDecoration(context, boxOrigin, textDecorations, styleToUse->textDec orationStyle(), textShadow); 748 paintDecoration(context, boxOrigin, textDecorations, styleToUse->textDec orationStyle(), textShadow);
750 if (combinedText) 749 if (combinedText)
751 context->concatCTM(rotation(boxRect, Counterclockwise)); 750 context->concatCTM(rotation(boxRect, Counterclockwise));
752 } 751 }
753 752
754 if (paintInfo.phase == PaintPhaseForeground) { 753 if (paintInfo.phase == PaintPhaseForeground) {
755 paintDocumentMarkers(context, boxOrigin, styleToUse, font, false); 754 paintDocumentMarkers(context, boxOrigin, styleToUse, font, false);
756 755
757 if (useCustomUnderlines) { 756 if (useCustomUnderlines) {
758 const Vector<CompositionUnderline>& underlines = renderer()->frame() ->inputMethodController().customCompositionUnderlines(); 757 const Vector<CompositionUnderline>& underlines = renderer().frame()- >inputMethodController().customCompositionUnderlines();
759 size_t numUnderlines = underlines.size(); 758 size_t numUnderlines = underlines.size();
760 759
761 for (size_t index = 0; index < numUnderlines; ++index) { 760 for (size_t index = 0; index < numUnderlines; ++index) {
762 const CompositionUnderline& underline = underlines[index]; 761 const CompositionUnderline& underline = underlines[index];
763 762
764 if (underline.endOffset <= start()) 763 if (underline.endOffset <= start())
765 // underline is completely before this run. This might be a n underline that sits 764 // underline is completely before this run. This might be a n underline that sits
766 // before the first run we draw, or underlines that were wit hin runs we skipped 765 // before the first run we draw, or underlines that were wit hin runs we skipped
767 // due to truncation. 766 // due to truncation.
768 continue; 767 continue;
(...skipping 11 matching lines...) Expand all
780 } 779 }
781 } 780 }
782 781
783 if (shouldRotate) 782 if (shouldRotate)
784 context->concatCTM(rotation(boxRect, Counterclockwise)); 783 context->concatCTM(rotation(boxRect, Counterclockwise));
785 } 784 }
786 785
787 void InlineTextBox::selectionStartEnd(int& sPos, int& ePos) 786 void InlineTextBox::selectionStartEnd(int& sPos, int& ePos)
788 { 787 {
789 int startPos, endPos; 788 int startPos, endPos;
790 if (renderer()->selectionState() == RenderObject::SelectionInside) { 789 if (renderer().selectionState() == RenderObject::SelectionInside) {
791 startPos = 0; 790 startPos = 0;
792 endPos = textRenderer()->textLength(); 791 endPos = textRenderer().textLength();
793 } else { 792 } else {
794 textRenderer()->selectionStartEnd(startPos, endPos); 793 textRenderer().selectionStartEnd(startPos, endPos);
795 if (renderer()->selectionState() == RenderObject::SelectionStart) 794 if (renderer().selectionState() == RenderObject::SelectionStart)
796 endPos = textRenderer()->textLength(); 795 endPos = textRenderer().textLength();
797 else if (renderer()->selectionState() == RenderObject::SelectionEnd) 796 else if (renderer().selectionState() == RenderObject::SelectionEnd)
798 startPos = 0; 797 startPos = 0;
799 } 798 }
800 799
801 sPos = max(startPos - m_start, 0); 800 sPos = max(startPos - m_start, 0);
802 ePos = min(endPos - m_start, (int)m_len); 801 ePos = min(endPos - m_start, (int)m_len);
803 } 802 }
804 803
805 void alignSelectionRectToDevicePixels(FloatRect& rect) 804 void alignSelectionRectToDevicePixels(FloatRect& rect)
806 { 805 {
807 float maxX = floorf(rect.maxX()); 806 float maxX = floorf(rect.maxX());
808 rect.setX(floorf(rect.x())); 807 rect.setX(floorf(rect.x()));
809 rect.setWidth(roundf(maxX - rect.x())); 808 rect.setWidth(roundf(maxX - rect.x()));
810 } 809 }
811 810
812 void InlineTextBox::paintSelection(GraphicsContext* context, const FloatPoint& b oxOrigin, RenderStyle* style, const Font& font, Color textColor) 811 void InlineTextBox::paintSelection(GraphicsContext* context, const FloatPoint& b oxOrigin, RenderStyle* style, const Font& font, Color textColor)
813 { 812 {
814 if (context->paintingDisabled()) 813 if (context->paintingDisabled())
815 return; 814 return;
816 815
817 // See if we have a selection to paint at all. 816 // See if we have a selection to paint at all.
818 int sPos, ePos; 817 int sPos, ePos;
819 selectionStartEnd(sPos, ePos); 818 selectionStartEnd(sPos, ePos);
820 if (sPos >= ePos) 819 if (sPos >= ePos)
821 return; 820 return;
822 821
823 Color c = renderer()->selectionBackgroundColor(); 822 Color c = renderer().selectionBackgroundColor();
824 if (!c.alpha()) 823 if (!c.alpha())
825 return; 824 return;
826 825
827 // If the text color ends up being the same as the selection background, inv ert the selection 826 // If the text color ends up being the same as the selection background, inv ert the selection
828 // background. 827 // background.
829 if (textColor == c) 828 if (textColor == c)
830 c = Color(0xff - c.red(), 0xff - c.green(), 0xff - c.blue()); 829 c = Color(0xff - c.red(), 0xff - c.green(), 0xff - c.blue());
831 830
832 GraphicsContextStateSaver stateSaver(*context); 831 GraphicsContextStateSaver stateSaver(*context);
833 updateGraphicsContext(context, c, c, 0); // Don't draw text at all! 832 updateGraphicsContext(context, c, c, 0); // Don't draw text at all!
834 833
835 // If the text is truncated, let the thing being painted in the truncation 834 // If the text is truncated, let the thing being painted in the truncation
836 // draw its own highlight. 835 // draw its own highlight.
837 int length = m_truncation != cNoTruncation ? m_truncation : m_len; 836 int length = m_truncation != cNoTruncation ? m_truncation : m_len;
838 StringView string = textRenderer()->text().createView(); 837 StringView string = textRenderer().text().createView();
839 838
840 if (string.length() != static_cast<unsigned>(length) || m_start) 839 if (string.length() != static_cast<unsigned>(length) || m_start)
841 string.narrow(m_start, length); 840 string.narrow(m_start, length);
842 841
843 StringBuilder charactersWithHyphen; 842 StringBuilder charactersWithHyphen;
844 bool respectHyphen = ePos == length && hasHyphen(); 843 bool respectHyphen = ePos == length && hasHyphen();
845 TextRun textRun = constructTextRun(style, font, string, textRenderer()->text Length() - m_start, respectHyphen ? &charactersWithHyphen : 0); 844 TextRun textRun = constructTextRun(style, font, string, textRenderer().textL ength() - m_start, respectHyphen ? &charactersWithHyphen : 0);
846 if (respectHyphen) 845 if (respectHyphen)
847 ePos = textRun.length(); 846 ePos = textRun.length();
848 847
849 LayoutUnit selectionBottom = root()->selectionBottom(); 848 LayoutUnit selectionBottom = root()->selectionBottom();
850 LayoutUnit selectionTop = root()->selectionTopAdjustedForPrecedingBlock(); 849 LayoutUnit selectionTop = root()->selectionTopAdjustedForPrecedingBlock();
851 850
852 int deltaY = roundToInt(renderer()->style()->isFlippedLinesWritingMode() ? s electionBottom - logicalBottom() : logicalTop() - selectionTop); 851 int deltaY = roundToInt(renderer().style()->isFlippedLinesWritingMode() ? se lectionBottom - logicalBottom() : logicalTop() - selectionTop);
853 int selHeight = max(0, roundToInt(selectionBottom - selectionTop)); 852 int selHeight = max(0, roundToInt(selectionBottom - selectionTop));
854 853
855 FloatPoint localOrigin(boxOrigin.x(), boxOrigin.y() - deltaY); 854 FloatPoint localOrigin(boxOrigin.x(), boxOrigin.y() - deltaY);
856 FloatRect clipRect(localOrigin, FloatSize(m_logicalWidth, selHeight)); 855 FloatRect clipRect(localOrigin, FloatSize(m_logicalWidth, selHeight));
857 alignSelectionRectToDevicePixels(clipRect); 856 alignSelectionRectToDevicePixels(clipRect);
858 857
859 context->clip(clipRect); 858 context->clip(clipRect);
860 859
861 context->drawHighlightForText(font, textRun, localOrigin, selHeight, c, sPos , ePos); 860 context->drawHighlightForText(font, textRun, localOrigin, selHeight, c, sPos , ePos);
862 } 861 }
863 862
864 void InlineTextBox::paintCompositionBackground(GraphicsContext* context, const F loatPoint& boxOrigin, RenderStyle* style, const Font& font, int startPos, int en dPos) 863 void InlineTextBox::paintCompositionBackground(GraphicsContext* context, const F loatPoint& boxOrigin, RenderStyle* style, const Font& font, int startPos, int en dPos)
865 { 864 {
866 int offset = m_start; 865 int offset = m_start;
867 int sPos = max(startPos - offset, 0); 866 int sPos = max(startPos - offset, 0);
868 int ePos = min(endPos - offset, (int)m_len); 867 int ePos = min(endPos - offset, (int)m_len);
869 868
870 if (sPos >= ePos) 869 if (sPos >= ePos)
871 return; 870 return;
872 871
873 GraphicsContextStateSaver stateSaver(*context); 872 GraphicsContextStateSaver stateSaver(*context);
874 873
875 Color c = Color(225, 221, 85); 874 Color c = Color(225, 221, 85);
876 875
877 updateGraphicsContext(context, c, c, 0); // Don't draw text at all! 876 updateGraphicsContext(context, c, c, 0); // Don't draw text at all!
878 877
879 int deltaY = renderer()->style()->isFlippedLinesWritingMode() ? selectionBot tom() - logicalBottom() : logicalTop() - selectionTop(); 878 int deltaY = renderer().style()->isFlippedLinesWritingMode() ? selectionBott om() - logicalBottom() : logicalTop() - selectionTop();
880 int selHeight = selectionHeight(); 879 int selHeight = selectionHeight();
881 FloatPoint localOrigin(boxOrigin.x(), boxOrigin.y() - deltaY); 880 FloatPoint localOrigin(boxOrigin.x(), boxOrigin.y() - deltaY);
882 context->drawHighlightForText(font, constructTextRun(style, font), localOrig in, selHeight, c, sPos, ePos); 881 context->drawHighlightForText(font, constructTextRun(style, font), localOrig in, selHeight, c, sPos, ePos);
883 } 882 }
884 883
885 static StrokeStyle textDecorationStyleToStrokeStyle(TextDecorationStyle decorati onStyle) 884 static StrokeStyle textDecorationStyleToStrokeStyle(TextDecorationStyle decorati onStyle)
886 { 885 {
887 StrokeStyle strokeStyle = SolidStroke; 886 StrokeStyle strokeStyle = SolidStroke;
888 switch (decorationStyle) { 887 switch (decorationStyle) {
889 case TextDecorationStyleSolid: 888 case TextDecorationStyleSolid:
(...skipping 165 matching lines...) Expand 10 before | Expand all | Expand 10 after
1055 { 1054 {
1056 GraphicsContextStateSaver stateSaver(*context); 1055 GraphicsContextStateSaver stateSaver(*context);
1057 1056
1058 if (m_truncation == cFullTruncation) 1057 if (m_truncation == cFullTruncation)
1059 return; 1058 return;
1060 1059
1061 FloatPoint localOrigin = boxOrigin; 1060 FloatPoint localOrigin = boxOrigin;
1062 1061
1063 float width = m_logicalWidth; 1062 float width = m_logicalWidth;
1064 if (m_truncation != cNoTruncation) { 1063 if (m_truncation != cNoTruncation) {
1065 width = toRenderText(renderer())->width(m_start, m_truncation, textPos() , isLeftToRightDirection() ? LTR : RTL, isFirstLineStyle()); 1064 width = toRenderText(renderer()).width(m_start, m_truncation, textPos(), isLeftToRightDirection() ? LTR : RTL, isFirstLineStyle());
1066 if (!isLeftToRightDirection()) 1065 if (!isLeftToRightDirection())
1067 localOrigin.move(m_logicalWidth - width, 0); 1066 localOrigin.move(m_logicalWidth - width, 0);
1068 } 1067 }
1069 1068
1070 // Get the text decoration colors. 1069 // Get the text decoration colors.
1071 Color underline(Color::transparent), overline(Color::transparent), linethrou gh(Color::transparent); 1070 Color underline(Color::transparent), overline(Color::transparent), linethrou gh(Color::transparent);
1072 renderer()->getTextDecorationColors(deco, underline, overline, linethrough, true); 1071 renderer().getTextDecorationColors(deco, underline, overline, linethrough, t rue);
1073 if (isFirstLineStyle()) 1072 if (isFirstLineStyle())
1074 renderer()->getTextDecorationColors(deco, underline, overline, linethrou gh, true, true); 1073 renderer().getTextDecorationColors(deco, underline, overline, linethroug h, true, true);
1075 1074
1076 // Use a special function for underlines to get the positioning exactly righ t. 1075 // Use a special function for underlines to get the positioning exactly righ t.
1077 bool isPrinting = textRenderer()->document().printing(); 1076 bool isPrinting = textRenderer().document().printing();
1078 1077
1079 bool linesAreOpaque = !isPrinting && (!(deco & TextDecorationUnderline) || u nderline.alpha() == 255) && (!(deco & TextDecorationOverline) || overline.alpha( ) == 255) && (!(deco & TextDecorationLineThrough) || linethrough.alpha() == 255) ; 1078 bool linesAreOpaque = !isPrinting && (!(deco & TextDecorationUnderline) || u nderline.alpha() == 255) && (!(deco & TextDecorationOverline) || overline.alpha( ) == 255) && (!(deco & TextDecorationLineThrough) || linethrough.alpha() == 255) ;
1080 1079
1081 RenderStyle* styleToUse = renderer()->style(isFirstLineStyle()); 1080 RenderStyle* styleToUse = renderer().style(isFirstLineStyle());
1082 int baseline = styleToUse->fontMetrics().ascent(); 1081 int baseline = styleToUse->fontMetrics().ascent();
1083 1082
1084 size_t shadowCount = shadowList ? shadowList->shadows().size() : 0; 1083 size_t shadowCount = shadowList ? shadowList->shadows().size() : 0;
1085 // Set the thick of the line to be 10% (or something else ?)of the computed font size and not less than 1px. 1084 // Set the thick of the line to be 10% (or something else ?)of the computed font size and not less than 1px.
1086 // Using computedFontSize should take care of zoom as well. 1085 // Using computedFontSize should take care of zoom as well.
1087 1086
1088 // Update Underline thickness, in case we have Faulty Font Metrics calculati ng underline thickness by old method. 1087 // Update Underline thickness, in case we have Faulty Font Metrics calculati ng underline thickness by old method.
1089 float textDecorationThickness = styleToUse->fontMetrics().underlineThickness (); 1088 float textDecorationThickness = styleToUse->fontMetrics().underlineThickness ();
1090 int fontHeightInt = (int)(styleToUse->fontMetrics().floatHeight() + 0.5); 1089 int fontHeightInt = (int)(styleToUse->fontMetrics().floatHeight() + 0.5);
1091 if ((textDecorationThickness == 0.f) || (textDecorationThickness >= (fontHei ghtInt >> 1))) 1090 if ((textDecorationThickness == 0.f) || (textDecorationThickness >= (fontHei ghtInt >> 1)))
(...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after
1187 return GraphicsContext::DocumentMarkerGrammarLineStyle; 1186 return GraphicsContext::DocumentMarkerGrammarLineStyle;
1188 default: 1187 default:
1189 ASSERT_NOT_REACHED(); 1188 ASSERT_NOT_REACHED();
1190 return GraphicsContext::DocumentMarkerSpellingLineStyle; 1189 return GraphicsContext::DocumentMarkerSpellingLineStyle;
1191 } 1190 }
1192 } 1191 }
1193 1192
1194 void InlineTextBox::paintDocumentMarker(GraphicsContext* pt, const FloatPoint& b oxOrigin, DocumentMarker* marker, RenderStyle* style, const Font& font, bool gra mmar) 1193 void InlineTextBox::paintDocumentMarker(GraphicsContext* pt, const FloatPoint& b oxOrigin, DocumentMarker* marker, RenderStyle* style, const Font& font, bool gra mmar)
1195 { 1194 {
1196 // Never print spelling/grammar markers (5327887) 1195 // Never print spelling/grammar markers (5327887)
1197 if (textRenderer()->document().printing()) 1196 if (textRenderer().document().printing())
1198 return; 1197 return;
1199 1198
1200 if (m_truncation == cFullTruncation) 1199 if (m_truncation == cFullTruncation)
1201 return; 1200 return;
1202 1201
1203 float start = 0; // start of line to draw, relative to tx 1202 float start = 0; // start of line to draw, relative to tx
1204 float width = m_logicalWidth; // how much line to draw 1203 float width = m_logicalWidth; // how much line to draw
1205 1204
1206 // Determine whether we need to measure text 1205 // Determine whether we need to measure text
1207 bool markerSpansWholeBox = true; 1206 bool markerSpansWholeBox = true;
1208 if (m_start <= (int)marker->startOffset()) 1207 if (m_start <= (int)marker->startOffset())
1209 markerSpansWholeBox = false; 1208 markerSpansWholeBox = false;
1210 if ((end() + 1) != marker->endOffset()) // end points at the last char, not past it 1209 if ((end() + 1) != marker->endOffset()) // end points at the last char, not past it
1211 markerSpansWholeBox = false; 1210 markerSpansWholeBox = false;
1212 if (m_truncation != cNoTruncation) 1211 if (m_truncation != cNoTruncation)
1213 markerSpansWholeBox = false; 1212 markerSpansWholeBox = false;
1214 1213
1215 if (!markerSpansWholeBox || grammar) { 1214 if (!markerSpansWholeBox || grammar) {
1216 int startPosition = max<int>(marker->startOffset() - m_start, 0); 1215 int startPosition = max<int>(marker->startOffset() - m_start, 0);
1217 int endPosition = min<int>(marker->endOffset() - m_start, m_len); 1216 int endPosition = min<int>(marker->endOffset() - m_start, m_len);
1218 1217
1219 if (m_truncation != cNoTruncation) 1218 if (m_truncation != cNoTruncation)
1220 endPosition = min<int>(endPosition, m_truncation); 1219 endPosition = min<int>(endPosition, m_truncation);
1221 1220
1222 // Calculate start & width 1221 // Calculate start & width
1223 int deltaY = renderer()->style()->isFlippedLinesWritingMode() ? selectio nBottom() - logicalBottom() : logicalTop() - selectionTop(); 1222 int deltaY = renderer().style()->isFlippedLinesWritingMode() ? selection Bottom() - logicalBottom() : logicalTop() - selectionTop();
1224 int selHeight = selectionHeight(); 1223 int selHeight = selectionHeight();
1225 FloatPoint startPoint(boxOrigin.x(), boxOrigin.y() - deltaY); 1224 FloatPoint startPoint(boxOrigin.x(), boxOrigin.y() - deltaY);
1226 TextRun run = constructTextRun(style, font); 1225 TextRun run = constructTextRun(style, font);
1227 1226
1228 // FIXME: Convert the document markers to float rects. 1227 // FIXME: Convert the document markers to float rects.
1229 IntRect markerRect = enclosingIntRect(font.selectionRectForText(run, sta rtPoint, selHeight, startPosition, endPosition)); 1228 IntRect markerRect = enclosingIntRect(font.selectionRectForText(run, sta rtPoint, selHeight, startPosition, endPosition));
1230 start = markerRect.x() - startPoint.x(); 1229 start = markerRect.x() - startPoint.x();
1231 width = markerRect.width(); 1230 width = markerRect.width();
1232 1231
1233 // Store rendered rects for bad grammar markers, so we can hit-test agai nst it elsewhere in order to 1232 // Store rendered rects for bad grammar markers, so we can hit-test agai nst it elsewhere in order to
1234 // display a toolTip. We don't do this for misspelling markers. 1233 // display a toolTip. We don't do this for misspelling markers.
1235 if (grammar) { 1234 if (grammar) {
1236 markerRect.move(-boxOrigin.x(), -boxOrigin.y()); 1235 markerRect.move(-boxOrigin.x(), -boxOrigin.y());
1237 markerRect = renderer()->localToAbsoluteQuad(FloatRect(markerRect)). enclosingBoundingBox(); 1236 markerRect = renderer().localToAbsoluteQuad(FloatRect(markerRect)).e nclosingBoundingBox();
1238 toRenderedDocumentMarker(marker)->setRenderedRect(markerRect); 1237 toRenderedDocumentMarker(marker)->setRenderedRect(markerRect);
1239 } 1238 }
1240 } 1239 }
1241 1240
1242 // IMPORTANT: The misspelling underline is not considered when calculating t he text bounds, so we have to 1241 // IMPORTANT: The misspelling underline is not considered when calculating t he text bounds, so we have to
1243 // make sure to fit within those bounds. This means the top pixel(s) of the underline will overlap the 1242 // make sure to fit within those bounds. This means the top pixel(s) of the underline will overlap the
1244 // bottom pixel(s) of the glyphs in smaller font sizes. The alternatives ar e to increase the line spacing (bad!!) 1243 // bottom pixel(s) of the glyphs in smaller font sizes. The alternatives ar e to increase the line spacing (bad!!)
1245 // or decrease the underline thickness. The overlap is actually the most us eful, and matches what AppKit does. 1244 // or decrease the underline thickness. The overlap is actually the most us eful, and matches what AppKit does.
1246 // So, we generally place the underline at the bottom of the text, but in la rger fonts that's not so good so 1245 // So, we generally place the underline at the bottom of the text, but in la rger fonts that's not so good so
1247 // we pin to two pixels under the baseline. 1246 // we pin to two pixels under the baseline.
1248 int lineThickness = misspellingLineThickness; 1247 int lineThickness = misspellingLineThickness;
1249 int baseline = renderer()->style(isFirstLineStyle())->fontMetrics().ascent() ; 1248 int baseline = renderer().style(isFirstLineStyle())->fontMetrics().ascent();
1250 int descent = logicalHeight() - baseline; 1249 int descent = logicalHeight() - baseline;
1251 int underlineOffset; 1250 int underlineOffset;
1252 if (descent <= (2 + lineThickness)) { 1251 if (descent <= (2 + lineThickness)) {
1253 // Place the underline at the very bottom of the text in small/medium fo nts. 1252 // Place the underline at the very bottom of the text in small/medium fo nts.
1254 underlineOffset = logicalHeight() - lineThickness; 1253 underlineOffset = logicalHeight() - lineThickness;
1255 } else { 1254 } else {
1256 // In larger fonts, though, place the underline up near the baseline to prevent a big gap. 1255 // In larger fonts, though, place the underline up near the baseline to prevent a big gap.
1257 underlineOffset = baseline + 2; 1256 underlineOffset = baseline + 2;
1258 } 1257 }
1259 pt->drawLineForDocumentMarker(FloatPoint(boxOrigin.x() + start, boxOrigin.y( ) + underlineOffset), width, lineStyleForMarkerType(marker->type())); 1258 pt->drawLineForDocumentMarker(FloatPoint(boxOrigin.x() + start, boxOrigin.y( ) + underlineOffset), width, lineStyleForMarkerType(marker->type()));
1260 } 1259 }
1261 1260
1262 void InlineTextBox::paintTextMatchMarker(GraphicsContext* pt, const FloatPoint& boxOrigin, DocumentMarker* marker, RenderStyle* style, const Font& font) 1261 void InlineTextBox::paintTextMatchMarker(GraphicsContext* pt, const FloatPoint& boxOrigin, DocumentMarker* marker, RenderStyle* style, const Font& font)
1263 { 1262 {
1264 // Use same y positioning and height as for selection, so that when the sele ction and this highlight are on 1263 // Use same y positioning and height as for selection, so that when the sele ction and this highlight are on
1265 // the same word there are no pieces sticking out. 1264 // the same word there are no pieces sticking out.
1266 int deltaY = renderer()->style()->isFlippedLinesWritingMode() ? selectionBot tom() - logicalBottom() : logicalTop() - selectionTop(); 1265 int deltaY = renderer().style()->isFlippedLinesWritingMode() ? selectionBott om() - logicalBottom() : logicalTop() - selectionTop();
1267 int selHeight = selectionHeight(); 1266 int selHeight = selectionHeight();
1268 1267
1269 int sPos = max(marker->startOffset() - m_start, (unsigned)0); 1268 int sPos = max(marker->startOffset() - m_start, (unsigned)0);
1270 int ePos = min(marker->endOffset() - m_start, (unsigned)m_len); 1269 int ePos = min(marker->endOffset() - m_start, (unsigned)m_len);
1271 TextRun run = constructTextRun(style, font); 1270 TextRun run = constructTextRun(style, font);
1272 1271
1273 // Always compute and store the rect associated with this marker. The comput ed rect is in absolute coordinates. 1272 // Always compute and store the rect associated with this marker. The comput ed rect is in absolute coordinates.
1274 IntRect markerRect = enclosingIntRect(font.selectionRectForText(run, IntPoin t(x(), selectionTop()), selHeight, sPos, ePos)); 1273 IntRect markerRect = enclosingIntRect(font.selectionRectForText(run, IntPoin t(x(), selectionTop()), selHeight, sPos, ePos));
1275 markerRect = renderer()->localToAbsoluteQuad(FloatRect(markerRect)).enclosin gBoundingBox(); 1274 markerRect = renderer().localToAbsoluteQuad(FloatRect(markerRect)).enclosing BoundingBox();
1276 toRenderedDocumentMarker(marker)->setRenderedRect(markerRect); 1275 toRenderedDocumentMarker(marker)->setRenderedRect(markerRect);
1277 1276
1278 // Optionally highlight the text 1277 // Optionally highlight the text
1279 if (renderer()->frame()->editor().markedTextMatchesAreHighlighted()) { 1278 if (renderer().frame()->editor().markedTextMatchesAreHighlighted()) {
1280 Color color = marker->activeMatch() ? 1279 Color color = marker->activeMatch() ?
1281 RenderTheme::theme().platformActiveTextSearchHighlightColor() : 1280 RenderTheme::theme().platformActiveTextSearchHighlightColor() :
1282 RenderTheme::theme().platformInactiveTextSearchHighlightColor(); 1281 RenderTheme::theme().platformInactiveTextSearchHighlightColor();
1283 GraphicsContextStateSaver stateSaver(*pt); 1282 GraphicsContextStateSaver stateSaver(*pt);
1284 updateGraphicsContext(pt, color, color, 0); // Don't draw text at all! 1283 updateGraphicsContext(pt, color, color, 0); // Don't draw text at all!
1285 pt->clip(FloatRect(boxOrigin.x(), boxOrigin.y() - deltaY, m_logicalWidth , selHeight)); 1284 pt->clip(FloatRect(boxOrigin.x(), boxOrigin.y() - deltaY, m_logicalWidth , selHeight));
1286 pt->drawHighlightForText(font, run, FloatPoint(boxOrigin.x(), boxOrigin. y() - deltaY), selHeight, color, sPos, ePos); 1285 pt->drawHighlightForText(font, run, FloatPoint(boxOrigin.x(), boxOrigin. y() - deltaY), selHeight, color, sPos, ePos);
1287 } 1286 }
1288 } 1287 }
1289 1288
1290 void InlineTextBox::paintDocumentMarkers(GraphicsContext* pt, const FloatPoint& boxOrigin, RenderStyle* style, const Font& font, bool background) 1289 void InlineTextBox::paintDocumentMarkers(GraphicsContext* pt, const FloatPoint& boxOrigin, RenderStyle* style, const Font& font, bool background)
1291 { 1290 {
1292 if (!renderer()->node()) 1291 if (!renderer().node())
1293 return; 1292 return;
1294 1293
1295 Vector<DocumentMarker*> markers = renderer()->document().markers().markersFo r(renderer()->node()); 1294 Vector<DocumentMarker*> markers = renderer().document().markers().markersFor (renderer().node());
1296 Vector<DocumentMarker*>::const_iterator markerIt = markers.begin(); 1295 Vector<DocumentMarker*>::const_iterator markerIt = markers.begin();
1297 1296
1298 // Give any document markers that touch this run a chance to draw before the text has been drawn. 1297 // Give any document markers that touch this run a chance to draw before the text has been drawn.
1299 // Note end() points at the last char, not one past it like endOffset and ra nges do. 1298 // Note end() points at the last char, not one past it like endOffset and ra nges do.
1300 for ( ; markerIt != markers.end(); ++markerIt) { 1299 for ( ; markerIt != markers.end(); ++markerIt) {
1301 DocumentMarker* marker = *markerIt; 1300 DocumentMarker* marker = *markerIt;
1302 1301
1303 // Paint either the background markers or the foreground markers, but no t both 1302 // Paint either the background markers or the foreground markers, but no t both
1304 switch (marker->type()) { 1303 switch (marker->type()) {
1305 case DocumentMarker::Grammar: 1304 case DocumentMarker::Grammar:
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
1348 return; 1347 return;
1349 1348
1350 float start = 0; // start of line to draw, relative to tx 1349 float start = 0; // start of line to draw, relative to tx
1351 float width = m_logicalWidth; // how much line to draw 1350 float width = m_logicalWidth; // how much line to draw
1352 bool useWholeWidth = true; 1351 bool useWholeWidth = true;
1353 unsigned paintStart = m_start; 1352 unsigned paintStart = m_start;
1354 unsigned paintEnd = end() + 1; // end points at the last char, not past it 1353 unsigned paintEnd = end() + 1; // end points at the last char, not past it
1355 if (paintStart <= underline.startOffset) { 1354 if (paintStart <= underline.startOffset) {
1356 paintStart = underline.startOffset; 1355 paintStart = underline.startOffset;
1357 useWholeWidth = false; 1356 useWholeWidth = false;
1358 start = toRenderText(renderer())->width(m_start, paintStart - m_start, t extPos(), isLeftToRightDirection() ? LTR : RTL, isFirstLineStyle()); 1357 start = toRenderText(renderer()).width(m_start, paintStart - m_start, te xtPos(), isLeftToRightDirection() ? LTR : RTL, isFirstLineStyle());
1359 } 1358 }
1360 if (paintEnd != underline.endOffset) { // end points at the last char, not past it 1359 if (paintEnd != underline.endOffset) { // end points at the last char, not past it
1361 paintEnd = min(paintEnd, (unsigned)underline.endOffset); 1360 paintEnd = min(paintEnd, (unsigned)underline.endOffset);
1362 useWholeWidth = false; 1361 useWholeWidth = false;
1363 } 1362 }
1364 if (m_truncation != cNoTruncation) { 1363 if (m_truncation != cNoTruncation) {
1365 paintEnd = min(paintEnd, (unsigned)m_start + m_truncation); 1364 paintEnd = min(paintEnd, (unsigned)m_start + m_truncation);
1366 useWholeWidth = false; 1365 useWholeWidth = false;
1367 } 1366 }
1368 if (!useWholeWidth) { 1367 if (!useWholeWidth) {
1369 width = toRenderText(renderer())->width(paintStart, paintEnd - paintStar t, textPos() + start, isLeftToRightDirection() ? LTR : RTL, isFirstLineStyle()); 1368 width = toRenderText(renderer()).width(paintStart, paintEnd - paintStart , textPos() + start, isLeftToRightDirection() ? LTR : RTL, isFirstLineStyle());
1370 } 1369 }
1371 1370
1372 // Thick marked text underlines are 2px thick as long as there is room for t he 2px line under the baseline. 1371 // Thick marked text underlines are 2px thick as long as there is room for t he 2px line under the baseline.
1373 // All other marked text underlines are 1px thick. 1372 // All other marked text underlines are 1px thick.
1374 // If there's not enough space the underline will touch or overlap character s. 1373 // If there's not enough space the underline will touch or overlap character s.
1375 int lineThickness = 1; 1374 int lineThickness = 1;
1376 int baseline = renderer()->style(isFirstLineStyle())->fontMetrics().ascent() ; 1375 int baseline = renderer().style(isFirstLineStyle())->fontMetrics().ascent();
1377 if (underline.thick && logicalHeight() - baseline >= 2) 1376 if (underline.thick && logicalHeight() - baseline >= 2)
1378 lineThickness = 2; 1377 lineThickness = 2;
1379 1378
1380 // We need to have some space between underlines of subsequent clauses, beca use some input methods do not use different underline styles for those. 1379 // We need to have some space between underlines of subsequent clauses, beca use some input methods do not use different underline styles for those.
1381 // We make each line shorter, which has a harmless side effect of shortening the first and last clauses, too. 1380 // We make each line shorter, which has a harmless side effect of shortening the first and last clauses, too.
1382 start += 1; 1381 start += 1;
1383 width -= 2; 1382 width -= 2;
1384 1383
1385 ctx->setStrokeColor(underline.color); 1384 ctx->setStrokeColor(underline.color);
1386 ctx->setStrokeThickness(lineThickness); 1385 ctx->setStrokeThickness(lineThickness);
1387 ctx->drawLineForText(FloatPoint(boxOrigin.x() + start, boxOrigin.y() + logic alHeight() - lineThickness), width, textRenderer()->document().printing()); 1386 ctx->drawLineForText(FloatPoint(boxOrigin.x() + start, boxOrigin.y() + logic alHeight() - lineThickness), width, textRenderer().document().printing());
1388 } 1387 }
1389 1388
1390 int InlineTextBox::caretMinOffset() const 1389 int InlineTextBox::caretMinOffset() const
1391 { 1390 {
1392 return m_start; 1391 return m_start;
1393 } 1392 }
1394 1393
1395 int InlineTextBox::caretMaxOffset() const 1394 int InlineTextBox::caretMaxOffset() const
1396 { 1395 {
1397 return m_start + m_len; 1396 return m_start + m_len;
(...skipping 13 matching lines...) Expand all
1411 if (isLineBreak()) 1410 if (isLineBreak())
1412 return 0; 1411 return 0;
1413 1412
1414 if (lineOffset - logicalLeft() > logicalWidth()) 1413 if (lineOffset - logicalLeft() > logicalWidth())
1415 return isLeftToRightDirection() ? len() : 0; 1414 return isLeftToRightDirection() ? len() : 0;
1416 if (lineOffset - logicalLeft() < 0) 1415 if (lineOffset - logicalLeft() < 0)
1417 return isLeftToRightDirection() ? 0 : len(); 1416 return isLeftToRightDirection() ? 0 : len();
1418 1417
1419 FontCachePurgePreventer fontCachePurgePreventer; 1418 FontCachePurgePreventer fontCachePurgePreventer;
1420 1419
1421 RenderText* text = toRenderText(renderer()); 1420 RenderText& text = toRenderText(renderer());
1422 RenderStyle* style = text->style(isFirstLineStyle()); 1421 RenderStyle* style = text.style(isFirstLineStyle());
1423 const Font& font = style->font(); 1422 const Font& font = style->font();
1424 return font.offsetForPosition(constructTextRun(style, font), lineOffset - lo gicalLeft(), includePartialGlyphs); 1423 return font.offsetForPosition(constructTextRun(style, font), lineOffset - lo gicalLeft(), includePartialGlyphs);
1425 } 1424 }
1426 1425
1427 float InlineTextBox::positionForOffset(int offset) const 1426 float InlineTextBox::positionForOffset(int offset) const
1428 { 1427 {
1429 ASSERT(offset >= m_start); 1428 ASSERT(offset >= m_start);
1430 ASSERT(offset <= m_start + m_len); 1429 ASSERT(offset <= m_start + m_len);
1431 1430
1432 if (isLineBreak()) 1431 if (isLineBreak())
1433 return logicalLeft(); 1432 return logicalLeft();
1434 1433
1435 FontCachePurgePreventer fontCachePurgePreventer; 1434 FontCachePurgePreventer fontCachePurgePreventer;
1436 1435
1437 RenderText* text = toRenderText(renderer()); 1436 RenderText& text = toRenderText(renderer());
1438 RenderStyle* styleToUse = text->style(isFirstLineStyle()); 1437 RenderStyle* styleToUse = text.style(isFirstLineStyle());
1439 ASSERT(styleToUse); 1438 ASSERT(styleToUse);
1440 const Font& font = styleToUse->font(); 1439 const Font& font = styleToUse->font();
1441 int from = !isLeftToRightDirection() ? offset - m_start : 0; 1440 int from = !isLeftToRightDirection() ? offset - m_start : 0;
1442 int to = !isLeftToRightDirection() ? m_len : offset - m_start; 1441 int to = !isLeftToRightDirection() ? m_len : offset - m_start;
1443 // FIXME: Do we need to add rightBearing here? 1442 // FIXME: Do we need to add rightBearing here?
1444 return font.selectionRectForText(constructTextRun(styleToUse, font), IntPoin t(logicalLeft(), 0), 0, from, to).maxX(); 1443 return font.selectionRectForText(constructTextRun(styleToUse, font), IntPoin t(logicalLeft(), 0), 0, from, to).maxX();
1445 } 1444 }
1446 1445
1447 bool InlineTextBox::containsCaretOffset(int offset) const 1446 bool InlineTextBox::containsCaretOffset(int offset) const
1448 { 1447 {
(...skipping 16 matching lines...) Expand all
1465 return false; 1464 return false;
1466 1465
1467 // Offsets at the end are "in" for normal boxes (but the caller has to check affinity). 1466 // Offsets at the end are "in" for normal boxes (but the caller has to check affinity).
1468 return true; 1467 return true;
1469 } 1468 }
1470 1469
1471 void InlineTextBox::characterWidths(Vector<float>& widths) const 1470 void InlineTextBox::characterWidths(Vector<float>& widths) const
1472 { 1471 {
1473 FontCachePurgePreventer fontCachePurgePreventer; 1472 FontCachePurgePreventer fontCachePurgePreventer;
1474 1473
1475 RenderText* textObj = textRenderer(); 1474 RenderStyle* styleToUse = textRenderer().style(isFirstLineStyle());
1476 RenderStyle* styleToUse = textObj->style(isFirstLineStyle());
1477 const Font& font = styleToUse->font(); 1475 const Font& font = styleToUse->font();
1478 1476
1479 TextRun textRun = constructTextRun(styleToUse, font); 1477 TextRun textRun = constructTextRun(styleToUse, font);
1480 1478
1481 GlyphBuffer glyphBuffer; 1479 GlyphBuffer glyphBuffer;
1482 WidthIterator it(&font, textRun); 1480 WidthIterator it(&font, textRun);
1483 float lastWidth = 0; 1481 float lastWidth = 0;
1484 widths.resize(m_len); 1482 widths.resize(m_len);
1485 for (unsigned i = 0; i < m_len; i++) { 1483 for (unsigned i = 0; i < m_len; i++) {
1486 it.advance(i + 1, &glyphBuffer); 1484 it.advance(i + 1, &glyphBuffer);
1487 widths[i] = it.m_runWidthSoFar - lastWidth; 1485 widths[i] = it.m_runWidthSoFar - lastWidth;
1488 lastWidth = it.m_runWidthSoFar; 1486 lastWidth = it.m_runWidthSoFar;
1489 } 1487 }
1490 } 1488 }
1491 1489
1492 TextRun InlineTextBox::constructTextRun(RenderStyle* style, const Font& font, St ringBuilder* charactersWithHyphen) const 1490 TextRun InlineTextBox::constructTextRun(RenderStyle* style, const Font& font, St ringBuilder* charactersWithHyphen) const
1493 { 1491 {
1494 ASSERT(style); 1492 ASSERT(style);
1493 ASSERT(textRenderer().text());
1495 1494
1496 RenderText* textRenderer = this->textRenderer(); 1495 StringView string = textRenderer().text().createView();
1497 ASSERT(textRenderer);
1498 ASSERT(textRenderer->text());
1499
1500 StringView string = textRenderer->text().createView();
1501 unsigned startPos = start(); 1496 unsigned startPos = start();
1502 unsigned length = len(); 1497 unsigned length = len();
1503 1498
1504 if (string.length() != length || startPos) 1499 if (string.length() != length || startPos)
1505 string.narrow(startPos, length); 1500 string.narrow(startPos, length);
1506 1501
1507 return constructTextRun(style, font, string, textRenderer->textLength() - st artPos, charactersWithHyphen); 1502 return constructTextRun(style, font, string, textRenderer().textLength() - s tartPos, charactersWithHyphen);
1508 } 1503 }
1509 1504
1510 TextRun InlineTextBox::constructTextRun(RenderStyle* style, const Font& font, St ringView string, int maximumLength, StringBuilder* charactersWithHyphen) const 1505 TextRun InlineTextBox::constructTextRun(RenderStyle* style, const Font& font, St ringView string, int maximumLength, StringBuilder* charactersWithHyphen) const
1511 { 1506 {
1512 ASSERT(style); 1507 ASSERT(style);
1513 1508
1514 RenderText* textRenderer = this->textRenderer();
1515 ASSERT(textRenderer);
1516
1517 if (charactersWithHyphen) { 1509 if (charactersWithHyphen) {
1518 const AtomicString& hyphenString = style->hyphenString(); 1510 const AtomicString& hyphenString = style->hyphenString();
1519 charactersWithHyphen->reserveCapacity(string.length() + hyphenString.len gth()); 1511 charactersWithHyphen->reserveCapacity(string.length() + hyphenString.len gth());
1520 charactersWithHyphen->append(string); 1512 charactersWithHyphen->append(string);
1521 charactersWithHyphen->append(hyphenString); 1513 charactersWithHyphen->append(hyphenString);
1522 string = charactersWithHyphen->toString().createView(); 1514 string = charactersWithHyphen->toString().createView();
1523 maximumLength = string.length(); 1515 maximumLength = string.length();
1524 } 1516 }
1525 1517
1526 ASSERT(maximumLength >= static_cast<int>(string.length())); 1518 ASSERT(maximumLength >= static_cast<int>(string.length()));
1527 1519
1528 TextRun run(string, textPos(), expansion(), expansionBehavior(), direction() , dirOverride() || style->rtlOrdering() == VisualOrder, !textRenderer->canUseSim pleFontCodePath()); 1520 TextRun run(string, textPos(), expansion(), expansionBehavior(), direction() , dirOverride() || style->rtlOrdering() == VisualOrder, !textRenderer().canUseSi mpleFontCodePath());
1529 run.setTabSize(!style->collapseWhiteSpace(), style->tabSize()); 1521 run.setTabSize(!style->collapseWhiteSpace(), style->tabSize());
1530 run.setCharacterScanForCodePath(!textRenderer->canUseSimpleFontCodePath()); 1522 run.setCharacterScanForCodePath(!textRenderer().canUseSimpleFontCodePath());
1531 if (textRunNeedsRenderingContext(font)) 1523 if (textRunNeedsRenderingContext(font))
1532 run.setRenderingContext(SVGTextRunRenderingContext::create(textRenderer) ); 1524 run.setRenderingContext(SVGTextRunRenderingContext::create(&textRenderer ()));
1533 1525
1534 // Propagate the maximum length of the characters buffer to the TextRun, eve n when we're only processing a substring. 1526 // Propagate the maximum length of the characters buffer to the TextRun, eve n when we're only processing a substring.
1535 run.setCharactersLength(maximumLength); 1527 run.setCharactersLength(maximumLength);
1536 ASSERT(run.charactersLength() >= run.length()); 1528 ASSERT(run.charactersLength() >= run.length());
1537 return run; 1529 return run;
1538 } 1530 }
1539 1531
1540 TextRun InlineTextBox::constructTextRunForInspector(RenderStyle* style, const Fo nt& font) const 1532 TextRun InlineTextBox::constructTextRunForInspector(RenderStyle* style, const Fo nt& font) const
1541 { 1533 {
1542 return InlineTextBox::constructTextRun(style, font); 1534 return InlineTextBox::constructTextRun(style, font);
1543 } 1535 }
1544 1536
1545 #ifndef NDEBUG 1537 #ifndef NDEBUG
1546 1538
1547 const char* InlineTextBox::boxName() const 1539 const char* InlineTextBox::boxName() const
1548 { 1540 {
1549 return "InlineTextBox"; 1541 return "InlineTextBox";
1550 } 1542 }
1551 1543
1552 void InlineTextBox::showBox(int printedCharacters) const 1544 void InlineTextBox::showBox(int printedCharacters) const
1553 { 1545 {
1554 const RenderText* obj = toRenderText(renderer()); 1546 const RenderText& obj = toRenderText(renderer());
1555 String value = obj->text(); 1547 String value = obj.text();
1556 value = value.substring(start(), len()); 1548 value = value.substring(start(), len());
1557 value.replaceWithLiteral('\\', "\\\\"); 1549 value.replaceWithLiteral('\\', "\\\\");
1558 value.replaceWithLiteral('\n', "\\n"); 1550 value.replaceWithLiteral('\n', "\\n");
1559 printedCharacters += fprintf(stderr, "%s\t%p", boxName(), this); 1551 printedCharacters += fprintf(stderr, "%s\t%p", boxName(), this);
1560 for (; printedCharacters < showTreeCharacterOffset; printedCharacters++) 1552 for (; printedCharacters < showTreeCharacterOffset; printedCharacters++)
1561 fputc(' ', stderr); 1553 fputc(' ', stderr);
1562 printedCharacters = fprintf(stderr, "\t%s %p", obj->renderName(), obj); 1554 printedCharacters = fprintf(stderr, "\t%s %p", obj.renderName(), &obj);
1563 const int rendererCharacterOffset = 24; 1555 const int rendererCharacterOffset = 24;
1564 for (; printedCharacters < rendererCharacterOffset; printedCharacters++) 1556 for (; printedCharacters < rendererCharacterOffset; printedCharacters++)
1565 fputc(' ', stderr); 1557 fputc(' ', stderr);
1566 fprintf(stderr, "(%d,%d) \"%s\"\n", start(), start() + len(), value.utf8().d ata()); 1558 fprintf(stderr, "(%d,%d) \"%s\"\n", start(), start() + len(), value.utf8().d ata());
1567 } 1559 }
1568 1560
1569 #endif 1561 #endif
1570 1562
1571 } // namespace WebCore 1563 } // namespace WebCore
OLDNEW
« no previous file with comments | « Source/core/rendering/InlineTextBox.h ('k') | Source/core/rendering/RenderBlock.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698