OLD | NEW |
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 187 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
198 int sPos = std::max(startPos - m_start, 0); | 198 int sPos = std::max(startPos - m_start, 0); |
199 int ePos = std::min(endPos - m_start, (int)m_len); | 199 int ePos = std::min(endPos - m_start, (int)m_len); |
200 | 200 |
201 if (sPos > ePos) | 201 if (sPos > ePos) |
202 return LayoutRect(); | 202 return LayoutRect(); |
203 | 203 |
204 FontCachePurgePreventer fontCachePurgePreventer; | 204 FontCachePurgePreventer fontCachePurgePreventer; |
205 | 205 |
206 LayoutUnit selTop = selectionTop(); | 206 LayoutUnit selTop = selectionTop(); |
207 LayoutUnit selHeight = selectionHeight(); | 207 LayoutUnit selHeight = selectionHeight(); |
208 RenderStyle* styleToUse = textRenderer().style(isFirstLineStyle()); | 208 RenderStyle* styleToUse = renderer().style(isFirstLineStyle()); |
209 const Font& font = styleToUse->font(); | 209 const Font& font = styleToUse->font(); |
210 | 210 |
211 StringBuilder charactersWithHyphen; | 211 StringBuilder charactersWithHyphen; |
212 bool respectHyphen = ePos == m_len && hasHyphen(); | 212 bool respectHyphen = ePos == m_len && hasHyphen(); |
213 TextRun textRun = constructTextRun(styleToUse, font, respectHyphen ? &charac
tersWithHyphen : 0); | 213 TextRun textRun = constructTextRun(styleToUse, font, respectHyphen ? &charac
tersWithHyphen : 0); |
214 | 214 |
215 FloatPoint startingPoint = FloatPoint(logicalLeft(), selTop.toFloat()); | 215 FloatPoint startingPoint = FloatPoint(logicalLeft(), selTop.toFloat()); |
216 LayoutRect r; | 216 LayoutRect r; |
217 if (sPos || ePos != static_cast<int>(m_len)) | 217 if (sPos || ePos != static_cast<int>(m_len)) |
218 r = enclosingIntRect(font.selectionRectForText(textRun, startingPoint, s
elHeight, sPos, ePos)); | 218 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. | 219 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.toFloat()))); | 220 r = enclosingIntRect(FloatRect(startingPoint, FloatSize(m_logicalWidth,
selHeight.toFloat()))); |
221 | 221 |
222 LayoutUnit logicalWidth = r.width(); | 222 LayoutUnit logicalWidth = r.width(); |
223 if (r.x() > logicalRight()) | 223 if (r.x() > logicalRight()) |
224 logicalWidth = 0; | 224 logicalWidth = 0; |
225 else if (r.maxX() > logicalRight()) | 225 else if (r.maxX() > logicalRight()) |
226 logicalWidth = logicalRight() - r.x(); | 226 logicalWidth = logicalRight() - r.x(); |
227 | 227 |
228 LayoutPoint topPoint = isHorizontal() ? LayoutPoint(r.x(), selTop) : LayoutP
oint(selTop, r.x()); | 228 LayoutPoint topPoint = isHorizontal() ? LayoutPoint(r.x(), selTop) : LayoutP
oint(selTop, r.x()); |
229 LayoutUnit width = isHorizontal() ? logicalWidth : selHeight; | 229 LayoutUnit width = isHorizontal() ? logicalWidth : selHeight; |
230 LayoutUnit height = isHorizontal() ? selHeight : logicalWidth; | 230 LayoutUnit height = isHorizontal() ? selHeight : logicalWidth; |
231 | 231 |
232 return LayoutRect(topPoint, LayoutSize(width, height)); | 232 return LayoutRect(topPoint, LayoutSize(width, height)); |
233 } | 233 } |
234 | 234 |
235 void InlineTextBox::deleteLine() | 235 void InlineTextBox::deleteLine() |
236 { | 236 { |
237 toRenderText(renderer()).removeTextBox(this); | 237 renderer().removeTextBox(this); |
238 destroy(); | 238 destroy(); |
239 } | 239 } |
240 | 240 |
241 void InlineTextBox::extractLine() | 241 void InlineTextBox::extractLine() |
242 { | 242 { |
243 if (extracted()) | 243 if (extracted()) |
244 return; | 244 return; |
245 | 245 |
246 toRenderText(renderer()).extractTextBox(this); | 246 renderer().extractTextBox(this); |
247 } | 247 } |
248 | 248 |
249 void InlineTextBox::attachLine() | 249 void InlineTextBox::attachLine() |
250 { | 250 { |
251 if (!extracted()) | 251 if (!extracted()) |
252 return; | 252 return; |
253 | 253 |
254 toRenderText(renderer()).attachTextBox(this); | 254 renderer().attachTextBox(this); |
255 } | 255 } |
256 | 256 |
257 float InlineTextBox::placeEllipsisBox(bool flowIsLTR, float visibleLeftEdge, flo
at visibleRightEdge, float ellipsisWidth, float &truncatedWidth, bool& foundBox) | 257 float InlineTextBox::placeEllipsisBox(bool flowIsLTR, float visibleLeftEdge, flo
at visibleRightEdge, float ellipsisWidth, float &truncatedWidth, bool& foundBox) |
258 { | 258 { |
259 if (foundBox) { | 259 if (foundBox) { |
260 m_truncation = cFullTruncation; | 260 m_truncation = cFullTruncation; |
261 return -1; | 261 return -1; |
262 } | 262 } |
263 | 263 |
264 // For LTR this is the left edge of the box, for RTL, the right edge in pare
nt coordinates. | 264 // 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 Loading... |
298 m_truncation = cFullTruncation; | 298 m_truncation = cFullTruncation; |
299 truncatedWidth += ellipsisWidth; | 299 truncatedWidth += ellipsisWidth; |
300 return std::min(ellipsisX, logicalLeft()); | 300 return std::min(ellipsisX, logicalLeft()); |
301 } | 301 } |
302 | 302 |
303 // Set the truncation index on the text run. | 303 // Set the truncation index on the text run. |
304 m_truncation = offset; | 304 m_truncation = offset; |
305 | 305 |
306 // If we got here that means that we were only partially truncated and w
e need to return the pixel offset at which | 306 // 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. | 307 // to place the ellipsis. |
308 float widthOfVisibleText = toRenderText(renderer()).width(m_start, offse
t, textPos(), flowIsLTR ? LTR : RTL, isFirstLineStyle()); | 308 float widthOfVisibleText = renderer().width(m_start, offset, textPos(),
flowIsLTR ? LTR : RTL, isFirstLineStyle()); |
309 | 309 |
310 // The ellipsis needs to be placed just after the last visible character
. | 310 // The ellipsis needs to be placed just after the last visible character
. |
311 // Where "after" is defined by the flow directionality, not the inline | 311 // Where "after" is defined by the flow directionality, not the inline |
312 // box directionality. | 312 // box directionality. |
313 // e.g. In the case of an LTR inline box truncated in an RTL flow then w
e can | 313 // 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| | 314 // have a situation such as |Hello| -> |...He| |
315 truncatedWidth += widthOfVisibleText + ellipsisWidth; | 315 truncatedWidth += widthOfVisibleText + ellipsisWidth; |
316 if (flowIsLTR) | 316 if (flowIsLTR) |
317 return logicalLeft() + widthOfVisibleText; | 317 return logicalLeft() + widthOfVisibleText; |
318 else | 318 else |
(...skipping 27 matching lines...) Expand all Loading... |
346 if (mode & TextModeStroke) { | 346 if (mode & TextModeStroke) { |
347 if (strokeColor != context->strokeColor()) | 347 if (strokeColor != context->strokeColor()) |
348 context->setStrokeColor(strokeColor); | 348 context->setStrokeColor(strokeColor); |
349 if (strokeThickness != context->strokeThickness()) | 349 if (strokeThickness != context->strokeThickness()) |
350 context->setStrokeThickness(strokeThickness); | 350 context->setStrokeThickness(strokeThickness); |
351 } | 351 } |
352 } | 352 } |
353 | 353 |
354 bool InlineTextBox::isLineBreak() const | 354 bool InlineTextBox::isLineBreak() const |
355 { | 355 { |
356 return renderer().isBR() || (renderer().style()->preserveNewline() && len()
== 1 && (*textRenderer().text().impl())[start()] == '\n'); | 356 return renderer().isBR() || (renderer().style()->preserveNewline() && len()
== 1 && (*renderer().text().impl())[start()] == '\n'); |
357 } | 357 } |
358 | 358 |
359 bool InlineTextBox::nodeAtPoint(const HitTestRequest& request, HitTestResult& re
sult, const HitTestLocation& locationInContainer, const LayoutPoint& accumulated
Offset, LayoutUnit /* lineTop */, LayoutUnit /*lineBottom*/) | 359 bool InlineTextBox::nodeAtPoint(const HitTestRequest& request, HitTestResult& re
sult, const HitTestLocation& locationInContainer, const LayoutPoint& accumulated
Offset, LayoutUnit /* lineTop */, LayoutUnit /*lineBottom*/) |
360 { | 360 { |
361 if (isLineBreak()) | 361 if (isLineBreak()) |
362 return false; | 362 return false; |
363 | 363 |
364 FloatPoint boxOrigin = locationIncludingFlipping(); | 364 FloatPoint boxOrigin = locationIncludingFlipping(); |
365 boxOrigin.moveBy(accumulatedOffset); | 365 boxOrigin.moveBy(accumulatedOffset); |
366 FloatRect rect(boxOrigin, size()); | 366 FloatRect rect(boxOrigin, size()); |
(...skipping 197 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
564 // subpixel boundaries on the x-axis and thus there is no reason to | 564 // subpixel boundaries on the x-axis and thus there is no reason to |
565 // snap the x value. We still round the y-axis to ensure consistent | 565 // snap the x value. We still round the y-axis to ensure consistent |
566 // line heights. | 566 // line heights. |
567 LayoutPoint adjustedPaintOffset = RuntimeEnabledFeatures::subpixelFontScalin
gEnabled() | 567 LayoutPoint adjustedPaintOffset = RuntimeEnabledFeatures::subpixelFontScalin
gEnabled() |
568 ? LayoutPoint(paintOffset.x(), paintOffset.y().round()) | 568 ? LayoutPoint(paintOffset.x(), paintOffset.y().round()) |
569 : roundedIntPoint(paintOffset); | 569 : roundedIntPoint(paintOffset); |
570 | 570 |
571 if (logicalStart >= paintEnd || logicalStart + logicalExtent <= paintStart) | 571 if (logicalStart >= paintEnd || logicalStart + logicalExtent <= paintStart) |
572 return; | 572 return; |
573 | 573 |
574 bool isPrinting = textRenderer().document().printing(); | 574 bool isPrinting = renderer().document().printing(); |
575 | 575 |
576 // Determine whether or not we're selected. | 576 // Determine whether or not we're selected. |
577 bool haveSelection = !isPrinting && paintInfo.phase != PaintPhaseTextClip &&
selectionState() != RenderObject::SelectionNone; | 577 bool haveSelection = !isPrinting && paintInfo.phase != PaintPhaseTextClip &&
selectionState() != RenderObject::SelectionNone; |
578 if (!haveSelection && paintInfo.phase == PaintPhaseSelection) | 578 if (!haveSelection && paintInfo.phase == PaintPhaseSelection) |
579 // When only painting the selection, don't bother to paint if there is n
one. | 579 // When only painting the selection, don't bother to paint if there is n
one. |
580 return; | 580 return; |
581 | 581 |
582 if (m_truncation != cNoTruncation) { | 582 if (m_truncation != cNoTruncation) { |
583 if (renderer().containingBlock()->style()->isLeftToRightDirection() != i
sLeftToRightDirection()) { | 583 if (renderer().containingBlock()->style()->isLeftToRightDirection() != i
sLeftToRightDirection()) { |
584 // Make the visible fragment of text hug the edge closest to the res
t of the run by moving the origin | 584 // Make the visible fragment of text hug the edge closest to the res
t of the run by moving the origin |
585 // at which we start drawing text. | 585 // at which we start drawing text. |
586 // e.g. In the case of LTR text truncated in an RTL Context, the cor
rect behavior is: | 586 // e.g. In the case of LTR text truncated in an RTL Context, the cor
rect behavior is: |
587 // |Hello|CBA| -> |...He|CBA| | 587 // |Hello|CBA| -> |...He|CBA| |
588 // In order to draw the fragment "He" aligned to the right edge of i
t's box, we need to start drawing | 588 // In order to draw the fragment "He" aligned to the right edge of i
t's box, we need to start drawing |
589 // farther to the right. | 589 // farther to the right. |
590 // NOTE: WebKit's behavior differs from that of IE which appears to
just overlay the ellipsis on top of the | 590 // NOTE: WebKit's behavior differs from that of IE which appears to
just overlay the ellipsis on top of the |
591 // truncated string i.e. |Hello|CBA| -> |...lo|CBA| | 591 // truncated string i.e. |Hello|CBA| -> |...lo|CBA| |
592 LayoutUnit widthOfVisibleText = toRenderText(renderer()).width(m_sta
rt, m_truncation, textPos(), isLeftToRightDirection() ? LTR : RTL, isFirstLineSt
yle()); | 592 LayoutUnit widthOfVisibleText = renderer().width(m_start, m_truncati
on, textPos(), isLeftToRightDirection() ? LTR : RTL, isFirstLineStyle()); |
593 LayoutUnit widthOfHiddenText = m_logicalWidth - widthOfVisibleText; | 593 LayoutUnit widthOfHiddenText = m_logicalWidth - widthOfVisibleText; |
594 // FIXME: The hit testing logic also needs to take this translation
into account. | 594 // FIXME: The hit testing logic also needs to take this translation
into account. |
595 LayoutSize truncationOffset(isLeftToRightDirection() ? widthOfHidden
Text : -widthOfHiddenText, 0); | 595 LayoutSize truncationOffset(isLeftToRightDirection() ? widthOfHidden
Text : -widthOfHiddenText, 0); |
596 adjustedPaintOffset.move(isHorizontal() ? truncationOffset : truncat
ionOffset.transposedSize()); | 596 adjustedPaintOffset.move(isHorizontal() ? truncationOffset : truncat
ionOffset.transposedSize()); |
597 } | 597 } |
598 } | 598 } |
599 | 599 |
600 GraphicsContext* context = paintInfo.context; | 600 GraphicsContext* context = paintInfo.context; |
601 RenderStyle* styleToUse = renderer().style(isFirstLineStyle()); | 601 RenderStyle* styleToUse = renderer().style(isFirstLineStyle()); |
602 | 602 |
603 adjustedPaintOffset.move(0, styleToUse->isHorizontalWritingMode() ? 0 : -log
icalHeight()); | 603 adjustedPaintOffset.move(0, styleToUse->isHorizontalWritingMode() ? 0 : -log
icalHeight()); |
604 | 604 |
605 FloatPoint boxOrigin = locationIncludingFlipping(); | 605 FloatPoint boxOrigin = locationIncludingFlipping(); |
606 boxOrigin.move(adjustedPaintOffset.x().toFloat(), adjustedPaintOffset.y().to
Float()); | 606 boxOrigin.move(adjustedPaintOffset.x().toFloat(), adjustedPaintOffset.y().to
Float()); |
607 FloatRect boxRect(boxOrigin, LayoutSize(logicalWidth(), logicalHeight())); | 607 FloatRect boxRect(boxOrigin, LayoutSize(logicalWidth(), logicalHeight())); |
608 | 608 |
609 RenderCombineText* combinedText = styleToUse->hasTextCombine() && textRender
er().isCombineText() && toRenderCombineText(textRenderer()).isCombined() ? &toRe
nderCombineText(textRenderer()) : 0; | 609 RenderCombineText* combinedText = styleToUse->hasTextCombine() && renderer()
.isCombineText() && toRenderCombineText(renderer()).isCombined() ? &toRenderComb
ineText(renderer()) : 0; |
610 | 610 |
611 bool shouldRotate = !isHorizontal() && !combinedText; | 611 bool shouldRotate = !isHorizontal() && !combinedText; |
612 if (shouldRotate) | 612 if (shouldRotate) |
613 context->concatCTM(rotation(boxRect, Clockwise)); | 613 context->concatCTM(rotation(boxRect, Clockwise)); |
614 | 614 |
615 // Determine whether or not we have composition underlines to draw. | 615 // Determine whether or not we have composition underlines to draw. |
616 bool containsComposition = renderer().node() && renderer().frame()->inputMet
hodController().compositionNode() == renderer().node(); | 616 bool containsComposition = renderer().node() && renderer().frame()->inputMet
hodController().compositionNode() == renderer().node(); |
617 bool useCustomUnderlines = containsComposition && renderer().frame()->inputM
ethodController().compositionUsesCustomUnderlines(); | 617 bool useCustomUnderlines = containsComposition && renderer().frame()->inputM
ethodController().compositionUsesCustomUnderlines(); |
618 | 618 |
619 // Determine text colors. | 619 // Determine text colors. |
620 TextPaintingStyle textStyle = textPaintingStyle(textRenderer(), styleToUse,
paintInfo.forceBlackText(), isPrinting); | 620 TextPaintingStyle textStyle = textPaintingStyle(renderer(), styleToUse, pain
tInfo.forceBlackText(), isPrinting); |
621 TextPaintingStyle selectionStyle = selectionPaintingStyle(textRenderer(), ha
veSelection, paintInfo.forceBlackText(), isPrinting, textStyle); | 621 TextPaintingStyle selectionStyle = selectionPaintingStyle(renderer(), haveSe
lection, paintInfo.forceBlackText(), isPrinting, textStyle); |
622 bool paintSelectedTextOnly = (paintInfo.phase == PaintPhaseSelection); | 622 bool paintSelectedTextOnly = (paintInfo.phase == PaintPhaseSelection); |
623 bool paintSelectedTextSeparately = !paintSelectedTextOnly && textStyle != se
lectionStyle; | 623 bool paintSelectedTextSeparately = !paintSelectedTextOnly && textStyle != se
lectionStyle; |
624 | 624 |
625 // Set our font. | 625 // Set our font. |
626 const Font& font = styleToUse->font(); | 626 const Font& font = styleToUse->font(); |
627 | 627 |
628 FloatPoint textOrigin = FloatPoint(boxOrigin.x(), boxOrigin.y() + font.fontM
etrics().ascent()); | 628 FloatPoint textOrigin = FloatPoint(boxOrigin.x(), boxOrigin.y() + font.fontM
etrics().ascent()); |
629 if (combinedText) | 629 if (combinedText) |
630 combinedText->adjustTextOrigin(textOrigin, boxRect); | 630 combinedText->adjustTextOrigin(textOrigin, boxRect); |
631 | 631 |
632 // 1. Paint backgrounds behind text if needed. Examples of such backgrounds
include selection | 632 // 1. Paint backgrounds behind text if needed. Examples of such backgrounds
include selection |
633 // and composition highlights. | 633 // and composition highlights. |
634 if (paintInfo.phase != PaintPhaseSelection && paintInfo.phase != PaintPhaseT
extClip && !isPrinting) { | 634 if (paintInfo.phase != PaintPhaseSelection && paintInfo.phase != PaintPhaseT
extClip && !isPrinting) { |
635 if (containsComposition) { | 635 if (containsComposition) { |
636 paintCompositionBackgrounds(context, boxOrigin, styleToUse, font, us
eCustomUnderlines); | 636 paintCompositionBackgrounds(context, boxOrigin, styleToUse, font, us
eCustomUnderlines); |
637 } | 637 } |
638 | 638 |
639 paintDocumentMarkers(context, boxOrigin, styleToUse, font, true); | 639 paintDocumentMarkers(context, boxOrigin, styleToUse, font, true); |
640 | 640 |
641 if (haveSelection && !useCustomUnderlines) | 641 if (haveSelection && !useCustomUnderlines) |
642 paintSelection(context, boxOrigin, styleToUse, font, selectionStyle.
fillColor); | 642 paintSelection(context, boxOrigin, styleToUse, font, selectionStyle.
fillColor); |
643 } | 643 } |
644 | 644 |
645 // 2. Now paint the foreground, including text and decorations like underlin
e/overline (in quirks mode only). | 645 // 2. Now paint the foreground, including text and decorations like underlin
e/overline (in quirks mode only). |
646 int length = m_len; | 646 int length = m_len; |
647 int maximumLength; | 647 int maximumLength; |
648 StringView string; | 648 StringView string; |
649 if (!combinedText) { | 649 if (!combinedText) { |
650 string = textRenderer().text().createView(); | 650 string = renderer().text().createView(); |
651 if (static_cast<unsigned>(length) != string.length() || m_start) | 651 if (static_cast<unsigned>(length) != string.length() || m_start) |
652 string.narrow(m_start, length); | 652 string.narrow(m_start, length); |
653 maximumLength = textRenderer().textLength() - m_start; | 653 maximumLength = renderer().textLength() - m_start; |
654 } else { | 654 } else { |
655 combinedText->getStringToRender(m_start, string, length); | 655 combinedText->getStringToRender(m_start, string, length); |
656 maximumLength = length; | 656 maximumLength = length; |
657 } | 657 } |
658 | 658 |
659 StringBuilder charactersWithHyphen; | 659 StringBuilder charactersWithHyphen; |
660 TextRun textRun = constructTextRun(styleToUse, font, string, maximumLength,
hasHyphen() ? &charactersWithHyphen : 0); | 660 TextRun textRun = constructTextRun(styleToUse, font, string, maximumLength,
hasHyphen() ? &charactersWithHyphen : 0); |
661 if (hasHyphen()) | 661 if (hasHyphen()) |
662 length = textRun.length(); | 662 length = textRun.length(); |
663 | 663 |
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
738 | 738 |
739 if (shouldRotate) | 739 if (shouldRotate) |
740 context->concatCTM(rotation(boxRect, Counterclockwise)); | 740 context->concatCTM(rotation(boxRect, Counterclockwise)); |
741 } | 741 } |
742 | 742 |
743 void InlineTextBox::selectionStartEnd(int& sPos, int& ePos) | 743 void InlineTextBox::selectionStartEnd(int& sPos, int& ePos) |
744 { | 744 { |
745 int startPos, endPos; | 745 int startPos, endPos; |
746 if (renderer().selectionState() == RenderObject::SelectionInside) { | 746 if (renderer().selectionState() == RenderObject::SelectionInside) { |
747 startPos = 0; | 747 startPos = 0; |
748 endPos = textRenderer().textLength(); | 748 endPos = renderer().textLength(); |
749 } else { | 749 } else { |
750 textRenderer().selectionStartEnd(startPos, endPos); | 750 renderer().selectionStartEnd(startPos, endPos); |
751 if (renderer().selectionState() == RenderObject::SelectionStart) | 751 if (renderer().selectionState() == RenderObject::SelectionStart) |
752 endPos = textRenderer().textLength(); | 752 endPos = renderer().textLength(); |
753 else if (renderer().selectionState() == RenderObject::SelectionEnd) | 753 else if (renderer().selectionState() == RenderObject::SelectionEnd) |
754 startPos = 0; | 754 startPos = 0; |
755 } | 755 } |
756 | 756 |
757 sPos = std::max(startPos - m_start, 0); | 757 sPos = std::max(startPos - m_start, 0); |
758 ePos = std::min(endPos - m_start, (int)m_len); | 758 ePos = std::min(endPos - m_start, (int)m_len); |
759 } | 759 } |
760 | 760 |
761 void InlineTextBox::paintSelection(GraphicsContext* context, const FloatPoint& b
oxOrigin, RenderStyle* style, const Font& font, Color textColor) | 761 void InlineTextBox::paintSelection(GraphicsContext* context, const FloatPoint& b
oxOrigin, RenderStyle* style, const Font& font, Color textColor) |
762 { | 762 { |
(...skipping 14 matching lines...) Expand all Loading... |
777 // background. | 777 // background. |
778 if (textColor == c) | 778 if (textColor == c) |
779 c = Color(0xff - c.red(), 0xff - c.green(), 0xff - c.blue()); | 779 c = Color(0xff - c.red(), 0xff - c.green(), 0xff - c.blue()); |
780 | 780 |
781 GraphicsContextStateSaver stateSaver(*context); | 781 GraphicsContextStateSaver stateSaver(*context); |
782 updateGraphicsContext(context, c, c, 0); // Don't draw text at all! | 782 updateGraphicsContext(context, c, c, 0); // Don't draw text at all! |
783 | 783 |
784 // If the text is truncated, let the thing being painted in the truncation | 784 // If the text is truncated, let the thing being painted in the truncation |
785 // draw its own highlight. | 785 // draw its own highlight. |
786 int length = m_truncation != cNoTruncation ? m_truncation : m_len; | 786 int length = m_truncation != cNoTruncation ? m_truncation : m_len; |
787 StringView string = textRenderer().text().createView(); | 787 StringView string = renderer().text().createView(); |
788 | 788 |
789 if (string.length() != static_cast<unsigned>(length) || m_start) | 789 if (string.length() != static_cast<unsigned>(length) || m_start) |
790 string.narrow(m_start, length); | 790 string.narrow(m_start, length); |
791 | 791 |
792 StringBuilder charactersWithHyphen; | 792 StringBuilder charactersWithHyphen; |
793 bool respectHyphen = ePos == length && hasHyphen(); | 793 bool respectHyphen = ePos == length && hasHyphen(); |
794 TextRun textRun = constructTextRun(style, font, string, textRenderer().textL
ength() - m_start, respectHyphen ? &charactersWithHyphen : 0); | 794 TextRun textRun = constructTextRun(style, font, string, renderer().textLengt
h() - m_start, respectHyphen ? &charactersWithHyphen : 0); |
795 if (respectHyphen) | 795 if (respectHyphen) |
796 ePos = textRun.length(); | 796 ePos = textRun.length(); |
797 | 797 |
798 LayoutUnit selectionBottom = root().selectionBottom(); | 798 LayoutUnit selectionBottom = root().selectionBottom(); |
799 LayoutUnit selectionTop = root().selectionTopAdjustedForPrecedingBlock(); | 799 LayoutUnit selectionTop = root().selectionTopAdjustedForPrecedingBlock(); |
800 | 800 |
801 int deltaY = roundToInt(renderer().style()->isFlippedLinesWritingMode() ? se
lectionBottom - logicalBottom() : logicalTop() - selectionTop); | 801 int deltaY = roundToInt(renderer().style()->isFlippedLinesWritingMode() ? se
lectionBottom - logicalBottom() : logicalTop() - selectionTop); |
802 int selHeight = std::max(0, roundToInt(selectionBottom - selectionTop)); | 802 int selHeight = std::max(0, roundToInt(selectionBottom - selectionTop)); |
803 | 803 |
804 FloatPoint localOrigin(boxOrigin.x(), boxOrigin.y() - deltaY); | 804 FloatPoint localOrigin(boxOrigin.x(), boxOrigin.y() - deltaY); |
(...skipping 249 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1054 { | 1054 { |
1055 GraphicsContextStateSaver stateSaver(*context); | 1055 GraphicsContextStateSaver stateSaver(*context); |
1056 | 1056 |
1057 if (m_truncation == cFullTruncation) | 1057 if (m_truncation == cFullTruncation) |
1058 return; | 1058 return; |
1059 | 1059 |
1060 FloatPoint localOrigin = boxOrigin; | 1060 FloatPoint localOrigin = boxOrigin; |
1061 | 1061 |
1062 float width = m_logicalWidth; | 1062 float width = m_logicalWidth; |
1063 if (m_truncation != cNoTruncation) { | 1063 if (m_truncation != cNoTruncation) { |
1064 width = toRenderText(renderer()).width(m_start, m_truncation, textPos(),
isLeftToRightDirection() ? LTR : RTL, isFirstLineStyle()); | 1064 width = renderer().width(m_start, m_truncation, textPos(), isLeftToRight
Direction() ? LTR : RTL, isFirstLineStyle()); |
1065 if (!isLeftToRightDirection()) | 1065 if (!isLeftToRightDirection()) |
1066 localOrigin.move(m_logicalWidth - width, 0); | 1066 localOrigin.move(m_logicalWidth - width, 0); |
1067 } | 1067 } |
1068 | 1068 |
1069 // Get the text decoration colors. | 1069 // Get the text decoration colors. |
1070 RenderObject::AppliedTextDecoration underline, overline, linethrough; | 1070 RenderObject::AppliedTextDecoration underline, overline, linethrough; |
1071 | 1071 |
1072 renderer().getTextDecorations(deco, underline, overline, linethrough, true); | 1072 renderer().getTextDecorations(deco, underline, overline, linethrough, true); |
1073 if (isFirstLineStyle()) | 1073 if (isFirstLineStyle()) |
1074 renderer().getTextDecorations(deco, underline, overline, linethrough, tr
ue, true); | 1074 renderer().getTextDecorations(deco, underline, overline, linethrough, tr
ue, true); |
1075 | 1075 |
1076 // Use a special function for underlines to get the positioning exactly righ
t. | 1076 // Use a special function for underlines to get the positioning exactly righ
t. |
1077 bool isPrinting = textRenderer().document().printing(); | 1077 bool isPrinting = renderer().document().printing(); |
1078 | 1078 |
1079 bool linesAreOpaque = !isPrinting && (!(deco & TextDecorationUnderline) || u
nderline.color.alpha() == 255) && (!(deco & TextDecorationOverline) || overline.
color.alpha() == 255) && (!(deco & TextDecorationLineThrough) || linethrough.col
or.alpha() == 255); | 1079 bool linesAreOpaque = !isPrinting && (!(deco & TextDecorationUnderline) || u
nderline.color.alpha() == 255) && (!(deco & TextDecorationOverline) || overline.
color.alpha() == 255) && (!(deco & TextDecorationLineThrough) || linethrough.col
or.alpha() == 255); |
1080 | 1080 |
1081 RenderStyle* styleToUse = renderer().style(isFirstLineStyle()); | 1081 RenderStyle* styleToUse = renderer().style(isFirstLineStyle()); |
1082 int baseline = styleToUse->fontMetrics().ascent(); | 1082 int baseline = styleToUse->fontMetrics().ascent(); |
1083 | 1083 |
1084 size_t shadowCount = shadowList ? shadowList->shadows().size() : 0; | 1084 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. | 1085 // 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. | 1086 // Using computedFontSize should take care of zoom as well. |
1087 | 1087 |
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1154 return GraphicsContext::DocumentMarkerGrammarLineStyle; | 1154 return GraphicsContext::DocumentMarkerGrammarLineStyle; |
1155 default: | 1155 default: |
1156 ASSERT_NOT_REACHED(); | 1156 ASSERT_NOT_REACHED(); |
1157 return GraphicsContext::DocumentMarkerSpellingLineStyle; | 1157 return GraphicsContext::DocumentMarkerSpellingLineStyle; |
1158 } | 1158 } |
1159 } | 1159 } |
1160 | 1160 |
1161 void InlineTextBox::paintDocumentMarker(GraphicsContext* pt, const FloatPoint& b
oxOrigin, DocumentMarker* marker, RenderStyle* style, const Font& font, bool gra
mmar) | 1161 void InlineTextBox::paintDocumentMarker(GraphicsContext* pt, const FloatPoint& b
oxOrigin, DocumentMarker* marker, RenderStyle* style, const Font& font, bool gra
mmar) |
1162 { | 1162 { |
1163 // Never print spelling/grammar markers (5327887) | 1163 // Never print spelling/grammar markers (5327887) |
1164 if (textRenderer().document().printing()) | 1164 if (renderer().document().printing()) |
1165 return; | 1165 return; |
1166 | 1166 |
1167 if (m_truncation == cFullTruncation) | 1167 if (m_truncation == cFullTruncation) |
1168 return; | 1168 return; |
1169 | 1169 |
1170 float start = 0; // start of line to draw, relative to tx | 1170 float start = 0; // start of line to draw, relative to tx |
1171 float width = m_logicalWidth; // how much line to draw | 1171 float width = m_logicalWidth; // how much line to draw |
1172 | 1172 |
1173 // Determine whether we need to measure text | 1173 // Determine whether we need to measure text |
1174 bool markerSpansWholeBox = true; | 1174 bool markerSpansWholeBox = true; |
(...skipping 156 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1331 void InlineTextBox::paintCompositionUnderline(GraphicsContext* ctx, const FloatP
oint& boxOrigin, const CompositionUnderline& underline) | 1331 void InlineTextBox::paintCompositionUnderline(GraphicsContext* ctx, const FloatP
oint& boxOrigin, const CompositionUnderline& underline) |
1332 { | 1332 { |
1333 if (m_truncation == cFullTruncation) | 1333 if (m_truncation == cFullTruncation) |
1334 return; | 1334 return; |
1335 | 1335 |
1336 unsigned paintStart = underlinePaintStart(underline); | 1336 unsigned paintStart = underlinePaintStart(underline); |
1337 unsigned paintEnd = underlinePaintEnd(underline); | 1337 unsigned paintEnd = underlinePaintEnd(underline); |
1338 | 1338 |
1339 // start of line to draw, relative to paintOffset. | 1339 // start of line to draw, relative to paintOffset. |
1340 float start = paintStart == static_cast<unsigned>(m_start) ? 0 : | 1340 float start = paintStart == static_cast<unsigned>(m_start) ? 0 : |
1341 toRenderText(renderer()).width(m_start, paintStart - m_start, textPos(),
isLeftToRightDirection() ? LTR : RTL, isFirstLineStyle()); | 1341 renderer().width(m_start, paintStart - m_start, textPos(), isLeftToRight
Direction() ? LTR : RTL, isFirstLineStyle()); |
1342 // how much line to draw | 1342 // how much line to draw |
1343 float width = (paintStart == static_cast<unsigned>(m_start) && paintEnd == s
tatic_cast<unsigned>(end()) + 1) ? m_logicalWidth : | 1343 float width = (paintStart == static_cast<unsigned>(m_start) && paintEnd == s
tatic_cast<unsigned>(end()) + 1) ? m_logicalWidth : |
1344 toRenderText(renderer()).width(paintStart, paintEnd - paintStart, textPo
s() + start, isLeftToRightDirection() ? LTR : RTL, isFirstLineStyle()); | 1344 renderer().width(paintStart, paintEnd - paintStart, textPos() + start, i
sLeftToRightDirection() ? LTR : RTL, isFirstLineStyle()); |
1345 | 1345 |
1346 // Thick marked text underlines are 2px thick as long as there is room for t
he 2px line under the baseline. | 1346 // Thick marked text underlines are 2px thick as long as there is room for t
he 2px line under the baseline. |
1347 // All other marked text underlines are 1px thick. | 1347 // All other marked text underlines are 1px thick. |
1348 // If there's not enough space the underline will touch or overlap character
s. | 1348 // If there's not enough space the underline will touch or overlap character
s. |
1349 int lineThickness = 1; | 1349 int lineThickness = 1; |
1350 int baseline = renderer().style(isFirstLineStyle())->fontMetrics().ascent(); | 1350 int baseline = renderer().style(isFirstLineStyle())->fontMetrics().ascent(); |
1351 if (underline.thick && logicalHeight() - baseline >= 2) | 1351 if (underline.thick && logicalHeight() - baseline >= 2) |
1352 lineThickness = 2; | 1352 lineThickness = 2; |
1353 | 1353 |
1354 // We need to have some space between underlines of subsequent clauses, beca
use some input methods do not use different underline styles for those. | 1354 // We need to have some space between underlines of subsequent clauses, beca
use some input methods do not use different underline styles for those. |
1355 // We make each line shorter, which has a harmless side effect of shortening
the first and last clauses, too. | 1355 // We make each line shorter, which has a harmless side effect of shortening
the first and last clauses, too. |
1356 start += 1; | 1356 start += 1; |
1357 width -= 2; | 1357 width -= 2; |
1358 | 1358 |
1359 ctx->setStrokeColor(underline.color); | 1359 ctx->setStrokeColor(underline.color); |
1360 ctx->setStrokeThickness(lineThickness); | 1360 ctx->setStrokeThickness(lineThickness); |
1361 ctx->drawLineForText(FloatPoint(boxOrigin.x() + start, boxOrigin.y() + logic
alHeight() - lineThickness), width, textRenderer().document().printing()); | 1361 ctx->drawLineForText(FloatPoint(boxOrigin.x() + start, boxOrigin.y() + logic
alHeight() - lineThickness), width, renderer().document().printing()); |
1362 } | 1362 } |
1363 | 1363 |
1364 int InlineTextBox::caretMinOffset() const | 1364 int InlineTextBox::caretMinOffset() const |
1365 { | 1365 { |
1366 return m_start; | 1366 return m_start; |
1367 } | 1367 } |
1368 | 1368 |
1369 int InlineTextBox::caretMaxOffset() const | 1369 int InlineTextBox::caretMaxOffset() const |
1370 { | 1370 { |
1371 return m_start + m_len; | 1371 return m_start + m_len; |
(...skipping 13 matching lines...) Expand all Loading... |
1385 if (isLineBreak()) | 1385 if (isLineBreak()) |
1386 return 0; | 1386 return 0; |
1387 | 1387 |
1388 if (lineOffset - logicalLeft() > logicalWidth()) | 1388 if (lineOffset - logicalLeft() > logicalWidth()) |
1389 return isLeftToRightDirection() ? len() : 0; | 1389 return isLeftToRightDirection() ? len() : 0; |
1390 if (lineOffset - logicalLeft() < 0) | 1390 if (lineOffset - logicalLeft() < 0) |
1391 return isLeftToRightDirection() ? 0 : len(); | 1391 return isLeftToRightDirection() ? 0 : len(); |
1392 | 1392 |
1393 FontCachePurgePreventer fontCachePurgePreventer; | 1393 FontCachePurgePreventer fontCachePurgePreventer; |
1394 | 1394 |
1395 RenderText& text = toRenderText(renderer()); | 1395 RenderText& text = renderer(); |
1396 RenderStyle* style = text.style(isFirstLineStyle()); | 1396 RenderStyle* style = text.style(isFirstLineStyle()); |
1397 const Font& font = style->font(); | 1397 const Font& font = style->font(); |
1398 return font.offsetForPosition(constructTextRun(style, font), lineOffset - lo
gicalLeft(), includePartialGlyphs); | 1398 return font.offsetForPosition(constructTextRun(style, font), lineOffset - lo
gicalLeft(), includePartialGlyphs); |
1399 } | 1399 } |
1400 | 1400 |
1401 float InlineTextBox::positionForOffset(int offset) const | 1401 float InlineTextBox::positionForOffset(int offset) const |
1402 { | 1402 { |
1403 ASSERT(offset >= m_start); | 1403 ASSERT(offset >= m_start); |
1404 ASSERT(offset <= m_start + m_len); | 1404 ASSERT(offset <= m_start + m_len); |
1405 | 1405 |
1406 if (isLineBreak()) | 1406 if (isLineBreak()) |
1407 return logicalLeft(); | 1407 return logicalLeft(); |
1408 | 1408 |
1409 FontCachePurgePreventer fontCachePurgePreventer; | 1409 FontCachePurgePreventer fontCachePurgePreventer; |
1410 | 1410 |
1411 RenderText& text = toRenderText(renderer()); | 1411 RenderText& text = renderer(); |
1412 RenderStyle* styleToUse = text.style(isFirstLineStyle()); | 1412 RenderStyle* styleToUse = text.style(isFirstLineStyle()); |
1413 ASSERT(styleToUse); | 1413 ASSERT(styleToUse); |
1414 const Font& font = styleToUse->font(); | 1414 const Font& font = styleToUse->font(); |
1415 int from = !isLeftToRightDirection() ? offset - m_start : 0; | 1415 int from = !isLeftToRightDirection() ? offset - m_start : 0; |
1416 int to = !isLeftToRightDirection() ? m_len : offset - m_start; | 1416 int to = !isLeftToRightDirection() ? m_len : offset - m_start; |
1417 // FIXME: Do we need to add rightBearing here? | 1417 // FIXME: Do we need to add rightBearing here? |
1418 return font.selectionRectForText(constructTextRun(styleToUse, font), IntPoin
t(logicalLeft(), 0), 0, from, to).maxX(); | 1418 return font.selectionRectForText(constructTextRun(styleToUse, font), IntPoin
t(logicalLeft(), 0), 0, from, to).maxX(); |
1419 } | 1419 } |
1420 | 1420 |
1421 bool InlineTextBox::containsCaretOffset(int offset) const | 1421 bool InlineTextBox::containsCaretOffset(int offset) const |
(...skipping 17 matching lines...) Expand all Loading... |
1439 return false; | 1439 return false; |
1440 | 1440 |
1441 // Offsets at the end are "in" for normal boxes (but the caller has to check
affinity). | 1441 // Offsets at the end are "in" for normal boxes (but the caller has to check
affinity). |
1442 return true; | 1442 return true; |
1443 } | 1443 } |
1444 | 1444 |
1445 void InlineTextBox::characterWidths(Vector<float>& widths) const | 1445 void InlineTextBox::characterWidths(Vector<float>& widths) const |
1446 { | 1446 { |
1447 FontCachePurgePreventer fontCachePurgePreventer; | 1447 FontCachePurgePreventer fontCachePurgePreventer; |
1448 | 1448 |
1449 RenderStyle* styleToUse = textRenderer().style(isFirstLineStyle()); | 1449 RenderStyle* styleToUse = renderer().style(isFirstLineStyle()); |
1450 const Font& font = styleToUse->font(); | 1450 const Font& font = styleToUse->font(); |
1451 | 1451 |
1452 TextRun textRun = constructTextRun(styleToUse, font); | 1452 TextRun textRun = constructTextRun(styleToUse, font); |
1453 | 1453 |
1454 GlyphBuffer glyphBuffer; | 1454 GlyphBuffer glyphBuffer; |
1455 WidthIterator it(&font, textRun); | 1455 WidthIterator it(&font, textRun); |
1456 float lastWidth = 0; | 1456 float lastWidth = 0; |
1457 widths.resize(m_len); | 1457 widths.resize(m_len); |
1458 for (unsigned i = 0; i < m_len; i++) { | 1458 for (unsigned i = 0; i < m_len; i++) { |
1459 it.advance(i + 1, &glyphBuffer); | 1459 it.advance(i + 1, &glyphBuffer); |
1460 widths[i] = it.m_runWidthSoFar - lastWidth; | 1460 widths[i] = it.m_runWidthSoFar - lastWidth; |
1461 lastWidth = it.m_runWidthSoFar; | 1461 lastWidth = it.m_runWidthSoFar; |
1462 } | 1462 } |
1463 } | 1463 } |
1464 | 1464 |
1465 TextRun InlineTextBox::constructTextRun(RenderStyle* style, const Font& font, St
ringBuilder* charactersWithHyphen) const | 1465 TextRun InlineTextBox::constructTextRun(RenderStyle* style, const Font& font, St
ringBuilder* charactersWithHyphen) const |
1466 { | 1466 { |
1467 ASSERT(style); | 1467 ASSERT(style); |
1468 ASSERT(textRenderer().text()); | 1468 ASSERT(renderer().text()); |
1469 | 1469 |
1470 StringView string = textRenderer().text().createView(); | 1470 StringView string = renderer().text().createView(); |
1471 unsigned startPos = start(); | 1471 unsigned startPos = start(); |
1472 unsigned length = len(); | 1472 unsigned length = len(); |
1473 | 1473 |
1474 if (string.length() != length || startPos) | 1474 if (string.length() != length || startPos) |
1475 string.narrow(startPos, length); | 1475 string.narrow(startPos, length); |
1476 | 1476 |
1477 return constructTextRun(style, font, string, textRenderer().textLength() - s
tartPos, charactersWithHyphen); | 1477 return constructTextRun(style, font, string, renderer().textLength() - start
Pos, charactersWithHyphen); |
1478 } | 1478 } |
1479 | 1479 |
1480 TextRun InlineTextBox::constructTextRun(RenderStyle* style, const Font& font, St
ringView string, int maximumLength, StringBuilder* charactersWithHyphen) const | 1480 TextRun InlineTextBox::constructTextRun(RenderStyle* style, const Font& font, St
ringView string, int maximumLength, StringBuilder* charactersWithHyphen) const |
1481 { | 1481 { |
1482 ASSERT(style); | 1482 ASSERT(style); |
1483 | 1483 |
1484 if (charactersWithHyphen) { | 1484 if (charactersWithHyphen) { |
1485 const AtomicString& hyphenString = style->hyphenString(); | 1485 const AtomicString& hyphenString = style->hyphenString(); |
1486 charactersWithHyphen->reserveCapacity(string.length() + hyphenString.len
gth()); | 1486 charactersWithHyphen->reserveCapacity(string.length() + hyphenString.len
gth()); |
1487 charactersWithHyphen->append(string); | 1487 charactersWithHyphen->append(string); |
1488 charactersWithHyphen->append(hyphenString); | 1488 charactersWithHyphen->append(hyphenString); |
1489 string = charactersWithHyphen->toString().createView(); | 1489 string = charactersWithHyphen->toString().createView(); |
1490 maximumLength = string.length(); | 1490 maximumLength = string.length(); |
1491 } | 1491 } |
1492 | 1492 |
1493 ASSERT(maximumLength >= static_cast<int>(string.length())); | 1493 ASSERT(maximumLength >= static_cast<int>(string.length())); |
1494 | 1494 |
1495 TextRun run(string, textPos(), expansion(), expansionBehavior(), direction()
, dirOverride() || style->rtlOrdering() == VisualOrder, !textRenderer().canUseSi
mpleFontCodePath()); | 1495 TextRun run(string, textPos(), expansion(), expansionBehavior(), direction()
, dirOverride() || style->rtlOrdering() == VisualOrder, !renderer().canUseSimple
FontCodePath()); |
1496 run.setTabSize(!style->collapseWhiteSpace(), style->tabSize()); | 1496 run.setTabSize(!style->collapseWhiteSpace(), style->tabSize()); |
1497 run.setCharacterScanForCodePath(!textRenderer().canUseSimpleFontCodePath()); | 1497 run.setCharacterScanForCodePath(!renderer().canUseSimpleFontCodePath()); |
1498 if (textRunNeedsRenderingContext(font)) | 1498 if (textRunNeedsRenderingContext(font)) |
1499 run.setRenderingContext(SVGTextRunRenderingContext::create(&textRenderer
())); | 1499 run.setRenderingContext(SVGTextRunRenderingContext::create(&renderer()))
; |
1500 | 1500 |
1501 // Propagate the maximum length of the characters buffer to the TextRun, eve
n when we're only processing a substring. | 1501 // Propagate the maximum length of the characters buffer to the TextRun, eve
n when we're only processing a substring. |
1502 run.setCharactersLength(maximumLength); | 1502 run.setCharactersLength(maximumLength); |
1503 ASSERT(run.charactersLength() >= run.length()); | 1503 ASSERT(run.charactersLength() >= run.length()); |
1504 return run; | 1504 return run; |
1505 } | 1505 } |
1506 | 1506 |
1507 TextRun InlineTextBox::constructTextRunForInspector(RenderStyle* style, const Fo
nt& font) const | 1507 TextRun InlineTextBox::constructTextRunForInspector(RenderStyle* style, const Fo
nt& font) const |
1508 { | 1508 { |
1509 return InlineTextBox::constructTextRun(style, font); | 1509 return InlineTextBox::constructTextRun(style, font); |
1510 } | 1510 } |
1511 | 1511 |
1512 #ifndef NDEBUG | 1512 #ifndef NDEBUG |
1513 | 1513 |
1514 const char* InlineTextBox::boxName() const | 1514 const char* InlineTextBox::boxName() const |
1515 { | 1515 { |
1516 return "InlineTextBox"; | 1516 return "InlineTextBox"; |
1517 } | 1517 } |
1518 | 1518 |
1519 void InlineTextBox::showBox(int printedCharacters) const | 1519 void InlineTextBox::showBox(int printedCharacters) const |
1520 { | 1520 { |
1521 const RenderText& obj = toRenderText(renderer()); | 1521 const RenderText& obj = renderer(); |
1522 String value = obj.text(); | 1522 String value = obj.text(); |
1523 value = value.substring(start(), len()); | 1523 value = value.substring(start(), len()); |
1524 value.replaceWithLiteral('\\', "\\\\"); | 1524 value.replaceWithLiteral('\\', "\\\\"); |
1525 value.replaceWithLiteral('\n', "\\n"); | 1525 value.replaceWithLiteral('\n', "\\n"); |
1526 printedCharacters += fprintf(stderr, "%s\t%p", boxName(), this); | 1526 printedCharacters += fprintf(stderr, "%s\t%p", boxName(), this); |
1527 for (; printedCharacters < showTreeCharacterOffset; printedCharacters++) | 1527 for (; printedCharacters < showTreeCharacterOffset; printedCharacters++) |
1528 fputc(' ', stderr); | 1528 fputc(' ', stderr); |
1529 printedCharacters = fprintf(stderr, "\t%s %p", obj.renderName(), &obj); | 1529 printedCharacters = fprintf(stderr, "\t%s %p", obj.renderName(), &obj); |
1530 const int rendererCharacterOffset = 24; | 1530 const int rendererCharacterOffset = 24; |
1531 for (; printedCharacters < rendererCharacterOffset; printedCharacters++) | 1531 for (; printedCharacters < rendererCharacterOffset; printedCharacters++) |
1532 fputc(' ', stderr); | 1532 fputc(' ', stderr); |
1533 fprintf(stderr, "(%d,%d) \"%s\"\n", start(), start() + len(), value.utf8().d
ata()); | 1533 fprintf(stderr, "(%d,%d) \"%s\"\n", start(), start() + len(), value.utf8().d
ata()); |
1534 } | 1534 } |
1535 | 1535 |
1536 #endif | 1536 #endif |
1537 | 1537 |
1538 } // namespace blink | 1538 } // namespace blink |
OLD | NEW |