Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(54)

Side by Side Diff: Source/core/rendering/InlineTextBox.cpp

Issue 40733004: Replace compile flag with runtime check for text-underline-position (Closed) Base URL: svn://svn.chromium.org/blink/trunk
Patch Set: Julien's review #2 (rebased) Created 7 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « Source/core/rendering/InlineFlowBox.cpp ('k') | Source/core/rendering/RootInlineBox.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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
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
OLDNEW
« no previous file with comments | « Source/core/rendering/InlineFlowBox.cpp ('k') | Source/core/rendering/RootInlineBox.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698