| 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 |