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 898 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
909 strokeStyle = DashedStroke; | 909 strokeStyle = DashedStroke; |
910 break; | 910 break; |
911 case TextDecorationStyleWavy: | 911 case TextDecorationStyleWavy: |
912 strokeStyle = WavyStroke; | 912 strokeStyle = WavyStroke; |
913 break; | 913 break; |
914 } | 914 } |
915 | 915 |
916 return strokeStyle; | 916 return strokeStyle; |
917 } | 917 } |
918 | 918 |
919 #if ENABLE(CSS3_TEXT) | 919 static int computeUnderlineOffset(const TextUnderlinePosition underlinePosition,
const FontMetrics& fontMetrics, const InlineTextBox* inlineTextBox, const float
textDecorationThickness) |
920 static int computeUnderlineOffset(const TextUnderlinePosition underlinePosition,
const FontMetrics& fontMetrics, const InlineTextBox* inlineTextBox, const int t
extDecorationThickness) | |
921 { | 920 { |
922 // Compute the gap between the font and the underline. Use at least one | 921 // Compute the gap between the font and the underline. Use at least one |
923 // pixel gap, if underline is thick then use a bigger gap. | 922 // pixel gap, if underline is thick then use a bigger gap. |
924 const int gap = max<int>(1, ceilf(textDecorationThickness / 2.0)); | 923 const int gap = std::max<int>(1, ceilf(textDecorationThickness / 2.f)); |
925 | 924 |
926 // According to the specification TextUnderlinePositionAuto should default t
o 'alphabetic' for horizontal text | 925 // According to the specification TextUnderlinePositionAuto should default t
o 'alphabetic' for horizontal text |
927 // and to 'under Left' for vertical text (e.g. japanese). We support only ho
rizontal text for now. | 926 // and to 'under Left' for vertical text (e.g. japanese). We support only ho
rizontal text for now. |
928 switch (underlinePosition) { | 927 switch (underlinePosition) { |
929 case TextUnderlinePositionAlphabetic: | 928 case TextUnderlinePositionAlphabetic: |
930 case TextUnderlinePositionAuto: | 929 case TextUnderlinePositionAuto: |
931 return fontMetrics.ascent() + gap; // Position underline near the alphab
etic baseline. | 930 return fontMetrics.ascent() + gap; // Position underline near the alphab
etic baseline. |
932 case TextUnderlinePositionUnder: { | 931 case TextUnderlinePositionUnder: { |
933 // Position underline relative to the under edge of the lowest element's
content box. | 932 // Position underline relative to the under edge of the lowest element's
content box. |
934 const float offset = inlineTextBox->root()->maxLogicalTop() - inlineText
Box->logicalTop(); | 933 const float offset = inlineTextBox->root()->maxLogicalTop() - inlineText
Box->logicalTop(); |
935 if (offset > 0) | 934 if (offset > 0) |
936 return inlineTextBox->logicalHeight() + gap + offset; | 935 return inlineTextBox->logicalHeight() + gap + offset; |
937 return inlineTextBox->logicalHeight() + gap; | 936 return inlineTextBox->logicalHeight() + gap; |
938 } | 937 } |
939 } | 938 } |
940 | 939 |
941 ASSERT_NOT_REACHED(); | 940 ASSERT_NOT_REACHED(); |
942 return fontMetrics.ascent() + gap; | 941 return fontMetrics.ascent() + gap; |
943 } | 942 } |
944 #endif // CSS3_TEXT | |
945 | 943 |
946 static void adjustStepToDecorationLength(float& step, float& controlPointDistanc
e, float length) | 944 static void adjustStepToDecorationLength(float& step, float& controlPointDistanc
e, float length) |
947 { | 945 { |
948 ASSERT(step > 0); | 946 ASSERT(step > 0); |
949 | 947 |
950 if (length <= 0) | 948 if (length <= 0) |
951 return; | 949 return; |
952 | 950 |
953 unsigned stepCount = static_cast<unsigned>(length / step); | 951 unsigned stepCount = static_cast<unsigned>(length / step); |
954 | 952 |
(...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1062 } | 1060 } |
1063 | 1061 |
1064 context->setShouldAntialias(true); | 1062 context->setShouldAntialias(true); |
1065 context->strokePath(path); | 1063 context->strokePath(path); |
1066 } | 1064 } |
1067 | 1065 |
1068 void InlineTextBox::paintDecoration(GraphicsContext* context, const FloatPoint&
boxOrigin, TextDecoration deco, TextDecorationStyle decorationStyle, const Shado
wList* shadowList) | 1066 void InlineTextBox::paintDecoration(GraphicsContext* context, const FloatPoint&
boxOrigin, TextDecoration deco, TextDecorationStyle decorationStyle, const Shado
wList* shadowList) |
1069 { | 1067 { |
1070 GraphicsContextStateSaver stateSaver(*context); | 1068 GraphicsContextStateSaver stateSaver(*context); |
1071 | 1069 |
1072 float textDecorationThickness = 1.f; | |
1073 | |
1074 if (m_truncation == cFullTruncation) | 1070 if (m_truncation == cFullTruncation) |
1075 return; | 1071 return; |
1076 | 1072 |
1077 FloatPoint localOrigin = boxOrigin; | 1073 FloatPoint localOrigin = boxOrigin; |
1078 | 1074 |
1079 float width = m_logicalWidth; | 1075 float width = m_logicalWidth; |
1080 if (m_truncation != cNoTruncation) { | 1076 if (m_truncation != cNoTruncation) { |
1081 width = toRenderText(renderer())->width(m_start, m_truncation, textPos()
, isFirstLineStyle()); | 1077 width = toRenderText(renderer())->width(m_start, m_truncation, textPos()
, isFirstLineStyle()); |
1082 if (!isLeftToRightDirection()) | 1078 if (!isLeftToRightDirection()) |
1083 localOrigin.move(m_logicalWidth - width, 0); | 1079 localOrigin.move(m_logicalWidth - width, 0); |
1084 } | 1080 } |
1085 | 1081 |
1086 // Get the text decoration colors. | 1082 // Get the text decoration colors. |
1087 Color underline, overline, linethrough; | 1083 Color underline, overline, linethrough; |
1088 renderer()->getTextDecorationColors(deco, underline, overline, linethrough,
true); | 1084 renderer()->getTextDecorationColors(deco, underline, overline, linethrough,
true); |
1089 if (isFirstLineStyle()) | 1085 if (isFirstLineStyle()) |
1090 renderer()->getTextDecorationColors(deco, underline, overline, linethrou
gh, true, true); | 1086 renderer()->getTextDecorationColors(deco, underline, overline, linethrou
gh, true, true); |
1091 | 1087 |
1092 // Use a special function for underlines to get the positioning exactly righ
t. | 1088 // Use a special function for underlines to get the positioning exactly righ
t. |
1093 bool isPrinting = textRenderer()->document().printing(); | 1089 bool isPrinting = textRenderer()->document().printing(); |
1094 | 1090 |
1095 bool linesAreOpaque = !isPrinting && (!(deco & TextDecorationUnderline) || u
nderline.alpha() == 255) && (!(deco & TextDecorationOverline) || overline.alpha(
) == 255) && (!(deco & TextDecorationLineThrough) || linethrough.alpha() == 255)
; | 1091 bool linesAreOpaque = !isPrinting && (!(deco & TextDecorationUnderline) || u
nderline.alpha() == 255) && (!(deco & TextDecorationOverline) || overline.alpha(
) == 255) && (!(deco & TextDecorationLineThrough) || linethrough.alpha() == 255)
; |
1096 | 1092 |
1097 RenderStyle* styleToUse = renderer()->style(isFirstLineStyle()); | 1093 RenderStyle* styleToUse = renderer()->style(isFirstLineStyle()); |
1098 int baseline = styleToUse->fontMetrics().ascent(); | 1094 int baseline = styleToUse->fontMetrics().ascent(); |
1099 | 1095 |
1100 size_t shadowCount = shadowList ? shadowList->shadows().size() : 0; | 1096 size_t shadowCount = shadowList ? shadowList->shadows().size() : 0; |
1101 // Set the thick of the line to be 10% (or something else ?)of the computed
font size and not less than 1px. | 1097 // Set the thick of the line to be 10% (or something else ?)of the computed
font size and not less than 1px. |
1102 // Using computedFontSize should take care of zoom as well. | 1098 // Using computedFontSize should take care of zoom as well. |
1103 textDecorationThickness = max(textDecorationThickness, styleToUse->computedF
ontSize() / 10.0f); | 1099 const float textDecorationThickness = std::max(1.f, styleToUse->computedFont
Size() / 10.f); |
1104 context->setStrokeThickness(textDecorationThickness); | 1100 context->setStrokeThickness(textDecorationThickness); |
1105 | 1101 |
1106 int extraOffset = 0; | 1102 int extraOffset = 0; |
1107 if (!linesAreOpaque && shadowCount > 1) { | 1103 if (!linesAreOpaque && shadowCount > 1) { |
1108 FloatRect clipRect(localOrigin, FloatSize(width, baseline + 2)); | 1104 FloatRect clipRect(localOrigin, FloatSize(width, baseline + 2)); |
1109 for (size_t i = shadowCount; i--; ) { | 1105 for (size_t i = shadowCount; i--; ) { |
1110 const ShadowData& s = shadowList->shadows()[i]; | 1106 const ShadowData& s = shadowList->shadows()[i]; |
1111 FloatRect shadowRect(localOrigin, FloatSize(width, baseline + 2)); | 1107 FloatRect shadowRect(localOrigin, FloatSize(width, baseline + 2)); |
1112 shadowRect.inflate(s.blur()); | 1108 shadowRect.inflate(s.blur()); |
1113 int shadowX = isHorizontal() ? s.x() : s.y(); | 1109 int shadowX = isHorizontal() ? s.x() : s.y(); |
(...skipping 19 matching lines...) Expand all Loading... |
1133 int shadowX = isHorizontal() ? shadow.x() : shadow.y(); | 1129 int shadowX = isHorizontal() ? shadow.x() : shadow.y(); |
1134 int shadowY = isHorizontal() ? shadow.y() : -shadow.x(); | 1130 int shadowY = isHorizontal() ? shadow.y() : -shadow.x(); |
1135 context->setShadow(FloatSize(shadowX, shadowY - extraOffset), shadow
.blur(), shadow.color()); | 1131 context->setShadow(FloatSize(shadowX, shadowY - extraOffset), shadow
.blur(), shadow.color()); |
1136 } | 1132 } |
1137 | 1133 |
1138 // Offset between lines - always non-zero, so lines never cross each oth
er. | 1134 // Offset between lines - always non-zero, so lines never cross each oth
er. |
1139 float doubleOffset = textDecorationThickness + 1.f; | 1135 float doubleOffset = textDecorationThickness + 1.f; |
1140 context->setStrokeStyle(textDecorationStyleToStrokeStyle(decorationStyle
)); | 1136 context->setStrokeStyle(textDecorationStyleToStrokeStyle(decorationStyle
)); |
1141 if (deco & TextDecorationUnderline) { | 1137 if (deco & TextDecorationUnderline) { |
1142 context->setStrokeColor(underline); | 1138 context->setStrokeColor(underline); |
1143 #if ENABLE(CSS3_TEXT) | 1139 const int underlineOffset = computeUnderlineOffset(styleToUse->textU
nderlinePosition(), styleToUse->fontMetrics(), this, textDecorationThickness); |
1144 TextUnderlinePosition underlinePosition = styleToUse->textUnderlineP
osition(); | |
1145 const int underlineOffset = computeUnderlineOffset(underlinePosition
, styleToUse->fontMetrics(), this, textDecorationThickness); | |
1146 #else | |
1147 const int underlineOffset = styleToUse->fontMetrics().ascent() + max
<int>(1, ceilf(textDecorationThickness / 2.0)); | |
1148 #endif // CSS3_TEXT | |
1149 | |
1150 switch (decorationStyle) { | 1140 switch (decorationStyle) { |
1151 case TextDecorationStyleWavy: { | 1141 case TextDecorationStyleWavy: { |
1152 FloatPoint start(localOrigin.x(), localOrigin.y() + underlineOff
set + doubleOffset); | 1142 FloatPoint start(localOrigin.x(), localOrigin.y() + underlineOff
set + doubleOffset); |
1153 FloatPoint end(localOrigin.x() + width, localOrigin.y() + underl
ineOffset + doubleOffset); | 1143 FloatPoint end(localOrigin.x() + width, localOrigin.y() + underl
ineOffset + doubleOffset); |
1154 strokeWavyTextDecoration(context, start, end, textDecorationThic
kness); | 1144 strokeWavyTextDecoration(context, start, end, textDecorationThic
kness); |
1155 break; | 1145 break; |
1156 } | 1146 } |
1157 default: | 1147 default: |
1158 context->drawLineForText(FloatPoint(localOrigin.x(), localOrigin
.y() + underlineOffset), width, isPrinting); | 1148 context->drawLineForText(FloatPoint(localOrigin.x(), localOrigin
.y() + underlineOffset), width, isPrinting); |
1159 | 1149 |
(...skipping 417 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1577 printedCharacters = fprintf(stderr, "\t%s %p", obj->renderName(), obj); | 1567 printedCharacters = fprintf(stderr, "\t%s %p", obj->renderName(), obj); |
1578 const int rendererCharacterOffset = 24; | 1568 const int rendererCharacterOffset = 24; |
1579 for (; printedCharacters < rendererCharacterOffset; printedCharacters++) | 1569 for (; printedCharacters < rendererCharacterOffset; printedCharacters++) |
1580 fputc(' ', stderr); | 1570 fputc(' ', stderr); |
1581 fprintf(stderr, "(%d,%d) \"%s\"\n", start(), start() + len(), value.utf8().d
ata()); | 1571 fprintf(stderr, "(%d,%d) \"%s\"\n", start(), start() + len(), value.utf8().d
ata()); |
1582 } | 1572 } |
1583 | 1573 |
1584 #endif | 1574 #endif |
1585 | 1575 |
1586 } // namespace WebCore | 1576 } // namespace WebCore |
OLD | NEW |