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 904 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
915 context->drawHighlightForText(font, constructTextRun(style, font), localOrig
in, selHeight, c, style->colorSpace(), sPos, ePos); | 915 context->drawHighlightForText(font, constructTextRun(style, font), localOrig
in, selHeight, c, style->colorSpace(), sPos, ePos); |
916 } | 916 } |
917 | 917 |
918 static StrokeStyle textDecorationStyleToStrokeStyle(TextDecorationStyle decorati
onStyle) | 918 static StrokeStyle textDecorationStyleToStrokeStyle(TextDecorationStyle decorati
onStyle) |
919 { | 919 { |
920 StrokeStyle strokeStyle = SolidStroke; | 920 StrokeStyle strokeStyle = SolidStroke; |
921 switch (decorationStyle) { | 921 switch (decorationStyle) { |
922 case TextDecorationStyleSolid: | 922 case TextDecorationStyleSolid: |
923 strokeStyle = SolidStroke; | 923 strokeStyle = SolidStroke; |
924 break; | 924 break; |
925 #if ENABLE(CSS3_TEXT) | |
926 case TextDecorationStyleDouble: | 925 case TextDecorationStyleDouble: |
927 strokeStyle = DoubleStroke; | 926 strokeStyle = DoubleStroke; |
928 break; | 927 break; |
929 case TextDecorationStyleDotted: | 928 case TextDecorationStyleDotted: |
930 strokeStyle = DottedStroke; | 929 strokeStyle = DottedStroke; |
931 break; | 930 break; |
932 case TextDecorationStyleDashed: | 931 case TextDecorationStyleDashed: |
933 strokeStyle = DashedStroke; | 932 strokeStyle = DashedStroke; |
934 break; | 933 break; |
935 case TextDecorationStyleWavy: | 934 case TextDecorationStyleWavy: |
936 strokeStyle = WavyStroke; | 935 strokeStyle = WavyStroke; |
937 break; | 936 break; |
938 #endif // CSS3_TEXT | |
939 } | 937 } |
940 | 938 |
941 return strokeStyle; | 939 return strokeStyle; |
942 } | 940 } |
943 | 941 |
944 #if ENABLE(CSS3_TEXT) | |
945 static int computeUnderlineOffset(const TextUnderlinePosition underlinePosition,
const FontMetrics& fontMetrics, const InlineTextBox* inlineTextBox, const int t
extDecorationThickness) | 942 static int computeUnderlineOffset(const TextUnderlinePosition underlinePosition,
const FontMetrics& fontMetrics, const InlineTextBox* inlineTextBox, const int t
extDecorationThickness) |
946 { | 943 { |
947 // Compute the gap between the font and the underline. Use at least one | 944 // Compute the gap between the font and the underline. Use at least one |
948 // pixel gap, if underline is thick then use a bigger gap. | 945 // pixel gap, if underline is thick then use a bigger gap. |
949 const int gap = max<int>(1, ceilf(textDecorationThickness / 2.0)); | 946 const int gap = max<int>(1, ceilf(textDecorationThickness / 2.0)); |
950 | 947 |
951 // According to the specification TextUnderlinePositionAuto should default t
o 'alphabetic' for horizontal text | 948 // According to the specification TextUnderlinePositionAuto should default t
o 'alphabetic' for horizontal text |
952 // and to 'under Left' for vertical text (e.g. japanese). We support only ho
rizontal text for now. | 949 // and to 'under Left' for vertical text (e.g. japanese). We support only ho
rizontal text for now. |
953 switch (underlinePosition) { | 950 switch (underlinePosition) { |
954 case TextUnderlinePositionAlphabetic: | 951 case TextUnderlinePositionAlphabetic: |
955 case TextUnderlinePositionAuto: | 952 case TextUnderlinePositionAuto: |
956 return fontMetrics.ascent() + gap; // Position underline near the alphab
etic baseline. | 953 return fontMetrics.ascent() + gap; // Position underline near the alphab
etic baseline. |
957 case TextUnderlinePositionUnder: { | 954 case TextUnderlinePositionUnder: { |
958 // Position underline relative to the under edge of the lowest element's
content box. | 955 // Position underline relative to the under edge of the lowest element's
content box. |
959 const float offset = inlineTextBox->root()->maxLogicalTop() - inlineText
Box->logicalTop(); | 956 const float offset = inlineTextBox->root()->maxLogicalTop() - inlineText
Box->logicalTop(); |
960 if (offset > 0) | 957 if (offset > 0) |
961 return inlineTextBox->logicalHeight() + gap + offset; | 958 return inlineTextBox->logicalHeight() + gap + offset; |
962 return inlineTextBox->logicalHeight() + gap; | 959 return inlineTextBox->logicalHeight() + gap; |
963 } | 960 } |
964 } | 961 } |
965 | 962 |
966 ASSERT_NOT_REACHED(); | 963 ASSERT_NOT_REACHED(); |
967 return fontMetrics.ascent() + gap; | 964 return fontMetrics.ascent() + gap; |
968 } | 965 } |
969 #endif // CSS3_TEXT | |
970 | 966 |
971 #if ENABLE(CSS3_TEXT) | |
972 static void adjustStepToDecorationLength(float& step, float& controlPointDistanc
e, float length) | 967 static void adjustStepToDecorationLength(float& step, float& controlPointDistanc
e, float length) |
973 { | 968 { |
974 ASSERT(step > 0); | 969 ASSERT(step > 0); |
975 | 970 |
976 if (length <= 0) | 971 if (length <= 0) |
977 return; | 972 return; |
978 | 973 |
979 unsigned stepCount = static_cast<unsigned>(length / step); | 974 unsigned stepCount = static_cast<unsigned>(length / step); |
980 | 975 |
981 // Each Bezier curve starts at the same pixel that the previous one | 976 // Each Bezier curve starts at the same pixel that the previous one |
(...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1083 controlPoint1.setX(x + step); | 1078 controlPoint1.setX(x + step); |
1084 controlPoint2.setX(x + step); | 1079 controlPoint2.setX(x + step); |
1085 x += 2 * step; | 1080 x += 2 * step; |
1086 path.addBezierCurveTo(controlPoint1, controlPoint2, FloatPoint(x, yA
xis)); | 1081 path.addBezierCurveTo(controlPoint1, controlPoint2, FloatPoint(x, yA
xis)); |
1087 } | 1082 } |
1088 } | 1083 } |
1089 | 1084 |
1090 context->setShouldAntialias(true); | 1085 context->setShouldAntialias(true); |
1091 context->strokePath(path); | 1086 context->strokePath(path); |
1092 } | 1087 } |
1093 #endif // CSS3_TEXT | |
1094 | 1088 |
1095 void InlineTextBox::paintDecoration(GraphicsContext* context, const FloatPoint&
boxOrigin, ETextDecoration deco, TextDecorationStyle decorationStyle, const Shad
owData* shadow) | 1089 void InlineTextBox::paintDecoration(GraphicsContext* context, const FloatPoint&
boxOrigin, ETextDecoration deco, TextDecorationStyle decorationStyle, const Shad
owData* shadow) |
1096 { | 1090 { |
1097 // FIXME: We should improve this rule and not always just assume 1. | 1091 // FIXME: We should improve this rule and not always just assume 1. |
1098 const float textDecorationThickness = 1.f; | 1092 const float textDecorationThickness = 1.f; |
1099 | 1093 |
1100 if (m_truncation == cFullTruncation) | 1094 if (m_truncation == cFullTruncation) |
1101 return; | 1095 return; |
1102 | 1096 |
1103 FloatPoint localOrigin = boxOrigin; | 1097 FloatPoint localOrigin = boxOrigin; |
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1154 localOrigin.move(0, -extraOffset); | 1148 localOrigin.move(0, -extraOffset); |
1155 extraOffset = 0; | 1149 extraOffset = 0; |
1156 } | 1150 } |
1157 int shadowX = isHorizontal() ? shadow->x() : shadow->y(); | 1151 int shadowX = isHorizontal() ? shadow->x() : shadow->y(); |
1158 int shadowY = isHorizontal() ? shadow->y() : -shadow->x(); | 1152 int shadowY = isHorizontal() ? shadow->y() : -shadow->x(); |
1159 context->setShadow(FloatSize(shadowX, shadowY - extraOffset), shadow
->blur(), shadow->color(), colorSpace); | 1153 context->setShadow(FloatSize(shadowX, shadowY - extraOffset), shadow
->blur(), shadow->color(), colorSpace); |
1160 setShadow = true; | 1154 setShadow = true; |
1161 shadow = shadow->next(); | 1155 shadow = shadow->next(); |
1162 } | 1156 } |
1163 | 1157 |
1164 #if ENABLE(CSS3_TEXT) | |
1165 // Offset between lines - always non-zero, so lines never cross each oth
er. | 1158 // Offset between lines - always non-zero, so lines never cross each oth
er. |
1166 float doubleOffset = textDecorationThickness + 1.f; | 1159 float doubleOffset = textDecorationThickness + 1.f; |
1167 #endif // CSS3_TEXT | |
1168 context->setStrokeStyle(textDecorationStyleToStrokeStyle(decorationStyle
)); | 1160 context->setStrokeStyle(textDecorationStyleToStrokeStyle(decorationStyle
)); |
1169 if (deco & UNDERLINE) { | 1161 if (deco & UNDERLINE) { |
1170 context->setStrokeColor(underline, colorSpace); | 1162 context->setStrokeColor(underline, colorSpace); |
1171 #if ENABLE(CSS3_TEXT) | |
1172 TextUnderlinePosition underlinePosition = styleToUse->textUnderlineP
osition(); | 1163 TextUnderlinePosition underlinePosition = styleToUse->textUnderlineP
osition(); |
1173 const int underlineOffset = computeUnderlineOffset(underlinePosition
, styleToUse->fontMetrics(), this, textDecorationThickness); | 1164 const int underlineOffset = computeUnderlineOffset(underlinePosition
, styleToUse->fontMetrics(), this, textDecorationThickness); |
1174 | 1165 |
1175 switch (decorationStyle) { | 1166 switch (decorationStyle) { |
1176 case TextDecorationStyleWavy: { | 1167 case TextDecorationStyleWavy: { |
1177 FloatPoint start(localOrigin.x(), localOrigin.y() + underlineOff
set + doubleOffset); | 1168 FloatPoint start(localOrigin.x(), localOrigin.y() + underlineOff
set + doubleOffset); |
1178 FloatPoint end(localOrigin.x() + width, localOrigin.y() + underl
ineOffset + doubleOffset); | 1169 FloatPoint end(localOrigin.x() + width, localOrigin.y() + underl
ineOffset + doubleOffset); |
1179 strokeWavyTextDecoration(context, start, end, textDecorationThic
kness); | 1170 strokeWavyTextDecoration(context, start, end, textDecorationThic
kness); |
1180 break; | 1171 break; |
1181 } | 1172 } |
1182 default: | 1173 default: |
1183 context->drawLineForText(FloatPoint(localOrigin.x(), localOrigin
.y() + underlineOffset), width, isPrinting); | 1174 context->drawLineForText(FloatPoint(localOrigin.x(), localOrigin
.y() + underlineOffset), width, isPrinting); |
1184 | 1175 |
1185 if (decorationStyle == TextDecorationStyleDouble) | 1176 if (decorationStyle == TextDecorationStyleDouble) |
1186 context->drawLineForText(FloatPoint(localOrigin.x(), localOr
igin.y() + underlineOffset + doubleOffset), width, isPrinting); | 1177 context->drawLineForText(FloatPoint(localOrigin.x(), localOr
igin.y() + underlineOffset + doubleOffset), width, isPrinting); |
1187 } | 1178 } |
1188 #else | |
1189 // Leave one pixel of white between the baseline and the underline. | |
1190 context->drawLineForText(FloatPoint(localOrigin.x(), localOrigin.y()
+ baseline + 1), width, isPrinting); | |
1191 #endif // CSS3_TEXT | |
1192 } | 1179 } |
1193 if (deco & OVERLINE) { | 1180 if (deco & OVERLINE) { |
1194 context->setStrokeColor(overline, colorSpace); | 1181 context->setStrokeColor(overline, colorSpace); |
1195 #if ENABLE(CSS3_TEXT) | |
1196 switch (decorationStyle) { | 1182 switch (decorationStyle) { |
1197 case TextDecorationStyleWavy: { | 1183 case TextDecorationStyleWavy: { |
1198 FloatPoint start(localOrigin.x(), localOrigin.y() - doubleOffset
); | 1184 FloatPoint start(localOrigin.x(), localOrigin.y() - doubleOffset
); |
1199 FloatPoint end(localOrigin.x() + width, localOrigin.y() - double
Offset); | 1185 FloatPoint end(localOrigin.x() + width, localOrigin.y() - double
Offset); |
1200 strokeWavyTextDecoration(context, start, end, textDecorationThic
kness); | 1186 strokeWavyTextDecoration(context, start, end, textDecorationThic
kness); |
1201 break; | 1187 break; |
1202 } | 1188 } |
1203 default: | 1189 default: |
1204 #endif // CSS3_TEXT | |
1205 context->drawLineForText(localOrigin, width, isPrinting); | 1190 context->drawLineForText(localOrigin, width, isPrinting); |
1206 #if ENABLE(CSS3_TEXT) | |
1207 if (decorationStyle == TextDecorationStyleDouble) | 1191 if (decorationStyle == TextDecorationStyleDouble) |
1208 context->drawLineForText(FloatPoint(localOrigin.x(), localOr
igin.y() - doubleOffset), width, isPrinting); | 1192 context->drawLineForText(FloatPoint(localOrigin.x(), localOr
igin.y() - doubleOffset), width, isPrinting); |
1209 } | 1193 } |
1210 #endif // CSS3_TEXT | |
1211 } | 1194 } |
1212 if (deco & LINE_THROUGH) { | 1195 if (deco & LINE_THROUGH) { |
1213 context->setStrokeColor(linethrough, colorSpace); | 1196 context->setStrokeColor(linethrough, colorSpace); |
1214 #if ENABLE(CSS3_TEXT) | |
1215 switch (decorationStyle) { | 1197 switch (decorationStyle) { |
1216 case TextDecorationStyleWavy: { | 1198 case TextDecorationStyleWavy: { |
1217 FloatPoint start(localOrigin.x(), localOrigin.y() + 2 * baseline
/ 3); | 1199 FloatPoint start(localOrigin.x(), localOrigin.y() + 2 * baseline
/ 3); |
1218 FloatPoint end(localOrigin.x() + width, localOrigin.y() + 2 * ba
seline / 3); | 1200 FloatPoint end(localOrigin.x() + width, localOrigin.y() + 2 * ba
seline / 3); |
1219 strokeWavyTextDecoration(context, start, end, textDecorationThic
kness); | 1201 strokeWavyTextDecoration(context, start, end, textDecorationThic
kness); |
1220 break; | 1202 break; |
1221 } | 1203 } |
1222 default: | 1204 default: |
1223 #endif // CSS3_TEXT | |
1224 context->drawLineForText(FloatPoint(localOrigin.x(), localOrigin
.y() + 2 * baseline / 3), width, isPrinting); | 1205 context->drawLineForText(FloatPoint(localOrigin.x(), localOrigin
.y() + 2 * baseline / 3), width, isPrinting); |
1225 #if ENABLE(CSS3_TEXT) | |
1226 if (decorationStyle == TextDecorationStyleDouble) | 1206 if (decorationStyle == TextDecorationStyleDouble) |
1227 context->drawLineForText(FloatPoint(localOrigin.x(), localOr
igin.y() + doubleOffset + 2 * baseline / 3), width, isPrinting); | 1207 context->drawLineForText(FloatPoint(localOrigin.x(), localOr
igin.y() + doubleOffset + 2 * baseline / 3), width, isPrinting); |
1228 } | 1208 } |
1229 #endif // CSS3_TEXT | |
1230 } | 1209 } |
1231 } while (shadow); | 1210 } while (shadow); |
1232 | 1211 |
1233 if (setClip) | 1212 if (setClip) |
1234 context->restore(); | 1213 context->restore(); |
1235 else if (setShadow) | 1214 else if (setShadow) |
1236 context->clearShadow(); | 1215 context->clearShadow(); |
1237 } | 1216 } |
1238 | 1217 |
1239 static GraphicsContext::DocumentMarkerLineStyle lineStyleForMarkerType(DocumentM
arker::MarkerType markerType) | 1218 static GraphicsContext::DocumentMarkerLineStyle lineStyleForMarkerType(DocumentM
arker::MarkerType markerType) |
(...skipping 384 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1624 | 1603 |
1625 void InlineTextBox::reportMemoryUsage(MemoryObjectInfo* memoryObjectInfo) const | 1604 void InlineTextBox::reportMemoryUsage(MemoryObjectInfo* memoryObjectInfo) const |
1626 { | 1605 { |
1627 MemoryClassInfo info(memoryObjectInfo, this, WebCoreMemoryTypes::Rendering); | 1606 MemoryClassInfo info(memoryObjectInfo, this, WebCoreMemoryTypes::Rendering); |
1628 InlineBox::reportMemoryUsage(memoryObjectInfo); | 1607 InlineBox::reportMemoryUsage(memoryObjectInfo); |
1629 info.addMember(m_prevTextBox, "prevTextBox"); | 1608 info.addMember(m_prevTextBox, "prevTextBox"); |
1630 info.addMember(m_nextTextBox, "nextTextBox"); | 1609 info.addMember(m_nextTextBox, "nextTextBox"); |
1631 } | 1610 } |
1632 | 1611 |
1633 } // namespace WebCore | 1612 } // namespace WebCore |
OLD | NEW |