| 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 24 matching lines...) Expand all Loading... |
| 35 #include "core/rendering/AbstractInlineTextBox.h" | 35 #include "core/rendering/AbstractInlineTextBox.h" |
| 36 #include "core/rendering/EllipsisBox.h" | 36 #include "core/rendering/EllipsisBox.h" |
| 37 #include "core/rendering/HitTestResult.h" | 37 #include "core/rendering/HitTestResult.h" |
| 38 #include "core/rendering/PaintInfo.h" | 38 #include "core/rendering/PaintInfo.h" |
| 39 #include "core/rendering/RenderBR.h" | 39 #include "core/rendering/RenderBR.h" |
| 40 #include "core/rendering/RenderBlock.h" | 40 #include "core/rendering/RenderBlock.h" |
| 41 #include "core/rendering/RenderCombineText.h" | 41 #include "core/rendering/RenderCombineText.h" |
| 42 #include "core/rendering/RenderRubyRun.h" | 42 #include "core/rendering/RenderRubyRun.h" |
| 43 #include "core/rendering/RenderRubyText.h" | 43 #include "core/rendering/RenderRubyText.h" |
| 44 #include "core/rendering/RenderTheme.h" | 44 #include "core/rendering/RenderTheme.h" |
| 45 #include "core/rendering/style/AppliedTextDecoration.h" |
| 45 #include "core/rendering/style/ShadowList.h" | 46 #include "core/rendering/style/ShadowList.h" |
| 46 #include "core/rendering/svg/SVGTextRunRenderingContext.h" | 47 #include "core/rendering/svg/SVGTextRunRenderingContext.h" |
| 47 #include "platform/fonts/FontCache.h" | 48 #include "platform/fonts/FontCache.h" |
| 48 #include "platform/fonts/WidthIterator.h" | 49 #include "platform/fonts/WidthIterator.h" |
| 49 #include "platform/graphics/DrawLooperBuilder.h" | 50 #include "platform/graphics/DrawLooperBuilder.h" |
| 50 #include "platform/graphics/GraphicsContextStateSaver.h" | 51 #include "platform/graphics/GraphicsContextStateSaver.h" |
| 51 #include "wtf/Vector.h" | 52 #include "wtf/Vector.h" |
| 52 #include "wtf/text/CString.h" | 53 #include "wtf/text/CString.h" |
| 53 #include "wtf/text/StringBuilder.h" | 54 #include "wtf/text/StringBuilder.h" |
| 54 | 55 |
| (...skipping 687 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 742 int endOffset = combinedText ? objectReplacementCharacterTextRun.len
gth() : ePos; | 743 int endOffset = combinedText ? objectReplacementCharacterTextRun.len
gth() : ePos; |
| 743 int paintRunLength = combinedText ? endOffset : length; | 744 int paintRunLength = combinedText ? endOffset : length; |
| 744 paintTextWithShadows(context, rendererToUse, combinedText ? combined
Text->originalFont() : font, emphasisMarkTextRun, emphasisMark, emphasisMarkOffs
et, startOffset, endOffset, paintRunLength, emphasisMarkTextOrigin, boxRect, sel
ectionShadow, selectionStrokeWidth > 0, isHorizontal()); | 745 paintTextWithShadows(context, rendererToUse, combinedText ? combined
Text->originalFont() : font, emphasisMarkTextRun, emphasisMark, emphasisMarkOffs
et, startOffset, endOffset, paintRunLength, emphasisMarkTextOrigin, boxRect, sel
ectionShadow, selectionStrokeWidth > 0, isHorizontal()); |
| 745 | 746 |
| 746 if (combinedText) | 747 if (combinedText) |
| 747 context->concatCTM(rotation(boxRect, Counterclockwise)); | 748 context->concatCTM(rotation(boxRect, Counterclockwise)); |
| 748 } | 749 } |
| 749 } | 750 } |
| 750 | 751 |
| 751 // Paint decorations | 752 // Paint decorations |
| 752 TextDecoration textDecorations = styleToUse->textDecorationsInEffect(); | 753 if (styleToUse->hasAppliedTextDecorations() && paintInfo.phase != PaintPhase
Selection) { |
| 753 if (textDecorations != TextDecorationNone && paintInfo.phase != PaintPhaseSe
lection) { | |
| 754 updateGraphicsContext(context, textFillColor, textStrokeColor, textStrok
eWidth); | 754 updateGraphicsContext(context, textFillColor, textStrokeColor, textStrok
eWidth); |
| 755 if (combinedText) | 755 if (combinedText) |
| 756 context->concatCTM(rotation(boxRect, Clockwise)); | 756 context->concatCTM(rotation(boxRect, Clockwise)); |
| 757 paintDecoration(context, boxOrigin, textDecorations, textShadow); | 757 paintDecoration(context, boxOrigin, styleToUse, textShadow); |
| 758 if (combinedText) | 758 if (combinedText) |
| 759 context->concatCTM(rotation(boxRect, Counterclockwise)); | 759 context->concatCTM(rotation(boxRect, Counterclockwise)); |
| 760 } | 760 } |
| 761 | 761 |
| 762 if (paintInfo.phase == PaintPhaseForeground) { | 762 if (paintInfo.phase == PaintPhaseForeground) { |
| 763 paintDocumentMarkers(context, boxOrigin, styleToUse, font, false); | 763 paintDocumentMarkers(context, boxOrigin, styleToUse, font, false); |
| 764 | 764 |
| 765 if (useCustomUnderlines) { | 765 if (useCustomUnderlines) { |
| 766 const Vector<CompositionUnderline>& underlines = renderer().frame()-
>inputMethodController().customCompositionUnderlines(); | 766 const Vector<CompositionUnderline>& underlines = renderer().frame()-
>inputMethodController().customCompositionUnderlines(); |
| 767 size_t numUnderlines = underlines.size(); | 767 size_t numUnderlines = underlines.size(); |
| (...skipping 139 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 907 strokeStyle = DashedStroke; | 907 strokeStyle = DashedStroke; |
| 908 break; | 908 break; |
| 909 case TextDecorationStyleWavy: | 909 case TextDecorationStyleWavy: |
| 910 strokeStyle = WavyStroke; | 910 strokeStyle = WavyStroke; |
| 911 break; | 911 break; |
| 912 } | 912 } |
| 913 | 913 |
| 914 return strokeStyle; | 914 return strokeStyle; |
| 915 } | 915 } |
| 916 | 916 |
| 917 static int computeUnderlineOffset(const TextUnderlinePosition underlinePosition,
const FontMetrics& fontMetrics, const InlineTextBox* inlineTextBox, const float
textDecorationThickness) | 917 int InlineTextBox::computeUnderlineOffset(RenderStyle* style, const float textDe
corationThickness) |
| 918 { | 918 { |
| 919 const TextUnderlinePosition underlinePosition = style->textUnderlinePosition
(); |
| 920 const FontMetrics& fontMetrics = style->fontMetrics(); |
| 921 |
| 919 // Compute the gap between the font and the underline. Use at least one | 922 // Compute the gap between the font and the underline. Use at least one |
| 920 // pixel gap, if underline is thick then use a bigger gap. | 923 // pixel gap, if underline is thick then use a bigger gap. |
| 921 int gap = 0; | 924 int gap = 0; |
| 922 | 925 |
| 923 // Underline position of zero means draw underline on Baseline Position, | 926 // Underline position of zero means draw underline on Baseline Position, |
| 924 // in Blink we need at least 1-pixel gap to adding following check. | 927 // in Blink we need at least 1-pixel gap to adding following check. |
| 925 // Positive underline Position means underline should be drawn above baselin
e | 928 // Positive underline Position means underline should be drawn above baselin
e |
| 926 // and negative value means drawing below baseline, negating the value as in
Blink | 929 // and negative value means drawing below baseline, negating the value as in
Blink |
| 927 // downward Y-increases. | 930 // downward Y-increases. |
| 928 | 931 |
| 929 if (fontMetrics.underlinePosition()) | 932 if (fontMetrics.underlinePosition()) |
| 930 gap = -fontMetrics.underlinePosition(); | 933 gap = -fontMetrics.underlinePosition(); |
| 931 else | 934 else |
| 932 gap = std::max<int>(1, ceilf(textDecorationThickness / 2.f)); | 935 gap = std::max<int>(1, ceilf(textDecorationThickness / 2.f)); |
| 933 | 936 |
| 934 // FIXME: We support only horizontal text for now. | 937 // FIXME: We support only horizontal text for now. |
| 935 switch (underlinePosition) { | 938 switch (underlinePosition) { |
| 936 case TextUnderlinePositionAuto: | 939 case TextUnderlinePositionAuto: |
| 937 return fontMetrics.ascent() + gap; // Position underline near the alphab
etic baseline. | 940 return fontMetrics.ascent() + gap; // Position underline near the alphab
etic baseline. |
| 938 case TextUnderlinePositionUnder: { | 941 case TextUnderlinePositionUnder: { |
| 939 // Position underline relative to the under edge of the lowest element's
content box. | 942 // Position underline relative to the under edge of the lowest element's
content box. |
| 940 const float offset = inlineTextBox->root().maxLogicalTop() - inlineTextB
ox->logicalTop(); | 943 const float offset = root().maxLogicalTop() - logicalTop(); |
| 941 if (offset > 0) | 944 if (offset > 0) |
| 942 return inlineTextBox->logicalHeight() + gap + offset; | 945 return logicalHeight() + gap + offset; |
| 943 return inlineTextBox->logicalHeight() + gap; | 946 return logicalHeight() + gap; |
| 944 } | 947 } |
| 945 } | 948 } |
| 946 | 949 |
| 947 ASSERT_NOT_REACHED(); | 950 ASSERT_NOT_REACHED(); |
| 948 return fontMetrics.ascent() + gap; | 951 return fontMetrics.ascent() + gap; |
| 949 } | 952 } |
| 950 | 953 |
| 951 static void adjustStepToDecorationLength(float& step, float& controlPointDistanc
e, float length) | 954 static void adjustStepToDecorationLength(float& step, float& controlPointDistanc
e, float length) |
| 952 { | 955 { |
| 953 ASSERT(step > 0); | 956 ASSERT(step > 0); |
| (...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1068 | 1071 |
| 1069 context->setShouldAntialias(true); | 1072 context->setShouldAntialias(true); |
| 1070 context->strokePath(path); | 1073 context->strokePath(path); |
| 1071 } | 1074 } |
| 1072 | 1075 |
| 1073 static bool shouldSetDecorationAntialias(TextDecorationStyle decorationStyle) | 1076 static bool shouldSetDecorationAntialias(TextDecorationStyle decorationStyle) |
| 1074 { | 1077 { |
| 1075 return decorationStyle == TextDecorationStyleDotted || decorationStyle == Te
xtDecorationStyleDashed; | 1078 return decorationStyle == TextDecorationStyleDotted || decorationStyle == Te
xtDecorationStyleDashed; |
| 1076 } | 1079 } |
| 1077 | 1080 |
| 1078 static bool shouldSetDecorationAntialias(TextDecorationStyle underline, TextDeco
rationStyle overline, TextDecorationStyle linethrough) | 1081 struct DecorationMetadata { |
| 1082 bool linesAreOpaque; |
| 1083 bool setDecorationAntialias; |
| 1084 |
| 1085 DecorationMetadata() |
| 1086 : linesAreOpaque(true) |
| 1087 , setDecorationAntialias(false) |
| 1088 { } |
| 1089 }; |
| 1090 |
| 1091 static DecorationMetadata getDecorationMetadata(RenderObject::ResolvedDecoration
Vector& decorations) |
| 1079 { | 1092 { |
| 1080 return shouldSetDecorationAntialias(underline) || shouldSetDecorationAntiali
as(overline) || shouldSetDecorationAntialias(linethrough); | 1093 DecorationMetadata metadata; |
| 1094 |
| 1095 for (size_t i = 0; i < decorations.size(); ++i) { |
| 1096 const RenderObject::ResolvedDecoration& decoration = decorations[i]; |
| 1097 metadata.linesAreOpaque &= (decoration.color.alpha() == 255); |
| 1098 metadata.setDecorationAntialias |= shouldSetDecorationAntialias(decorati
on.style); |
| 1099 } |
| 1100 |
| 1101 return metadata; |
| 1081 } | 1102 } |
| 1082 | 1103 |
| 1083 static void paintAppliedDecoration(GraphicsContext* context, FloatPoint start, f
loat width, float doubleOffset, int wavyOffsetFactor, | 1104 struct PaintAppliedDecorationData { |
| 1084 RenderObject::AppliedTextDecoration decoration, float thickness, bool antial
iasDecoration, bool isPrinting) | 1105 RenderStyle* style; |
| 1106 FloatPoint start; |
| 1107 float width; |
| 1108 float doubleOffset; |
| 1109 float thickness; |
| 1110 bool antialias; |
| 1111 bool isPrinting; |
| 1112 int baseline; |
| 1113 |
| 1114 PaintAppliedDecorationData() |
| 1115 : style(nullptr) |
| 1116 , width(0) |
| 1117 , doubleOffset(0) |
| 1118 , thickness(0) |
| 1119 , antialias(false) |
| 1120 , isPrinting(false) |
| 1121 , baseline(0) |
| 1122 { } |
| 1123 }; |
| 1124 |
| 1125 static void paintAppliedDecorationStyle(GraphicsContext* context, const RenderOb
ject::ResolvedDecoration& decoration, const PaintAppliedDecorationData& data, in
t wavyOffsetFactor) |
| 1085 { | 1126 { |
| 1086 context->setStrokeStyle(textDecorationStyleToStrokeStyle(decoration.style)); | 1127 context->setStrokeStyle(textDecorationStyleToStrokeStyle(decoration.style)); |
| 1087 context->setStrokeColor(decoration.color); | 1128 context->setStrokeColor(decoration.color); |
| 1088 | 1129 |
| 1089 switch (decoration.style) { | 1130 switch (decoration.style) { |
| 1090 case TextDecorationStyleWavy: | 1131 case TextDecorationStyleWavy: |
| 1091 strokeWavyTextDecoration(context, start + FloatPoint(0, doubleOffset * w
avyOffsetFactor), start + FloatPoint(width, doubleOffset * wavyOffsetFactor), th
ickness); | 1132 strokeWavyTextDecoration(context, data.start + FloatPoint(0, data.double
Offset * wavyOffsetFactor), data.start + FloatPoint(data.width, data.doubleOffse
t * wavyOffsetFactor), data.thickness); |
| 1092 break; | 1133 break; |
| 1093 case TextDecorationStyleDotted: | 1134 case TextDecorationStyleDotted: |
| 1094 case TextDecorationStyleDashed: | 1135 case TextDecorationStyleDashed: |
| 1095 context->setShouldAntialias(antialiasDecoration); | 1136 context->setShouldAntialias(data.antialias); |
| 1096 // Fall through | 1137 // Fall through |
| 1097 default: | 1138 default: |
| 1098 context->drawLineForText(start, width, isPrinting); | 1139 context->drawLineForText(data.start, data.width, data.isPrinting); |
| 1099 | 1140 |
| 1100 if (decoration.style == TextDecorationStyleDouble) | 1141 if (decoration.style == TextDecorationStyleDouble) |
| 1101 context->drawLineForText(start + FloatPoint(0, doubleOffset), width,
isPrinting); | 1142 context->drawLineForText(data.start + FloatPoint(0, data.doubleOffse
t), data.width, data.isPrinting); |
| 1102 } | 1143 } |
| 1103 } | 1144 } |
| 1104 | 1145 |
| 1105 void InlineTextBox::paintDecoration(GraphicsContext* context, const FloatPoint&
boxOrigin, TextDecoration deco, const ShadowList* shadowList) | 1146 void InlineTextBox::paintAppliedDecoration(GraphicsContext* context, const Rende
rObject::ResolvedDecoration& decoration, const PaintAppliedDecorationData& data) |
| 1147 { |
| 1148 PaintAppliedDecorationData outData = data; |
| 1149 int wavyOffsetFactor = 1; |
| 1150 |
| 1151 switch (decoration.line) { |
| 1152 case TextDecorationUnderline: |
| 1153 outData.start += FloatPoint(0, computeUnderlineOffset(data.style, data.t
hickness)); |
| 1154 break; |
| 1155 case TextDecorationOverline: |
| 1156 outData.doubleOffset *= -1; |
| 1157 break; |
| 1158 case TextDecorationLineThrough: |
| 1159 outData.start += FloatPoint(0, (2 * data.baseline / 3)); |
| 1160 wavyOffsetFactor = 0; |
| 1161 break; |
| 1162 default: |
| 1163 return; |
| 1164 } |
| 1165 |
| 1166 paintAppliedDecorationStyle(context, decoration, outData, wavyOffsetFactor); |
| 1167 } |
| 1168 |
| 1169 void InlineTextBox::paintDecoration(GraphicsContext* context, const FloatPoint&
boxOrigin, RenderStyle* styleToUse, const ShadowList* shadowList) |
| 1106 { | 1170 { |
| 1107 GraphicsContextStateSaver stateSaver(*context); | 1171 GraphicsContextStateSaver stateSaver(*context); |
| 1108 | 1172 |
| 1109 if (m_truncation == cFullTruncation) | 1173 if (m_truncation == cFullTruncation) |
| 1110 return; | 1174 return; |
| 1111 | 1175 |
| 1112 FloatPoint localOrigin = boxOrigin; | 1176 FloatPoint localOrigin = boxOrigin; |
| 1113 | 1177 |
| 1114 float width = m_logicalWidth; | 1178 float width = m_logicalWidth; |
| 1115 if (m_truncation != cNoTruncation) { | 1179 if (m_truncation != cNoTruncation) { |
| 1116 width = toRenderText(renderer()).width(m_start, m_truncation, textPos(),
isLeftToRightDirection() ? LTR : RTL, isFirstLineStyle()); | 1180 width = toRenderText(renderer()).width(m_start, m_truncation, textPos(),
isLeftToRightDirection() ? LTR : RTL, isFirstLineStyle()); |
| 1117 if (!isLeftToRightDirection()) | 1181 if (!isLeftToRightDirection()) |
| 1118 localOrigin.move(m_logicalWidth - width, 0); | 1182 localOrigin.move(m_logicalWidth - width, 0); |
| 1119 } | 1183 } |
| 1120 | 1184 |
| 1121 // Get the text decoration colors. | 1185 const Vector<AppliedTextDecoration>& decorations = styleToUse->appliedTextDe
corations(); |
| 1122 RenderObject::AppliedTextDecoration underline, overline, linethrough; | 1186 RenderObject::ResolvedDecorationVector resolvedDecorations; |
| 1123 | 1187 renderer().resolvedDecorations(isFirstLineStyle(), decorations, resolvedDeco
rations); |
| 1124 renderer().getTextDecorations(deco, underline, overline, linethrough, true); | |
| 1125 if (isFirstLineStyle()) | |
| 1126 renderer().getTextDecorations(deco, underline, overline, linethrough, tr
ue, true); | |
| 1127 | 1188 |
| 1128 // Use a special function for underlines to get the positioning exactly righ
t. | 1189 // Use a special function for underlines to get the positioning exactly righ
t. |
| 1129 bool isPrinting = textRenderer().document().printing(); | 1190 bool isPrinting = textRenderer().document().printing(); |
| 1130 | 1191 |
| 1131 bool linesAreOpaque = !isPrinting && (!(deco & TextDecorationUnderline) || u
nderline.color.alpha() == 255) && (!(deco & TextDecorationOverline) || overline.
color.alpha() == 255) && (!(deco & TextDecorationLineThrough) || linethrough.col
or.alpha() == 255); | 1192 DecorationMetadata metadata = getDecorationMetadata(resolvedDecorations); |
| 1132 | 1193 |
| 1133 RenderStyle* styleToUse = renderer().style(isFirstLineStyle()); | |
| 1134 int baseline = styleToUse->fontMetrics().ascent(); | 1194 int baseline = styleToUse->fontMetrics().ascent(); |
| 1135 | 1195 |
| 1136 size_t shadowCount = shadowList ? shadowList->shadows().size() : 0; | 1196 size_t shadowCount = shadowList ? shadowList->shadows().size() : 0; |
| 1137 // Set the thick of the line to be 10% (or something else ?)of the computed
font size and not less than 1px. | 1197 // Set the thick of the line to be 10% (or something else ?)of the computed
font size and not less than 1px. |
| 1138 // Using computedFontSize should take care of zoom as well. | 1198 // Using computedFontSize should take care of zoom as well. |
| 1139 | 1199 |
| 1140 // Update Underline thickness, in case we have Faulty Font Metrics calculati
ng underline thickness by old method. | 1200 // Update Underline thickness, in case we have Faulty Font Metrics calculati
ng underline thickness by old method. |
| 1141 float textDecorationThickness = styleToUse->fontMetrics().underlineThickness
(); | 1201 float textDecorationThickness = styleToUse->fontMetrics().underlineThickness
(); |
| 1142 int fontHeightInt = (int)(styleToUse->fontMetrics().floatHeight() + 0.5); | 1202 int fontHeightInt = (int)(styleToUse->fontMetrics().floatHeight() + 0.5); |
| 1143 if ((textDecorationThickness == 0.f) || (textDecorationThickness >= (fontHei
ghtInt >> 1))) | 1203 if ((textDecorationThickness == 0.f) || (textDecorationThickness >= (fontHei
ghtInt >> 1))) |
| 1144 textDecorationThickness = std::max(1.f, styleToUse->computedFontSize() /
10.f); | 1204 textDecorationThickness = std::max(1.f, styleToUse->computedFontSize() /
10.f); |
| 1145 | 1205 |
| 1146 context->setStrokeThickness(textDecorationThickness); | 1206 context->setStrokeThickness(textDecorationThickness); |
| 1147 | 1207 |
| 1148 bool antialiasDecoration = shouldSetDecorationAntialias(overline.style, unde
rline.style, linethrough.style) | 1208 bool antialiasDecoration = metadata.setDecorationAntialias && RenderBoxModel
Object::shouldAntialiasLines(context); |
| 1149 && RenderBoxModelObject::shouldAntialiasLines(context); | |
| 1150 | 1209 |
| 1151 float extraOffset = 0; | 1210 float extraOffset = 0; |
| 1152 if (!linesAreOpaque && shadowCount > 1) { | 1211 if ((!metadata.linesAreOpaque || isPrinting) && shadowCount > 1) { |
| 1153 FloatRect clipRect(localOrigin, FloatSize(width, baseline + 2)); | 1212 FloatRect clipRect(localOrigin, FloatSize(width, baseline + 2)); |
| 1154 for (size_t i = shadowCount; i--; ) { | 1213 for (size_t i = shadowCount; i--; ) { |
| 1155 const ShadowData& s = shadowList->shadows()[i]; | 1214 const ShadowData& s = shadowList->shadows()[i]; |
| 1156 FloatRect shadowRect(localOrigin, FloatSize(width, baseline + 2)); | 1215 FloatRect shadowRect(localOrigin, FloatSize(width, baseline + 2)); |
| 1157 shadowRect.inflate(s.blur()); | 1216 shadowRect.inflate(s.blur()); |
| 1158 float shadowX = isHorizontal() ? s.x() : s.y(); | 1217 float shadowX = isHorizontal() ? s.x() : s.y(); |
| 1159 float shadowY = isHorizontal() ? s.y() : -s.x(); | 1218 float shadowY = isHorizontal() ? s.y() : -s.x(); |
| 1160 shadowRect.move(shadowX, shadowY); | 1219 shadowRect.move(shadowX, shadowY); |
| 1161 clipRect.unite(shadowRect); | 1220 clipRect.unite(shadowRect); |
| 1162 extraOffset = max(extraOffset, max(0.0f, shadowY) + s.blur()); | 1221 extraOffset = max(extraOffset, max(0.0f, shadowY) + s.blur()); |
| (...skipping 10 matching lines...) Expand all Loading... |
| 1173 // The last set of lines paints normally inside the clip. | 1232 // The last set of lines paints normally inside the clip. |
| 1174 localOrigin.move(0, -extraOffset); | 1233 localOrigin.move(0, -extraOffset); |
| 1175 extraOffset = 0; | 1234 extraOffset = 0; |
| 1176 } | 1235 } |
| 1177 const ShadowData& shadow = shadowList->shadows()[i]; | 1236 const ShadowData& shadow = shadowList->shadows()[i]; |
| 1178 float shadowX = isHorizontal() ? shadow.x() : shadow.y(); | 1237 float shadowX = isHorizontal() ? shadow.x() : shadow.y(); |
| 1179 float shadowY = isHorizontal() ? shadow.y() : -shadow.x(); | 1238 float shadowY = isHorizontal() ? shadow.y() : -shadow.x(); |
| 1180 context->setShadow(FloatSize(shadowX, shadowY - extraOffset), shadow
.blur(), shadow.color()); | 1239 context->setShadow(FloatSize(shadowX, shadowY - extraOffset), shadow
.blur(), shadow.color()); |
| 1181 } | 1240 } |
| 1182 | 1241 |
| 1242 PaintAppliedDecorationData data; |
| 1243 data.style = styleToUse; |
| 1244 data.start = localOrigin; |
| 1245 data.width = width; |
| 1183 // Offset between lines - always non-zero, so lines never cross each oth
er. | 1246 // Offset between lines - always non-zero, so lines never cross each oth
er. |
| 1184 float doubleOffset = textDecorationThickness + 1.f; | 1247 data.doubleOffset = textDecorationThickness + 1.f; |
| 1248 data.thickness = textDecorationThickness; |
| 1249 data.antialias = antialiasDecoration; |
| 1250 data.isPrinting = isPrinting; |
| 1251 data.baseline = baseline; |
| 1185 | 1252 |
| 1186 if (deco & TextDecorationUnderline) { | 1253 for (auto decoration = resolvedDecorations.rbegin(); decoration != resol
vedDecorations.rend(); ++decoration) |
| 1187 const int underlineOffset = computeUnderlineOffset(styleToUse->textU
nderlinePosition(), styleToUse->fontMetrics(), this, textDecorationThickness); | 1254 paintAppliedDecoration(context, *decoration, data); |
| 1188 paintAppliedDecoration(context, localOrigin + FloatPoint(0, underlin
eOffset), width, doubleOffset, 1, underline, textDecorationThickness, antialiasD
ecoration, isPrinting); | |
| 1189 } | |
| 1190 if (deco & TextDecorationOverline) { | |
| 1191 paintAppliedDecoration(context, localOrigin, width, -doubleOffset, 1
, overline, textDecorationThickness, antialiasDecoration, isPrinting); | |
| 1192 } | |
| 1193 if (deco & TextDecorationLineThrough) { | |
| 1194 const float lineThroughOffset = 2 * baseline / 3; | |
| 1195 paintAppliedDecoration(context, localOrigin + FloatPoint(0, lineThro
ughOffset), width, doubleOffset, 0, linethrough, textDecorationThickness, antial
iasDecoration, isPrinting); | |
| 1196 } | |
| 1197 } | 1255 } |
| 1198 } | 1256 } |
| 1199 | 1257 |
| 1200 static GraphicsContext::DocumentMarkerLineStyle lineStyleForMarkerType(DocumentM
arker::MarkerType markerType) | 1258 static GraphicsContext::DocumentMarkerLineStyle lineStyleForMarkerType(DocumentM
arker::MarkerType markerType) |
| 1201 { | 1259 { |
| 1202 switch (markerType) { | 1260 switch (markerType) { |
| 1203 case DocumentMarker::Spelling: | 1261 case DocumentMarker::Spelling: |
| 1204 return GraphicsContext::DocumentMarkerSpellingLineStyle; | 1262 return GraphicsContext::DocumentMarkerSpellingLineStyle; |
| 1205 case DocumentMarker::Grammar: | 1263 case DocumentMarker::Grammar: |
| 1206 return GraphicsContext::DocumentMarkerGrammarLineStyle; | 1264 return GraphicsContext::DocumentMarkerGrammarLineStyle; |
| (...skipping 367 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1574 printedCharacters = fprintf(stderr, "\t%s %p", obj.renderName(), &obj); | 1632 printedCharacters = fprintf(stderr, "\t%s %p", obj.renderName(), &obj); |
| 1575 const int rendererCharacterOffset = 24; | 1633 const int rendererCharacterOffset = 24; |
| 1576 for (; printedCharacters < rendererCharacterOffset; printedCharacters++) | 1634 for (; printedCharacters < rendererCharacterOffset; printedCharacters++) |
| 1577 fputc(' ', stderr); | 1635 fputc(' ', stderr); |
| 1578 fprintf(stderr, "(%d,%d) \"%s\"\n", start(), start() + len(), value.utf8().d
ata()); | 1636 fprintf(stderr, "(%d,%d) \"%s\"\n", start(), start() + len(), value.utf8().d
ata()); |
| 1579 } | 1637 } |
| 1580 | 1638 |
| 1581 #endif | 1639 #endif |
| 1582 | 1640 |
| 1583 } // namespace WebCore | 1641 } // namespace WebCore |
| OLD | NEW |