| 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 332 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 343 int distanceFromWhite = differenceSquared(textColor, Color::white); | 343 int distanceFromWhite = differenceSquared(textColor, Color::white); |
| 344 int distanceFromBlack = differenceSquared(textColor, Color::black); | 344 int distanceFromBlack = differenceSquared(textColor, Color::black); |
| 345 | 345 |
| 346 if (distanceFromWhite < distanceFromBlack) { | 346 if (distanceFromWhite < distanceFromBlack) { |
| 347 return textColor.dark(); | 347 return textColor.dark(); |
| 348 } | 348 } |
| 349 | 349 |
| 350 return textColor.light(); | 350 return textColor.light(); |
| 351 } | 351 } |
| 352 | 352 |
| 353 void updateGraphicsContext(GraphicsContext* context, const Color& fillColor, con
st Color& strokeColor, float strokeThickness, ColorSpace colorSpace) | 353 void updateGraphicsContext(GraphicsContext* context, const Color& fillColor, con
st Color& strokeColor, float strokeThickness) |
| 354 { | 354 { |
| 355 TextDrawingModeFlags mode = context->textDrawingMode(); | 355 TextDrawingModeFlags mode = context->textDrawingMode(); |
| 356 if (strokeThickness > 0) { | 356 if (strokeThickness > 0) { |
| 357 TextDrawingModeFlags newMode = mode | TextModeStroke; | 357 TextDrawingModeFlags newMode = mode | TextModeStroke; |
| 358 if (mode != newMode) { | 358 if (mode != newMode) { |
| 359 context->setTextDrawingMode(newMode); | 359 context->setTextDrawingMode(newMode); |
| 360 mode = newMode; | 360 mode = newMode; |
| 361 } | 361 } |
| 362 } | 362 } |
| 363 | 363 |
| 364 if (mode & TextModeFill && (fillColor != context->fillColor() || colorSpace
!= context->fillColorSpace())) | 364 if (mode & TextModeFill && fillColor != context->fillColor()) |
| 365 context->setFillColor(fillColor, colorSpace); | 365 context->setFillColor(fillColor); |
| 366 | 366 |
| 367 if (mode & TextModeStroke) { | 367 if (mode & TextModeStroke) { |
| 368 if (strokeColor != context->strokeColor()) | 368 if (strokeColor != context->strokeColor()) |
| 369 context->setStrokeColor(strokeColor, colorSpace); | 369 context->setStrokeColor(strokeColor); |
| 370 if (strokeThickness != context->strokeThickness()) | 370 if (strokeThickness != context->strokeThickness()) |
| 371 context->setStrokeThickness(strokeThickness); | 371 context->setStrokeThickness(strokeThickness); |
| 372 } | 372 } |
| 373 } | 373 } |
| 374 | 374 |
| 375 bool InlineTextBox::isLineBreak() const | 375 bool InlineTextBox::isLineBreak() const |
| 376 { | 376 { |
| 377 return renderer()->isBR() || (renderer()->style()->preserveNewline() && len(
) == 1 && (*textRenderer()->text())[start()] == '\n'); | 377 return renderer()->isBR() || (renderer()->style()->preserveNewline() && len(
) == 1 && (*textRenderer()->text())[start()] == '\n'); |
| 378 } | 378 } |
| 379 | 379 |
| (...skipping 350 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 730 bool hasTextEmphasis = getEmphasisMarkPosition(styleToUse, emphasisMarkPosit
ion); | 730 bool hasTextEmphasis = getEmphasisMarkPosition(styleToUse, emphasisMarkPosit
ion); |
| 731 const AtomicString& emphasisMark = hasTextEmphasis ? styleToUse->textEmphasi
sMarkString() : nullAtom; | 731 const AtomicString& emphasisMark = hasTextEmphasis ? styleToUse->textEmphasi
sMarkString() : nullAtom; |
| 732 if (!emphasisMark.isEmpty()) | 732 if (!emphasisMark.isEmpty()) |
| 733 emphasisMarkOffset = emphasisMarkPosition == TextEmphasisPositionOver ?
-font.fontMetrics().ascent() - font.emphasisMarkDescent(emphasisMark) : font.fon
tMetrics().descent() + font.emphasisMarkAscent(emphasisMark); | 733 emphasisMarkOffset = emphasisMarkPosition == TextEmphasisPositionOver ?
-font.fontMetrics().ascent() - font.emphasisMarkDescent(emphasisMark) : font.fon
tMetrics().descent() + font.emphasisMarkAscent(emphasisMark); |
| 734 | 734 |
| 735 if (!paintSelectedTextOnly) { | 735 if (!paintSelectedTextOnly) { |
| 736 // For stroked painting, we have to change the text drawing mode. It's
probably dangerous to leave that mutated as a side | 736 // For stroked painting, we have to change the text drawing mode. It's
probably dangerous to leave that mutated as a side |
| 737 // effect, so only when we know we're stroking, do a save/restore. | 737 // effect, so only when we know we're stroking, do a save/restore. |
| 738 GraphicsContextStateSaver stateSaver(*context, textStrokeWidth > 0); | 738 GraphicsContextStateSaver stateSaver(*context, textStrokeWidth > 0); |
| 739 | 739 |
| 740 updateGraphicsContext(context, textFillColor, textStrokeColor, textStrok
eWidth, styleToUse->colorSpace()); | 740 updateGraphicsContext(context, textFillColor, textStrokeColor, textStrok
eWidth); |
| 741 if (!paintSelectedTextSeparately || ePos <= sPos) { | 741 if (!paintSelectedTextSeparately || ePos <= sPos) { |
| 742 // FIXME: Truncate right-to-left text correctly. | 742 // FIXME: Truncate right-to-left text correctly. |
| 743 paintTextWithShadows(context, font, textRun, nullAtom, 0, 0, length,
length, textOrigin, boxRect, textShadow, textStrokeWidth > 0, isHorizontal()); | 743 paintTextWithShadows(context, font, textRun, nullAtom, 0, 0, length,
length, textOrigin, boxRect, textShadow, textStrokeWidth > 0, isHorizontal()); |
| 744 } else | 744 } else |
| 745 paintTextWithShadows(context, font, textRun, nullAtom, 0, ePos, sPos
, length, textOrigin, boxRect, textShadow, textStrokeWidth > 0, isHorizontal()); | 745 paintTextWithShadows(context, font, textRun, nullAtom, 0, ePos, sPos
, length, textOrigin, boxRect, textShadow, textStrokeWidth > 0, isHorizontal()); |
| 746 | 746 |
| 747 if (!emphasisMark.isEmpty()) { | 747 if (!emphasisMark.isEmpty()) { |
| 748 updateGraphicsContext(context, emphasisMarkColor, textStrokeColor, t
extStrokeWidth, styleToUse->colorSpace()); | 748 updateGraphicsContext(context, emphasisMarkColor, textStrokeColor, t
extStrokeWidth); |
| 749 | 749 |
| 750 DEFINE_STATIC_LOCAL(TextRun, objectReplacementCharacterTextRun, (&ob
jectReplacementCharacter, 1)); | 750 DEFINE_STATIC_LOCAL(TextRun, objectReplacementCharacterTextRun, (&ob
jectReplacementCharacter, 1)); |
| 751 TextRun& emphasisMarkTextRun = combinedText ? objectReplacementChara
cterTextRun : textRun; | 751 TextRun& emphasisMarkTextRun = combinedText ? objectReplacementChara
cterTextRun : textRun; |
| 752 FloatPoint emphasisMarkTextOrigin = combinedText ? FloatPoint(boxOri
gin.x() + boxRect.width() / 2, boxOrigin.y() + font.fontMetrics().ascent()) : te
xtOrigin; | 752 FloatPoint emphasisMarkTextOrigin = combinedText ? FloatPoint(boxOri
gin.x() + boxRect.width() / 2, boxOrigin.y() + font.fontMetrics().ascent()) : te
xtOrigin; |
| 753 if (combinedText) | 753 if (combinedText) |
| 754 context->concatCTM(rotation(boxRect, Clockwise)); | 754 context->concatCTM(rotation(boxRect, Clockwise)); |
| 755 | 755 |
| 756 if (!paintSelectedTextSeparately || ePos <= sPos) { | 756 if (!paintSelectedTextSeparately || ePos <= sPos) { |
| 757 // FIXME: Truncate right-to-left text correctly. | 757 // FIXME: Truncate right-to-left text correctly. |
| 758 paintTextWithShadows(context, combinedText ? combinedText->origi
nalFont() : font, emphasisMarkTextRun, emphasisMark, emphasisMarkOffset, 0, leng
th, length, emphasisMarkTextOrigin, boxRect, textShadow, textStrokeWidth > 0, is
Horizontal()); | 758 paintTextWithShadows(context, combinedText ? combinedText->origi
nalFont() : font, emphasisMarkTextRun, emphasisMark, emphasisMarkOffset, 0, leng
th, length, emphasisMarkTextOrigin, boxRect, textShadow, textStrokeWidth > 0, is
Horizontal()); |
| 759 } else | 759 } else |
| 760 paintTextWithShadows(context, combinedText ? combinedText->origi
nalFont() : font, emphasisMarkTextRun, emphasisMark, emphasisMarkOffset, ePos, s
Pos, length, emphasisMarkTextOrigin, boxRect, textShadow, textStrokeWidth > 0, i
sHorizontal()); | 760 paintTextWithShadows(context, combinedText ? combinedText->origi
nalFont() : font, emphasisMarkTextRun, emphasisMark, emphasisMarkOffset, ePos, s
Pos, length, emphasisMarkTextOrigin, boxRect, textShadow, textStrokeWidth > 0, i
sHorizontal()); |
| 761 | 761 |
| 762 if (combinedText) | 762 if (combinedText) |
| 763 context->concatCTM(rotation(boxRect, Counterclockwise)); | 763 context->concatCTM(rotation(boxRect, Counterclockwise)); |
| 764 } | 764 } |
| 765 } | 765 } |
| 766 | 766 |
| 767 if ((paintSelectedTextOnly || paintSelectedTextSeparately) && sPos < ePos) { | 767 if ((paintSelectedTextOnly || paintSelectedTextSeparately) && sPos < ePos) { |
| 768 // paint only the text that is selected | 768 // paint only the text that is selected |
| 769 GraphicsContextStateSaver stateSaver(*context, selectionStrokeWidth > 0)
; | 769 GraphicsContextStateSaver stateSaver(*context, selectionStrokeWidth > 0)
; |
| 770 | 770 |
| 771 updateGraphicsContext(context, selectionFillColor, selectionStrokeColor,
selectionStrokeWidth, styleToUse->colorSpace()); | 771 updateGraphicsContext(context, selectionFillColor, selectionStrokeColor,
selectionStrokeWidth); |
| 772 paintTextWithShadows(context, font, textRun, nullAtom, 0, sPos, ePos, le
ngth, textOrigin, boxRect, selectionShadow, selectionStrokeWidth > 0, isHorizont
al()); | 772 paintTextWithShadows(context, font, textRun, nullAtom, 0, sPos, ePos, le
ngth, textOrigin, boxRect, selectionShadow, selectionStrokeWidth > 0, isHorizont
al()); |
| 773 if (!emphasisMark.isEmpty()) { | 773 if (!emphasisMark.isEmpty()) { |
| 774 updateGraphicsContext(context, selectionEmphasisMarkColor, textStrok
eColor, textStrokeWidth, styleToUse->colorSpace()); | 774 updateGraphicsContext(context, selectionEmphasisMarkColor, textStrok
eColor, textStrokeWidth); |
| 775 | 775 |
| 776 DEFINE_STATIC_LOCAL(TextRun, objectReplacementCharacterTextRun, (&ob
jectReplacementCharacter, 1)); | 776 DEFINE_STATIC_LOCAL(TextRun, objectReplacementCharacterTextRun, (&ob
jectReplacementCharacter, 1)); |
| 777 TextRun& emphasisMarkTextRun = combinedText ? objectReplacementChara
cterTextRun : textRun; | 777 TextRun& emphasisMarkTextRun = combinedText ? objectReplacementChara
cterTextRun : textRun; |
| 778 FloatPoint emphasisMarkTextOrigin = combinedText ? FloatPoint(boxOri
gin.x() + boxRect.width() / 2, boxOrigin.y() + font.fontMetrics().ascent()) : te
xtOrigin; | 778 FloatPoint emphasisMarkTextOrigin = combinedText ? FloatPoint(boxOri
gin.x() + boxRect.width() / 2, boxOrigin.y() + font.fontMetrics().ascent()) : te
xtOrigin; |
| 779 if (combinedText) | 779 if (combinedText) |
| 780 context->concatCTM(rotation(boxRect, Clockwise)); | 780 context->concatCTM(rotation(boxRect, Clockwise)); |
| 781 | 781 |
| 782 paintTextWithShadows(context, combinedText ? combinedText->originalF
ont() : font, emphasisMarkTextRun, emphasisMark, emphasisMarkOffset, sPos, ePos,
length, emphasisMarkTextOrigin, boxRect, selectionShadow, selectionStrokeWidth
> 0, isHorizontal()); | 782 paintTextWithShadows(context, combinedText ? combinedText->originalF
ont() : font, emphasisMarkTextRun, emphasisMark, emphasisMarkOffset, sPos, ePos,
length, emphasisMarkTextOrigin, boxRect, selectionShadow, selectionStrokeWidth
> 0, isHorizontal()); |
| 783 | 783 |
| 784 if (combinedText) | 784 if (combinedText) |
| 785 context->concatCTM(rotation(boxRect, Counterclockwise)); | 785 context->concatCTM(rotation(boxRect, Counterclockwise)); |
| 786 } | 786 } |
| 787 } | 787 } |
| 788 | 788 |
| 789 // Paint decorations | 789 // Paint decorations |
| 790 TextDecoration textDecorations = styleToUse->textDecorationsInEffect(); | 790 TextDecoration textDecorations = styleToUse->textDecorationsInEffect(); |
| 791 if (textDecorations != TextDecorationNone && paintInfo.phase != PaintPhaseSe
lection) { | 791 if (textDecorations != TextDecorationNone && paintInfo.phase != PaintPhaseSe
lection) { |
| 792 updateGraphicsContext(context, textFillColor, textStrokeColor, textStrok
eWidth, styleToUse->colorSpace()); | 792 updateGraphicsContext(context, textFillColor, textStrokeColor, textStrok
eWidth); |
| 793 if (combinedText) | 793 if (combinedText) |
| 794 context->concatCTM(rotation(boxRect, Clockwise)); | 794 context->concatCTM(rotation(boxRect, Clockwise)); |
| 795 paintDecoration(context, boxOrigin, textDecorations, styleToUse->textDec
orationStyle(), textShadow); | 795 paintDecoration(context, boxOrigin, textDecorations, styleToUse->textDec
orationStyle(), textShadow); |
| 796 if (combinedText) | 796 if (combinedText) |
| 797 context->concatCTM(rotation(boxRect, Counterclockwise)); | 797 context->concatCTM(rotation(boxRect, Counterclockwise)); |
| 798 } | 798 } |
| 799 | 799 |
| 800 if (paintInfo.phase == PaintPhaseForeground) { | 800 if (paintInfo.phase == PaintPhaseForeground) { |
| 801 paintDocumentMarkers(context, boxOrigin, styleToUse, font, false); | 801 paintDocumentMarkers(context, boxOrigin, styleToUse, font, false); |
| 802 | 802 |
| (...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 869 Color c = renderer()->selectionBackgroundColor(); | 869 Color c = renderer()->selectionBackgroundColor(); |
| 870 if (!c.isValid() || c.alpha() == 0) | 870 if (!c.isValid() || c.alpha() == 0) |
| 871 return; | 871 return; |
| 872 | 872 |
| 873 // If the text color ends up being the same as the selection background, inv
ert the selection | 873 // If the text color ends up being the same as the selection background, inv
ert the selection |
| 874 // background. | 874 // background. |
| 875 if (textColor == c) | 875 if (textColor == c) |
| 876 c = Color(0xff - c.red(), 0xff - c.green(), 0xff - c.blue()); | 876 c = Color(0xff - c.red(), 0xff - c.green(), 0xff - c.blue()); |
| 877 | 877 |
| 878 GraphicsContextStateSaver stateSaver(*context); | 878 GraphicsContextStateSaver stateSaver(*context); |
| 879 updateGraphicsContext(context, c, c, 0, style->colorSpace()); // Don't draw
text at all! | 879 updateGraphicsContext(context, c, c, 0); // Don't draw text at all! |
| 880 | 880 |
| 881 // If the text is truncated, let the thing being painted in the truncation | 881 // If the text is truncated, let the thing being painted in the truncation |
| 882 // draw its own highlight. | 882 // draw its own highlight. |
| 883 int length = m_truncation != cNoTruncation ? m_truncation : m_len; | 883 int length = m_truncation != cNoTruncation ? m_truncation : m_len; |
| 884 String string = textRenderer()->text(); | 884 String string = textRenderer()->text(); |
| 885 | 885 |
| 886 if (string.length() != static_cast<unsigned>(length) || m_start) { | 886 if (string.length() != static_cast<unsigned>(length) || m_start) { |
| 887 ASSERT_WITH_SECURITY_IMPLICATION(static_cast<unsigned>(m_start + length)
<= string.length()); | 887 ASSERT_WITH_SECURITY_IMPLICATION(static_cast<unsigned>(m_start + length)
<= string.length()); |
| 888 string = string.substringSharingImpl(m_start, length); | 888 string = string.substringSharingImpl(m_start, length); |
| 889 } | 889 } |
| 890 | 890 |
| 891 BufferForAppendingHyphen charactersWithHyphen; | 891 BufferForAppendingHyphen charactersWithHyphen; |
| 892 bool respectHyphen = ePos == length && hasHyphen(); | 892 bool respectHyphen = ePos == length && hasHyphen(); |
| 893 TextRun textRun = constructTextRun(style, font, string, textRenderer()->text
Length() - m_start, respectHyphen ? &charactersWithHyphen : 0); | 893 TextRun textRun = constructTextRun(style, font, string, textRenderer()->text
Length() - m_start, respectHyphen ? &charactersWithHyphen : 0); |
| 894 if (respectHyphen) | 894 if (respectHyphen) |
| 895 ePos = textRun.length(); | 895 ePos = textRun.length(); |
| 896 | 896 |
| 897 LayoutUnit selectionBottom = root()->selectionBottom(); | 897 LayoutUnit selectionBottom = root()->selectionBottom(); |
| 898 LayoutUnit selectionTop = root()->selectionTopAdjustedForPrecedingBlock(); | 898 LayoutUnit selectionTop = root()->selectionTopAdjustedForPrecedingBlock(); |
| 899 | 899 |
| 900 int deltaY = roundToInt(renderer()->style()->isFlippedLinesWritingMode() ? s
electionBottom - logicalBottom() : logicalTop() - selectionTop); | 900 int deltaY = roundToInt(renderer()->style()->isFlippedLinesWritingMode() ? s
electionBottom - logicalBottom() : logicalTop() - selectionTop); |
| 901 int selHeight = max(0, roundToInt(selectionBottom - selectionTop)); | 901 int selHeight = max(0, roundToInt(selectionBottom - selectionTop)); |
| 902 | 902 |
| 903 FloatPoint localOrigin(boxOrigin.x(), boxOrigin.y() - deltaY); | 903 FloatPoint localOrigin(boxOrigin.x(), boxOrigin.y() - deltaY); |
| 904 FloatRect clipRect(localOrigin, FloatSize(m_logicalWidth, selHeight)); | 904 FloatRect clipRect(localOrigin, FloatSize(m_logicalWidth, selHeight)); |
| 905 alignSelectionRectToDevicePixels(clipRect); | 905 alignSelectionRectToDevicePixels(clipRect); |
| 906 | 906 |
| 907 context->clip(clipRect); | 907 context->clip(clipRect); |
| 908 | 908 |
| 909 context->drawHighlightForText(font, textRun, localOrigin, selHeight, c, styl
e->colorSpace(), sPos, ePos); | 909 context->drawHighlightForText(font, textRun, localOrigin, selHeight, c, sPos
, ePos); |
| 910 } | 910 } |
| 911 | 911 |
| 912 void InlineTextBox::paintCompositionBackground(GraphicsContext* context, const F
loatPoint& boxOrigin, RenderStyle* style, const Font& font, int startPos, int en
dPos) | 912 void InlineTextBox::paintCompositionBackground(GraphicsContext* context, const F
loatPoint& boxOrigin, RenderStyle* style, const Font& font, int startPos, int en
dPos) |
| 913 { | 913 { |
| 914 int offset = m_start; | 914 int offset = m_start; |
| 915 int sPos = max(startPos - offset, 0); | 915 int sPos = max(startPos - offset, 0); |
| 916 int ePos = min(endPos - offset, (int)m_len); | 916 int ePos = min(endPos - offset, (int)m_len); |
| 917 | 917 |
| 918 if (sPos >= ePos) | 918 if (sPos >= ePos) |
| 919 return; | 919 return; |
| 920 | 920 |
| 921 GraphicsContextStateSaver stateSaver(*context); | 921 GraphicsContextStateSaver stateSaver(*context); |
| 922 | 922 |
| 923 Color c = Color(225, 221, 85); | 923 Color c = Color(225, 221, 85); |
| 924 | 924 |
| 925 updateGraphicsContext(context, c, c, 0, style->colorSpace()); // Don't draw
text at all! | 925 updateGraphicsContext(context, c, c, 0); // Don't draw text at all! |
| 926 | 926 |
| 927 int deltaY = renderer()->style()->isFlippedLinesWritingMode() ? selectionBot
tom() - logicalBottom() : logicalTop() - selectionTop(); | 927 int deltaY = renderer()->style()->isFlippedLinesWritingMode() ? selectionBot
tom() - logicalBottom() : logicalTop() - selectionTop(); |
| 928 int selHeight = selectionHeight(); | 928 int selHeight = selectionHeight(); |
| 929 FloatPoint localOrigin(boxOrigin.x(), boxOrigin.y() - deltaY); | 929 FloatPoint localOrigin(boxOrigin.x(), boxOrigin.y() - deltaY); |
| 930 context->drawHighlightForText(font, constructTextRun(style, font), localOrig
in, selHeight, c, style->colorSpace(), sPos, ePos); | 930 context->drawHighlightForText(font, constructTextRun(style, font), localOrig
in, selHeight, c, sPos, ePos); |
| 931 } | 931 } |
| 932 | 932 |
| 933 static StrokeStyle textDecorationStyleToStrokeStyle(TextDecorationStyle decorati
onStyle) | 933 static StrokeStyle textDecorationStyleToStrokeStyle(TextDecorationStyle decorati
onStyle) |
| 934 { | 934 { |
| 935 StrokeStyle strokeStyle = SolidStroke; | 935 StrokeStyle strokeStyle = SolidStroke; |
| 936 switch (decorationStyle) { | 936 switch (decorationStyle) { |
| 937 case TextDecorationStyleSolid: | 937 case TextDecorationStyleSolid: |
| 938 strokeStyle = SolidStroke; | 938 strokeStyle = SolidStroke; |
| 939 break; | 939 break; |
| 940 case TextDecorationStyleDouble: | 940 case TextDecorationStyleDouble: |
| (...skipping 206 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1147 int shadowY = isHorizontal() ? s->y() : -s->x(); | 1147 int shadowY = isHorizontal() ? s->y() : -s->x(); |
| 1148 shadowRect.move(shadowX, shadowY); | 1148 shadowRect.move(shadowX, shadowY); |
| 1149 clipRect.unite(shadowRect); | 1149 clipRect.unite(shadowRect); |
| 1150 extraOffset = max(extraOffset, max(0, shadowY) + s->blur()); | 1150 extraOffset = max(extraOffset, max(0, shadowY) + s->blur()); |
| 1151 } | 1151 } |
| 1152 context->clip(clipRect); | 1152 context->clip(clipRect); |
| 1153 extraOffset += baseline + 2; | 1153 extraOffset += baseline + 2; |
| 1154 localOrigin.move(0, extraOffset); | 1154 localOrigin.move(0, extraOffset); |
| 1155 } | 1155 } |
| 1156 | 1156 |
| 1157 ColorSpace colorSpace = renderer()->style()->colorSpace(); | |
| 1158 | |
| 1159 do { | 1157 do { |
| 1160 if (shadow) { | 1158 if (shadow) { |
| 1161 if (!shadow->next()) { | 1159 if (!shadow->next()) { |
| 1162 // The last set of lines paints normally inside the clip. | 1160 // The last set of lines paints normally inside the clip. |
| 1163 localOrigin.move(0, -extraOffset); | 1161 localOrigin.move(0, -extraOffset); |
| 1164 extraOffset = 0; | 1162 extraOffset = 0; |
| 1165 } | 1163 } |
| 1166 int shadowX = isHorizontal() ? shadow->x() : shadow->y(); | 1164 int shadowX = isHorizontal() ? shadow->x() : shadow->y(); |
| 1167 int shadowY = isHorizontal() ? shadow->y() : -shadow->x(); | 1165 int shadowY = isHorizontal() ? shadow->y() : -shadow->x(); |
| 1168 context->setShadow(FloatSize(shadowX, shadowY - extraOffset), shadow
->blur(), shadow->color()); | 1166 context->setShadow(FloatSize(shadowX, shadowY - extraOffset), shadow
->blur(), shadow->color()); |
| 1169 shadow = shadow->next(); | 1167 shadow = shadow->next(); |
| 1170 } | 1168 } |
| 1171 | 1169 |
| 1172 // Offset between lines - always non-zero, so lines never cross each oth
er. | 1170 // Offset between lines - always non-zero, so lines never cross each oth
er. |
| 1173 float doubleOffset = textDecorationThickness + 1.f; | 1171 float doubleOffset = textDecorationThickness + 1.f; |
| 1174 context->setStrokeStyle(textDecorationStyleToStrokeStyle(decorationStyle
)); | 1172 context->setStrokeStyle(textDecorationStyleToStrokeStyle(decorationStyle
)); |
| 1175 if (deco & TextDecorationUnderline) { | 1173 if (deco & TextDecorationUnderline) { |
| 1176 context->setStrokeColor(underline, colorSpace); | 1174 context->setStrokeColor(underline); |
| 1177 #if ENABLE(CSS3_TEXT) | 1175 #if ENABLE(CSS3_TEXT) |
| 1178 TextUnderlinePosition underlinePosition = styleToUse->textUnderlineP
osition(); | 1176 TextUnderlinePosition underlinePosition = styleToUse->textUnderlineP
osition(); |
| 1179 const int underlineOffset = computeUnderlineOffset(underlinePosition
, styleToUse->fontMetrics(), this, textDecorationThickness); | 1177 const int underlineOffset = computeUnderlineOffset(underlinePosition
, styleToUse->fontMetrics(), this, textDecorationThickness); |
| 1180 #else | 1178 #else |
| 1181 const int underlineOffset = styleToUse->fontMetrics().ascent() + max
<int>(1, ceilf(textDecorationThickness / 2.0)); | 1179 const int underlineOffset = styleToUse->fontMetrics().ascent() + max
<int>(1, ceilf(textDecorationThickness / 2.0)); |
| 1182 #endif // CSS3_TEXT | 1180 #endif // CSS3_TEXT |
| 1183 | 1181 |
| 1184 switch (decorationStyle) { | 1182 switch (decorationStyle) { |
| 1185 case TextDecorationStyleWavy: { | 1183 case TextDecorationStyleWavy: { |
| 1186 FloatPoint start(localOrigin.x(), localOrigin.y() + underlineOff
set + doubleOffset); | 1184 FloatPoint start(localOrigin.x(), localOrigin.y() + underlineOff
set + doubleOffset); |
| 1187 FloatPoint end(localOrigin.x() + width, localOrigin.y() + underl
ineOffset + doubleOffset); | 1185 FloatPoint end(localOrigin.x() + width, localOrigin.y() + underl
ineOffset + doubleOffset); |
| 1188 strokeWavyTextDecoration(context, start, end, textDecorationThic
kness); | 1186 strokeWavyTextDecoration(context, start, end, textDecorationThic
kness); |
| 1189 break; | 1187 break; |
| 1190 } | 1188 } |
| 1191 default: | 1189 default: |
| 1192 context->drawLineForText(FloatPoint(localOrigin.x(), localOrigin
.y() + underlineOffset), width, isPrinting); | 1190 context->drawLineForText(FloatPoint(localOrigin.x(), localOrigin
.y() + underlineOffset), width, isPrinting); |
| 1193 | 1191 |
| 1194 if (decorationStyle == TextDecorationStyleDouble) | 1192 if (decorationStyle == TextDecorationStyleDouble) |
| 1195 context->drawLineForText(FloatPoint(localOrigin.x(), localOr
igin.y() + underlineOffset + doubleOffset), width, isPrinting); | 1193 context->drawLineForText(FloatPoint(localOrigin.x(), localOr
igin.y() + underlineOffset + doubleOffset), width, isPrinting); |
| 1196 } | 1194 } |
| 1197 } | 1195 } |
| 1198 if (deco & TextDecorationOverline) { | 1196 if (deco & TextDecorationOverline) { |
| 1199 context->setStrokeColor(overline, colorSpace); | 1197 context->setStrokeColor(overline); |
| 1200 switch (decorationStyle) { | 1198 switch (decorationStyle) { |
| 1201 case TextDecorationStyleWavy: { | 1199 case TextDecorationStyleWavy: { |
| 1202 FloatPoint start(localOrigin.x(), localOrigin.y() - doubleOffset
); | 1200 FloatPoint start(localOrigin.x(), localOrigin.y() - doubleOffset
); |
| 1203 FloatPoint end(localOrigin.x() + width, localOrigin.y() - double
Offset); | 1201 FloatPoint end(localOrigin.x() + width, localOrigin.y() - double
Offset); |
| 1204 strokeWavyTextDecoration(context, start, end, textDecorationThic
kness); | 1202 strokeWavyTextDecoration(context, start, end, textDecorationThic
kness); |
| 1205 break; | 1203 break; |
| 1206 } | 1204 } |
| 1207 default: | 1205 default: |
| 1208 context->drawLineForText(localOrigin, width, isPrinting); | 1206 context->drawLineForText(localOrigin, width, isPrinting); |
| 1209 if (decorationStyle == TextDecorationStyleDouble) | 1207 if (decorationStyle == TextDecorationStyleDouble) |
| 1210 context->drawLineForText(FloatPoint(localOrigin.x(), localOr
igin.y() - doubleOffset), width, isPrinting); | 1208 context->drawLineForText(FloatPoint(localOrigin.x(), localOr
igin.y() - doubleOffset), width, isPrinting); |
| 1211 } | 1209 } |
| 1212 } | 1210 } |
| 1213 if (deco & TextDecorationLineThrough) { | 1211 if (deco & TextDecorationLineThrough) { |
| 1214 context->setStrokeColor(linethrough, colorSpace); | 1212 context->setStrokeColor(linethrough); |
| 1215 switch (decorationStyle) { | 1213 switch (decorationStyle) { |
| 1216 case TextDecorationStyleWavy: { | 1214 case TextDecorationStyleWavy: { |
| 1217 FloatPoint start(localOrigin.x(), localOrigin.y() + 2 * baseline
/ 3); | 1215 FloatPoint start(localOrigin.x(), localOrigin.y() + 2 * baseline
/ 3); |
| 1218 FloatPoint end(localOrigin.x() + width, localOrigin.y() + 2 * ba
seline / 3); | 1216 FloatPoint end(localOrigin.x() + width, localOrigin.y() + 2 * ba
seline / 3); |
| 1219 strokeWavyTextDecoration(context, start, end, textDecorationThic
kness); | 1217 strokeWavyTextDecoration(context, start, end, textDecorationThic
kness); |
| 1220 break; | 1218 break; |
| 1221 } | 1219 } |
| 1222 default: | 1220 default: |
| 1223 context->drawLineForText(FloatPoint(localOrigin.x(), localOrigin
.y() + 2 * baseline / 3), width, isPrinting); | 1221 context->drawLineForText(FloatPoint(localOrigin.x(), localOrigin
.y() + 2 * baseline / 3), width, isPrinting); |
| 1224 if (decorationStyle == TextDecorationStyleDouble) | 1222 if (decorationStyle == TextDecorationStyleDouble) |
| (...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1317 int selHeight = selectionHeight(); | 1315 int selHeight = selectionHeight(); |
| 1318 | 1316 |
| 1319 int sPos = max(marker->startOffset() - m_start, (unsigned)0); | 1317 int sPos = max(marker->startOffset() - m_start, (unsigned)0); |
| 1320 int ePos = min(marker->endOffset() - m_start, (unsigned)m_len); | 1318 int ePos = min(marker->endOffset() - m_start, (unsigned)m_len); |
| 1321 TextRun run = constructTextRun(style, font); | 1319 TextRun run = constructTextRun(style, font); |
| 1322 | 1320 |
| 1323 // Always compute and store the rect associated with this marker. The comput
ed rect is in absolute coordinates. | 1321 // Always compute and store the rect associated with this marker. The comput
ed rect is in absolute coordinates. |
| 1324 IntRect markerRect = enclosingIntRect(font.selectionRectForText(run, IntPoin
t(x(), selectionTop()), selHeight, sPos, ePos)); | 1322 IntRect markerRect = enclosingIntRect(font.selectionRectForText(run, IntPoin
t(x(), selectionTop()), selHeight, sPos, ePos)); |
| 1325 markerRect = renderer()->localToAbsoluteQuad(FloatRect(markerRect)).enclosin
gBoundingBox(); | 1323 markerRect = renderer()->localToAbsoluteQuad(FloatRect(markerRect)).enclosin
gBoundingBox(); |
| 1326 toRenderedDocumentMarker(marker)->setRenderedRect(markerRect); | 1324 toRenderedDocumentMarker(marker)->setRenderedRect(markerRect); |
| 1327 | 1325 |
| 1328 // Optionally highlight the text | 1326 // Optionally highlight the text |
| 1329 if (renderer()->frame()->editor()->markedTextMatchesAreHighlighted()) { | 1327 if (renderer()->frame()->editor()->markedTextMatchesAreHighlighted()) { |
| 1330 Color color = marker->activeMatch() ? | 1328 Color color = marker->activeMatch() ? |
| 1331 renderer()->theme()->platformActiveTextSearchHighlightColor() : | 1329 renderer()->theme()->platformActiveTextSearchHighlightColor() : |
| 1332 renderer()->theme()->platformInactiveTextSearchHighlightColor(); | 1330 renderer()->theme()->platformInactiveTextSearchHighlightColor(); |
| 1333 GraphicsContextStateSaver stateSaver(*pt); | 1331 GraphicsContextStateSaver stateSaver(*pt); |
| 1334 updateGraphicsContext(pt, color, color, 0, style->colorSpace()); // Don
't draw text at all! | 1332 updateGraphicsContext(pt, color, color, 0); // Don't draw text at all! |
| 1335 pt->clip(FloatRect(boxOrigin.x(), boxOrigin.y() - deltaY, m_logicalWidth
, selHeight)); | 1333 pt->clip(FloatRect(boxOrigin.x(), boxOrigin.y() - deltaY, m_logicalWidth
, selHeight)); |
| 1336 pt->drawHighlightForText(font, run, FloatPoint(boxOrigin.x(), boxOrigin.
y() - deltaY), selHeight, color, style->colorSpace(), sPos, ePos); | 1334 pt->drawHighlightForText(font, run, FloatPoint(boxOrigin.x(), boxOrigin.
y() - deltaY), selHeight, color, sPos, ePos); |
| 1337 } | 1335 } |
| 1338 } | 1336 } |
| 1339 | 1337 |
| 1340 void InlineTextBox::paintDocumentMarkers(GraphicsContext* pt, const FloatPoint&
boxOrigin, RenderStyle* style, const Font& font, bool background) | 1338 void InlineTextBox::paintDocumentMarkers(GraphicsContext* pt, const FloatPoint&
boxOrigin, RenderStyle* style, const Font& font, bool background) |
| 1341 { | 1339 { |
| 1342 if (!renderer()->node()) | 1340 if (!renderer()->node()) |
| 1343 return; | 1341 return; |
| 1344 | 1342 |
| 1345 Vector<DocumentMarker*> markers = renderer()->document()->markers()->markers
For(renderer()->node()); | 1343 Vector<DocumentMarker*> markers = renderer()->document()->markers()->markers
For(renderer()->node()); |
| 1346 Vector<DocumentMarker*>::const_iterator markerIt = markers.begin(); | 1344 Vector<DocumentMarker*>::const_iterator markerIt = markers.begin(); |
| (...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1425 int lineThickness = 1; | 1423 int lineThickness = 1; |
| 1426 int baseline = renderer()->style(isFirstLineStyle())->fontMetrics().ascent()
; | 1424 int baseline = renderer()->style(isFirstLineStyle())->fontMetrics().ascent()
; |
| 1427 if (underline.thick && logicalHeight() - baseline >= 2) | 1425 if (underline.thick && logicalHeight() - baseline >= 2) |
| 1428 lineThickness = 2; | 1426 lineThickness = 2; |
| 1429 | 1427 |
| 1430 // We need to have some space between underlines of subsequent clauses, beca
use some input methods do not use different underline styles for those. | 1428 // We need to have some space between underlines of subsequent clauses, beca
use some input methods do not use different underline styles for those. |
| 1431 // We make each line shorter, which has a harmless side effect of shortening
the first and last clauses, too. | 1429 // We make each line shorter, which has a harmless side effect of shortening
the first and last clauses, too. |
| 1432 start += 1; | 1430 start += 1; |
| 1433 width -= 2; | 1431 width -= 2; |
| 1434 | 1432 |
| 1435 ctx->setStrokeColor(underline.color, renderer()->style()->colorSpace()); | 1433 ctx->setStrokeColor(underline.color); |
| 1436 ctx->setStrokeThickness(lineThickness); | 1434 ctx->setStrokeThickness(lineThickness); |
| 1437 ctx->drawLineForText(FloatPoint(boxOrigin.x() + start, boxOrigin.y() + logic
alHeight() - lineThickness), width, textRenderer()->document()->printing()); | 1435 ctx->drawLineForText(FloatPoint(boxOrigin.x() + start, boxOrigin.y() + logic
alHeight() - lineThickness), width, textRenderer()->document()->printing()); |
| 1438 } | 1436 } |
| 1439 | 1437 |
| 1440 int InlineTextBox::caretMinOffset() const | 1438 int InlineTextBox::caretMinOffset() const |
| 1441 { | 1439 { |
| 1442 return m_start; | 1440 return m_start; |
| 1443 } | 1441 } |
| 1444 | 1442 |
| 1445 int InlineTextBox::caretMaxOffset() const | 1443 int InlineTextBox::caretMaxOffset() const |
| (...skipping 145 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1591 | 1589 |
| 1592 void InlineTextBox::reportMemoryUsage(MemoryObjectInfo* memoryObjectInfo) const | 1590 void InlineTextBox::reportMemoryUsage(MemoryObjectInfo* memoryObjectInfo) const |
| 1593 { | 1591 { |
| 1594 MemoryClassInfo info(memoryObjectInfo, this, WebCoreMemoryTypes::Rendering); | 1592 MemoryClassInfo info(memoryObjectInfo, this, WebCoreMemoryTypes::Rendering); |
| 1595 InlineBox::reportMemoryUsage(memoryObjectInfo); | 1593 InlineBox::reportMemoryUsage(memoryObjectInfo); |
| 1596 info.addMember(m_prevTextBox, "prevTextBox"); | 1594 info.addMember(m_prevTextBox, "prevTextBox"); |
| 1597 info.addMember(m_nextTextBox, "nextTextBox"); | 1595 info.addMember(m_nextTextBox, "nextTextBox"); |
| 1598 } | 1596 } |
| 1599 | 1597 |
| 1600 } // namespace WebCore | 1598 } // namespace WebCore |
| OLD | NEW |