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 738 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
749 context->concatCTM(rotation(boxRect, Counterclockwise)); | 749 context->concatCTM(rotation(boxRect, Counterclockwise)); |
750 } | 750 } |
751 } | 751 } |
752 | 752 |
753 // Paint decorations | 753 // Paint decorations |
754 TextDecoration textDecorations = styleToUse->textDecorationsInEffect(); | 754 TextDecoration textDecorations = styleToUse->textDecorationsInEffect(); |
755 if (textDecorations != TextDecorationNone && paintInfo.phase != PaintPhaseSe
lection) { | 755 if (textDecorations != TextDecorationNone && paintInfo.phase != PaintPhaseSe
lection) { |
756 updateGraphicsContext(context, textFillColor, textStrokeColor, textStrok
eWidth); | 756 updateGraphicsContext(context, textFillColor, textStrokeColor, textStrok
eWidth); |
757 if (combinedText) | 757 if (combinedText) |
758 context->concatCTM(rotation(boxRect, Clockwise)); | 758 context->concatCTM(rotation(boxRect, Clockwise)); |
759 paintDecoration(context, boxOrigin, textDecorations, styleToUse->textDec
orationStyle(), textShadow); | 759 paintDecoration(context, boxOrigin, textDecorations, textShadow); |
760 if (combinedText) | 760 if (combinedText) |
761 context->concatCTM(rotation(boxRect, Counterclockwise)); | 761 context->concatCTM(rotation(boxRect, Counterclockwise)); |
762 } | 762 } |
763 | 763 |
764 if (paintInfo.phase == PaintPhaseForeground) { | 764 if (paintInfo.phase == PaintPhaseForeground) { |
765 paintDocumentMarkers(context, boxOrigin, styleToUse, font, false); | 765 paintDocumentMarkers(context, boxOrigin, styleToUse, font, false); |
766 | 766 |
767 if (useCustomUnderlines) { | 767 if (useCustomUnderlines) { |
768 const Vector<CompositionUnderline>& underlines = renderer().frame()-
>inputMethodController().customCompositionUnderlines(); | 768 const Vector<CompositionUnderline>& underlines = renderer().frame()-
>inputMethodController().customCompositionUnderlines(); |
769 size_t numUnderlines = underlines.size(); | 769 size_t numUnderlines = underlines.size(); |
(...skipping 284 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1054 controlPoint2.setX(x + step); | 1054 controlPoint2.setX(x + step); |
1055 x += 2 * step; | 1055 x += 2 * step; |
1056 path.addBezierCurveTo(controlPoint1, controlPoint2, FloatPoint(x, yA
xis)); | 1056 path.addBezierCurveTo(controlPoint1, controlPoint2, FloatPoint(x, yA
xis)); |
1057 } | 1057 } |
1058 } | 1058 } |
1059 | 1059 |
1060 context->setShouldAntialias(true); | 1060 context->setShouldAntialias(true); |
1061 context->strokePath(path); | 1061 context->strokePath(path); |
1062 } | 1062 } |
1063 | 1063 |
1064 void InlineTextBox::paintDecoration(GraphicsContext* context, const FloatPoint&
boxOrigin, TextDecoration deco, TextDecorationStyle decorationStyle, const Shado
wList* shadowList) | 1064 static bool shouldSetDecorationAntialias(TextDecorationStyle decorationStyle) |
| 1065 { |
| 1066 return decorationStyle == TextDecorationStyleDotted || decorationStyle == Te
xtDecorationStyleDashed; |
| 1067 } |
| 1068 |
| 1069 static bool shouldSetDecorationAntialias(TextDecorationStyle underline, TextDeco
rationStyle overline, TextDecorationStyle linethrough) |
| 1070 { |
| 1071 return shouldSetDecorationAntialias(underline) || shouldSetDecorationAntiali
as(overline) || shouldSetDecorationAntialias(linethrough); |
| 1072 } |
| 1073 |
| 1074 void InlineTextBox::paintDecoration(GraphicsContext* context, const FloatPoint&
boxOrigin, TextDecoration deco, const ShadowList* shadowList) |
1065 { | 1075 { |
1066 GraphicsContextStateSaver stateSaver(*context); | 1076 GraphicsContextStateSaver stateSaver(*context); |
1067 | 1077 |
1068 if (m_truncation == cFullTruncation) | 1078 if (m_truncation == cFullTruncation) |
1069 return; | 1079 return; |
1070 | 1080 |
1071 FloatPoint localOrigin = boxOrigin; | 1081 FloatPoint localOrigin = boxOrigin; |
1072 | 1082 |
1073 float width = m_logicalWidth; | 1083 float width = m_logicalWidth; |
1074 if (m_truncation != cNoTruncation) { | 1084 if (m_truncation != cNoTruncation) { |
1075 width = toRenderText(renderer()).width(m_start, m_truncation, textPos(),
isLeftToRightDirection() ? LTR : RTL, isFirstLineStyle()); | 1085 width = toRenderText(renderer()).width(m_start, m_truncation, textPos(),
isLeftToRightDirection() ? LTR : RTL, isFirstLineStyle()); |
1076 if (!isLeftToRightDirection()) | 1086 if (!isLeftToRightDirection()) |
1077 localOrigin.move(m_logicalWidth - width, 0); | 1087 localOrigin.move(m_logicalWidth - width, 0); |
1078 } | 1088 } |
1079 | 1089 |
1080 // Get the text decoration colors. | 1090 // Get the text decoration colors. |
1081 Color underline(Color::transparent), overline(Color::transparent), linethrou
gh(Color::transparent); | 1091 RenderObject::AppliedTextDecoration underline, overline, linethrough; |
1082 renderer().getTextDecorationColors(deco, underline, overline, linethrough, t
rue); | 1092 |
| 1093 renderer().getTextDecorations(deco, underline, overline, linethrough, true); |
1083 if (isFirstLineStyle()) | 1094 if (isFirstLineStyle()) |
1084 renderer().getTextDecorationColors(deco, underline, overline, linethroug
h, true, true); | 1095 renderer().getTextDecorations(deco, underline, overline, linethrough, tr
ue, true); |
1085 | 1096 |
1086 // Use a special function for underlines to get the positioning exactly righ
t. | 1097 // Use a special function for underlines to get the positioning exactly righ
t. |
1087 bool isPrinting = textRenderer().document().printing(); | 1098 bool isPrinting = textRenderer().document().printing(); |
1088 | 1099 |
1089 bool linesAreOpaque = !isPrinting && (!(deco & TextDecorationUnderline) || u
nderline.alpha() == 255) && (!(deco & TextDecorationOverline) || overline.alpha(
) == 255) && (!(deco & TextDecorationLineThrough) || linethrough.alpha() == 255)
; | 1100 bool linesAreOpaque = !isPrinting && (!(deco & TextDecorationUnderline) || u
nderline.color.alpha() == 255) && (!(deco & TextDecorationOverline) || overline.
color.alpha() == 255) && (!(deco & TextDecorationLineThrough) || linethrough.col
or.alpha() == 255); |
1090 | 1101 |
1091 RenderStyle* styleToUse = renderer().style(isFirstLineStyle()); | 1102 RenderStyle* styleToUse = renderer().style(isFirstLineStyle()); |
1092 int baseline = styleToUse->fontMetrics().ascent(); | 1103 int baseline = styleToUse->fontMetrics().ascent(); |
1093 | 1104 |
1094 size_t shadowCount = shadowList ? shadowList->shadows().size() : 0; | 1105 size_t shadowCount = shadowList ? shadowList->shadows().size() : 0; |
1095 // Set the thick of the line to be 10% (or something else ?)of the computed
font size and not less than 1px. | 1106 // Set the thick of the line to be 10% (or something else ?)of the computed
font size and not less than 1px. |
1096 // Using computedFontSize should take care of zoom as well. | 1107 // Using computedFontSize should take care of zoom as well. |
1097 | 1108 |
1098 // Update Underline thickness, in case we have Faulty Font Metrics calculati
ng underline thickness by old method. | 1109 // Update Underline thickness, in case we have Faulty Font Metrics calculati
ng underline thickness by old method. |
1099 float textDecorationThickness = styleToUse->fontMetrics().underlineThickness
(); | 1110 float textDecorationThickness = styleToUse->fontMetrics().underlineThickness
(); |
1100 int fontHeightInt = (int)(styleToUse->fontMetrics().floatHeight() + 0.5); | 1111 int fontHeightInt = (int)(styleToUse->fontMetrics().floatHeight() + 0.5); |
1101 if ((textDecorationThickness == 0.f) || (textDecorationThickness >= (fontHei
ghtInt >> 1))) | 1112 if ((textDecorationThickness == 0.f) || (textDecorationThickness >= (fontHei
ghtInt >> 1))) |
1102 textDecorationThickness = std::max(1.f, styleToUse->computedFontSize() /
10.f); | 1113 textDecorationThickness = std::max(1.f, styleToUse->computedFontSize() /
10.f); |
1103 | 1114 |
1104 context->setStrokeThickness(textDecorationThickness); | 1115 context->setStrokeThickness(textDecorationThickness); |
1105 | 1116 |
1106 switch (decorationStyle) { | 1117 bool antialiasDecoration = shouldSetDecorationAntialias(overline.style, unde
rline.style, linethrough.style) |
1107 case TextDecorationStyleDotted: | 1118 && RenderBoxModelObject::shouldAntialiasLines(context); |
1108 case TextDecorationStyleDashed: | |
1109 context->setShouldAntialias(RenderBoxModelObject::shouldAntialiasLines(c
ontext)); | |
1110 break; | |
1111 case TextDecorationStyleSolid: | |
1112 case TextDecorationStyleDouble: | |
1113 case TextDecorationStyleWavy: | |
1114 break; | |
1115 } | |
1116 | 1119 |
1117 float extraOffset = 0; | 1120 float extraOffset = 0; |
1118 if (!linesAreOpaque && shadowCount > 1) { | 1121 if (!linesAreOpaque && shadowCount > 1) { |
1119 FloatRect clipRect(localOrigin, FloatSize(width, baseline + 2)); | 1122 FloatRect clipRect(localOrigin, FloatSize(width, baseline + 2)); |
1120 for (size_t i = shadowCount; i--; ) { | 1123 for (size_t i = shadowCount; i--; ) { |
1121 const ShadowData& s = shadowList->shadows()[i]; | 1124 const ShadowData& s = shadowList->shadows()[i]; |
1122 FloatRect shadowRect(localOrigin, FloatSize(width, baseline + 2)); | 1125 FloatRect shadowRect(localOrigin, FloatSize(width, baseline + 2)); |
1123 shadowRect.inflate(s.blur()); | 1126 shadowRect.inflate(s.blur()); |
1124 float shadowX = isHorizontal() ? s.x() : s.y(); | 1127 float shadowX = isHorizontal() ? s.x() : s.y(); |
1125 float shadowY = isHorizontal() ? s.y() : -s.x(); | 1128 float shadowY = isHorizontal() ? s.y() : -s.x(); |
(...skipping 15 matching lines...) Expand all Loading... |
1141 extraOffset = 0; | 1144 extraOffset = 0; |
1142 } | 1145 } |
1143 const ShadowData& shadow = shadowList->shadows()[i]; | 1146 const ShadowData& shadow = shadowList->shadows()[i]; |
1144 float shadowX = isHorizontal() ? shadow.x() : shadow.y(); | 1147 float shadowX = isHorizontal() ? shadow.x() : shadow.y(); |
1145 float shadowY = isHorizontal() ? shadow.y() : -shadow.x(); | 1148 float shadowY = isHorizontal() ? shadow.y() : -shadow.x(); |
1146 context->setShadow(FloatSize(shadowX, shadowY - extraOffset), shadow
.blur(), shadow.color()); | 1149 context->setShadow(FloatSize(shadowX, shadowY - extraOffset), shadow
.blur(), shadow.color()); |
1147 } | 1150 } |
1148 | 1151 |
1149 // Offset between lines - always non-zero, so lines never cross each oth
er. | 1152 // Offset between lines - always non-zero, so lines never cross each oth
er. |
1150 float doubleOffset = textDecorationThickness + 1.f; | 1153 float doubleOffset = textDecorationThickness + 1.f; |
1151 context->setStrokeStyle(textDecorationStyleToStrokeStyle(decorationStyle
)); | 1154 |
1152 if (deco & TextDecorationUnderline) { | 1155 if (deco & TextDecorationUnderline) { |
1153 context->setStrokeColor(underline); | 1156 context->setStrokeStyle(textDecorationStyleToStrokeStyle(underline.s
tyle)); |
| 1157 context->setStrokeColor(underline.color); |
1154 const int underlineOffset = computeUnderlineOffset(styleToUse->textU
nderlinePosition(), styleToUse->fontMetrics(), this, textDecorationThickness); | 1158 const int underlineOffset = computeUnderlineOffset(styleToUse->textU
nderlinePosition(), styleToUse->fontMetrics(), this, textDecorationThickness); |
1155 switch (decorationStyle) { | 1159 switch (underline.style) { |
1156 case TextDecorationStyleWavy: { | 1160 case TextDecorationStyleWavy: { |
1157 FloatPoint start(localOrigin.x(), localOrigin.y() + underlineOff
set + doubleOffset); | 1161 FloatPoint start(localOrigin.x(), localOrigin.y() + underlineOff
set + doubleOffset); |
1158 FloatPoint end(localOrigin.x() + width, localOrigin.y() + underl
ineOffset + doubleOffset); | 1162 FloatPoint end(localOrigin.x() + width, localOrigin.y() + underl
ineOffset + doubleOffset); |
1159 strokeWavyTextDecoration(context, start, end, textDecorationThic
kness); | 1163 strokeWavyTextDecoration(context, start, end, textDecorationThic
kness); |
1160 break; | 1164 break; |
1161 } | 1165 } |
| 1166 case TextDecorationStyleDotted: |
| 1167 case TextDecorationStyleDashed: |
| 1168 context->setShouldAntialias(antialiasDecoration); |
| 1169 // Fall through |
| 1170 case TextDecorationStyleDouble: |
| 1171 context->drawLineForText(FloatPoint(localOrigin.x(), localOrigin
.y() + underlineOffset + doubleOffset), width, isPrinting); |
| 1172 // Fall through |
1162 default: | 1173 default: |
1163 context->drawLineForText(FloatPoint(localOrigin.x(), localOrigin
.y() + underlineOffset), width, isPrinting); | 1174 context->drawLineForText(FloatPoint(localOrigin.x(), localOrigin
.y() + underlineOffset), width, isPrinting); |
1164 | |
1165 if (decorationStyle == TextDecorationStyleDouble) | |
1166 context->drawLineForText(FloatPoint(localOrigin.x(), localOr
igin.y() + underlineOffset + doubleOffset), width, isPrinting); | |
1167 } | 1175 } |
1168 } | 1176 } |
1169 if (deco & TextDecorationOverline) { | 1177 if (deco & TextDecorationOverline) { |
1170 context->setStrokeColor(overline); | 1178 context->setStrokeStyle(textDecorationStyleToStrokeStyle(overline.st
yle)); |
1171 switch (decorationStyle) { | 1179 context->setStrokeColor(overline.color); |
| 1180 switch (overline.style) { |
1172 case TextDecorationStyleWavy: { | 1181 case TextDecorationStyleWavy: { |
1173 FloatPoint start(localOrigin.x(), localOrigin.y() - doubleOffset
); | 1182 FloatPoint start(localOrigin.x(), localOrigin.y() - doubleOffset
); |
1174 FloatPoint end(localOrigin.x() + width, localOrigin.y() - double
Offset); | 1183 FloatPoint end(localOrigin.x() + width, localOrigin.y() - double
Offset); |
1175 strokeWavyTextDecoration(context, start, end, textDecorationThic
kness); | 1184 strokeWavyTextDecoration(context, start, end, textDecorationThic
kness); |
1176 break; | 1185 break; |
1177 } | 1186 } |
| 1187 case TextDecorationStyleDotted: |
| 1188 case TextDecorationStyleDashed: |
| 1189 context->setShouldAntialias(antialiasDecoration); |
| 1190 // Fall through |
| 1191 case TextDecorationStyleDouble: |
| 1192 context->drawLineForText(FloatPoint(localOrigin.x(), localOrigin
.y() - doubleOffset), width, isPrinting); |
| 1193 // Fall through |
1178 default: | 1194 default: |
1179 context->drawLineForText(localOrigin, width, isPrinting); | 1195 context->drawLineForText(localOrigin, width, isPrinting); |
1180 if (decorationStyle == TextDecorationStyleDouble) | |
1181 context->drawLineForText(FloatPoint(localOrigin.x(), localOr
igin.y() - doubleOffset), width, isPrinting); | |
1182 } | 1196 } |
1183 } | 1197 } |
1184 if (deco & TextDecorationLineThrough) { | 1198 if (deco & TextDecorationLineThrough) { |
1185 context->setStrokeColor(linethrough); | 1199 context->setStrokeStyle(textDecorationStyleToStrokeStyle(linethrough
.style)); |
1186 switch (decorationStyle) { | 1200 context->setStrokeColor(linethrough.color); |
| 1201 switch (linethrough.style) { |
1187 case TextDecorationStyleWavy: { | 1202 case TextDecorationStyleWavy: { |
1188 FloatPoint start(localOrigin.x(), localOrigin.y() + 2 * baseline
/ 3); | 1203 FloatPoint start(localOrigin.x(), localOrigin.y() + 2 * baseline
/ 3); |
1189 FloatPoint end(localOrigin.x() + width, localOrigin.y() + 2 * ba
seline / 3); | 1204 FloatPoint end(localOrigin.x() + width, localOrigin.y() + 2 * ba
seline / 3); |
1190 strokeWavyTextDecoration(context, start, end, textDecorationThic
kness); | 1205 strokeWavyTextDecoration(context, start, end, textDecorationThic
kness); |
1191 break; | 1206 break; |
1192 } | 1207 } |
| 1208 case TextDecorationStyleDotted: |
| 1209 case TextDecorationStyleDashed: |
| 1210 context->setShouldAntialias(antialiasDecoration); |
| 1211 // Fall through |
| 1212 case TextDecorationStyleDouble: |
| 1213 context->drawLineForText(FloatPoint(localOrigin.x(), localOrigin
.y() + doubleOffset + 2 * baseline / 3), width, isPrinting); |
| 1214 // Fall through |
1193 default: | 1215 default: |
1194 context->drawLineForText(FloatPoint(localOrigin.x(), localOrigin
.y() + 2 * baseline / 3), width, isPrinting); | 1216 context->drawLineForText(FloatPoint(localOrigin.x(), localOrigin
.y() + 2 * baseline / 3), width, isPrinting); |
1195 if (decorationStyle == TextDecorationStyleDouble) | |
1196 context->drawLineForText(FloatPoint(localOrigin.x(), localOr
igin.y() + doubleOffset + 2 * baseline / 3), width, isPrinting); | |
1197 } | 1217 } |
1198 } | 1218 } |
1199 } | 1219 } |
1200 } | 1220 } |
1201 | 1221 |
1202 static GraphicsContext::DocumentMarkerLineStyle lineStyleForMarkerType(DocumentM
arker::MarkerType markerType) | 1222 static GraphicsContext::DocumentMarkerLineStyle lineStyleForMarkerType(DocumentM
arker::MarkerType markerType) |
1203 { | 1223 { |
1204 switch (markerType) { | 1224 switch (markerType) { |
1205 case DocumentMarker::Spelling: | 1225 case DocumentMarker::Spelling: |
1206 return GraphicsContext::DocumentMarkerSpellingLineStyle; | 1226 return GraphicsContext::DocumentMarkerSpellingLineStyle; |
(...skipping 369 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1576 printedCharacters = fprintf(stderr, "\t%s %p", obj.renderName(), &obj); | 1596 printedCharacters = fprintf(stderr, "\t%s %p", obj.renderName(), &obj); |
1577 const int rendererCharacterOffset = 24; | 1597 const int rendererCharacterOffset = 24; |
1578 for (; printedCharacters < rendererCharacterOffset; printedCharacters++) | 1598 for (; printedCharacters < rendererCharacterOffset; printedCharacters++) |
1579 fputc(' ', stderr); | 1599 fputc(' ', stderr); |
1580 fprintf(stderr, "(%d,%d) \"%s\"\n", start(), start() + len(), value.utf8().d
ata()); | 1600 fprintf(stderr, "(%d,%d) \"%s\"\n", start(), start() + len(), value.utf8().d
ata()); |
1581 } | 1601 } |
1582 | 1602 |
1583 #endif | 1603 #endif |
1584 | 1604 |
1585 } // namespace WebCore | 1605 } // namespace WebCore |
OLD | NEW |