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