Chromium Code Reviews| 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 778 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 789 | 789 |
| 790 // Each Bezier curve starts at the same pixel that the previous one | 790 // Each Bezier curve starts at the same pixel that the previous one |
| 791 // ended. We need to subtract (stepCount - 1) pixels when calculating the | 791 // ended. We need to subtract (stepCount - 1) pixels when calculating the |
| 792 // length covered to account for that. | 792 // length covered to account for that. |
| 793 float uncoveredLength = length - (stepCount * step - (stepCount - 1)); | 793 float uncoveredLength = length - (stepCount * step - (stepCount - 1)); |
| 794 float adjustment = uncoveredLength / stepCount; | 794 float adjustment = uncoveredLength / stepCount; |
| 795 step += adjustment; | 795 step += adjustment; |
| 796 controlPointDistance += adjustment; | 796 controlPointDistance += adjustment; |
| 797 } | 797 } |
| 798 | 798 |
| 799 struct CurveAlongX { | |
| 800 static inline float y(FloatPoint p) { return p.y(); } | |
| 801 static inline float x(FloatPoint p) { return p.x(); } | |
| 802 static inline FloatPoint p(float x, float y) { return FloatPoint(x, y); } | |
| 803 static inline void setX(FloatPoint& p, double x) { p.setX(x); } | |
|
abarth-chromium
2015/06/19 23:00:46
const FloatPoint& for y, x, and setX.
(Also, I wo
| |
| 804 }; | |
| 805 | |
| 806 struct CurveAlongY { | |
| 807 static inline float y(FloatPoint p) { return p.x(); } | |
| 808 static inline float x(FloatPoint p) { return p.y(); } | |
| 809 static inline FloatPoint p(float x, float y) { return FloatPoint(y, x); } | |
| 810 static inline void setX(FloatPoint& p, double x) { p.setY(x); } | |
|
abarth-chromium
2015/06/19 23:00:45
ditto
| |
| 811 }; | |
| 812 | |
| 799 /* | 813 /* |
| 800 * Draw one cubic Bezier curve and repeat the same pattern long the the decorati on's axis. | 814 * Draw one cubic Bezier curve and repeat the same pattern along the |
| 801 * The start point (p1), controlPoint1, controlPoint2 and end point (p2) of the Bezier curve | 815 * the decoration's axis. The start point (p1), controlPoint1, |
| 802 * form a diamond shape: | 816 * controlPoint2 and end point (p2) of the Bezier curve form a diamond |
| 817 * shape, as follows (the four points marked +): | |
| 803 * | 818 * |
| 804 * step | 819 * step |
| 805 * |-----------| | 820 * |-----------| |
| 806 * | 821 * |
| 807 * controlPoint1 | 822 * controlPoint1 |
| 808 * + | 823 * + |
| 809 * | 824 * |
| 810 * | 825 * |
| 811 * . . | 826 * . . |
| 812 * . . | 827 * . . |
| 813 * . . | 828 * . . |
| 814 * (x1, y1) p1 + . + p2 (x2, y2) - <--- Decoration's axis | 829 * (x1, y1) p1 + . + p2 (x2, y2) - <--- Decoration's axis |
| 815 * . . | | 830 * . . | |
| 816 * . . | | 831 * . . | |
| 817 * . . | controlPointDistance | 832 * . . | controlPointDistance |
| 818 * | | 833 * | |
| 819 * | | 834 * | |
| 820 * + - | 835 * + - |
| 821 * controlPoint2 | 836 * controlPoint2 |
| 822 * | 837 * |
| 823 * |-----------| | 838 * |-----------| |
| 824 * step | 839 * step |
| 840 * | |
| 841 * strokeWavyTextDecorationInternal() takes two points, p1 and p2. | |
| 842 * These must be axis-aligned. If they are horizontally-aligned, | |
| 843 * specialize it with CurveAlongX; if they are vertically aligned, | |
| 844 * specialize it with CurveAlongY. The function is written as if it | |
| 845 * was doing everything along the X axis; CurveAlongY just flips the | |
| 846 * coordinates around. | |
| 825 */ | 847 */ |
| 826 static void strokeWavyTextDecoration(GraphicsContext* context, FloatPoint p1, Fl oatPoint p2, float strokeThickness) | 848 template <class T> static void strokeWavyTextDecorationInternal(GraphicsContext* context, FloatPoint p1, FloatPoint p2, float strokeThickness) |
|
abarth-chromium
2015/06/19 23:00:45
s/T/Curve/ for readability.
| |
| 827 { | 849 { |
| 850 ASSERT(T::y(p1) == T::y(p2)); // verify that this is indeed axis-aligned | |
| 851 | |
| 828 context->adjustLineToPixelBoundaries(p1, p2, strokeThickness, context->strok eStyle()); | 852 context->adjustLineToPixelBoundaries(p1, p2, strokeThickness, context->strok eStyle()); |
| 829 | 853 |
| 830 Path path; | 854 Path path; |
| 831 path.moveTo(p1); | 855 path.moveTo(p1); |
| 832 | 856 |
| 833 // Distance between decoration's axis and Bezier curve's control points. | 857 float controlPointDistance = 2 * strokeThickness; |
| 834 // The height of the curve is based on this distance. Use a minimum of 6 pix els distance since | 858 float step = controlPointDistance; |
| 835 // the actual curve passes approximately at half of that distance, that is 3 pixels. | |
| 836 // The minimum height of the curve is also approximately 3 pixels. Increases the curve's height | |
| 837 // as strockThickness increases to make the curve looks better. | |
| 838 float controlPointDistance = 3 * std::max<float>(2, strokeThickness); | |
| 839 | 859 |
| 840 // Increment used to form the diamond shape between start point (p1), contro l | 860 float yAxis = T::y(p1); |
| 841 // points and end point (p2) along the axis of the decoration. Makes the | 861 float x1; |
| 842 // curve wider as strockThickness increases to make the curve looks better. | 862 float x2; |
| 843 float step = 2 * std::max<float>(2, strokeThickness); | |
| 844 | 863 |
| 845 bool isVerticalLine = (p1.x() == p2.x()); | 864 if (T::x(p1) < T::x(p2)) { |
| 865 x1 = T::x(p1); | |
| 866 x2 = T::x(p2); | |
|
abarth-chromium
2015/06/19 23:00:45
Should we give these more semantic names, like |ma
| |
| 867 } else { | |
| 868 x1 = T::x(p2); | |
| 869 x2 = T::x(p1); | |
| 870 } | |
| 846 | 871 |
| 847 if (isVerticalLine) { | 872 adjustStepToDecorationLength(step, controlPointDistance, x2 - x1); |
| 848 ASSERT(p1.x() == p2.x()); | |
| 849 | 873 |
| 850 float xAxis = p1.x(); | 874 FloatPoint controlPoint1 = T::p(0, yAxis + controlPointDistance); |
| 851 float y1; | 875 FloatPoint controlPoint2 = T::p(0, yAxis - controlPointDistance); |
| 852 float y2; | |
| 853 | 876 |
| 854 if (p1.y() < p2.y()) { | 877 for (float x = x1; x + 2 * step <= x2;) { |
| 855 y1 = p1.y(); | 878 T::setX(controlPoint1, x + step); |
| 856 y2 = p2.y(); | 879 T::setX(controlPoint2, x + step); |
| 857 } else { | 880 x += 2 * step; |
| 858 y1 = p2.y(); | 881 path.addBezierCurveTo(controlPoint1, controlPoint2, T::p(x, yAxis)); |
| 859 y2 = p1.y(); | |
| 860 } | |
| 861 | |
| 862 adjustStepToDecorationLength(step, controlPointDistance, y2 - y1); | |
| 863 FloatPoint controlPoint1(xAxis + controlPointDistance, 0); | |
| 864 FloatPoint controlPoint2(xAxis - controlPointDistance, 0); | |
| 865 | |
| 866 for (float y = y1; y + 2 * step <= y2;) { | |
| 867 controlPoint1.setY(y + step); | |
| 868 controlPoint2.setY(y + step); | |
| 869 y += 2 * step; | |
| 870 path.addBezierCurveTo(controlPoint1, controlPoint2, FloatPoint(xAxis , y)); | |
| 871 } | |
| 872 } else { | |
| 873 ASSERT(p1.y() == p2.y()); | |
| 874 | |
| 875 float yAxis = p1.y(); | |
| 876 float x1; | |
| 877 float x2; | |
| 878 | |
| 879 if (p1.x() < p2.x()) { | |
| 880 x1 = p1.x(); | |
| 881 x2 = p2.x(); | |
| 882 } else { | |
| 883 x1 = p2.x(); | |
| 884 x2 = p1.x(); | |
| 885 } | |
| 886 | |
| 887 adjustStepToDecorationLength(step, controlPointDistance, x2 - x1); | |
| 888 FloatPoint controlPoint1(0, yAxis + controlPointDistance); | |
| 889 FloatPoint controlPoint2(0, yAxis - controlPointDistance); | |
| 890 | |
| 891 for (float x = x1; x + 2 * step <= x2;) { | |
| 892 controlPoint1.setX(x + step); | |
| 893 controlPoint2.setX(x + step); | |
| 894 x += 2 * step; | |
| 895 path.addBezierCurveTo(controlPoint1, controlPoint2, FloatPoint(x, yA xis)); | |
| 896 } | |
| 897 } | 882 } |
| 898 | 883 |
| 899 context->setShouldAntialias(true); | 884 context->setShouldAntialias(true); |
| 900 context->strokePath(path); | 885 context->strokePath(path); |
| 901 } | 886 } |
| 902 | 887 |
| 888 static void strokeWavyTextDecoration(GraphicsContext* context, FloatPoint p1, Fl oatPoint p2, float strokeThickness) | |
| 889 { | |
| 890 if (p1.y() == p2.y()) // horizontal line | |
| 891 strokeWavyTextDecorationInternal<CurveAlongX>(context, p1, p2, strokeThick ness); | |
| 892 else // vertical line | |
| 893 strokeWavyTextDecorationInternal<CurveAlongY>(context, p1, p2, strokeThick ness); | |
| 894 } | |
| 895 | |
| 903 static bool shouldSetDecorationAntialias(TextDecorationStyle decorationStyle) | 896 static bool shouldSetDecorationAntialias(TextDecorationStyle decorationStyle) |
| 904 { | 897 { |
| 905 return decorationStyle == TextDecorationStyleDotted || decorationStyle == Te xtDecorationStyleDashed; | 898 return decorationStyle == TextDecorationStyleDotted || decorationStyle == Te xtDecorationStyleDashed; |
| 906 } | 899 } |
| 907 | 900 |
| 908 static bool shouldSetDecorationAntialias(TextDecorationStyle underline, TextDeco rationStyle overline, TextDecorationStyle linethrough) | 901 static bool shouldSetDecorationAntialias(TextDecorationStyle underline, TextDeco rationStyle overline, TextDecorationStyle linethrough) |
| 909 { | 902 { |
| 910 return shouldSetDecorationAntialias(underline) || shouldSetDecorationAntiali as(overline) || shouldSetDecorationAntialias(linethrough); | 903 return shouldSetDecorationAntialias(underline) || shouldSetDecorationAntiali as(overline) || shouldSetDecorationAntialias(linethrough); |
| 911 } | 904 } |
| 912 | 905 |
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 955 renderer().getTextDecorations(deco, underline, overline, linethrough, tr ue, true); | 948 renderer().getTextDecorations(deco, underline, overline, linethrough, tr ue, true); |
| 956 | 949 |
| 957 // Use a special function for underlines to get the positioning exactly righ t. | 950 // Use a special function for underlines to get the positioning exactly righ t. |
| 958 | 951 |
| 959 RenderStyle* styleToUse = renderer().style(isFirstLineStyle()); | 952 RenderStyle* styleToUse = renderer().style(isFirstLineStyle()); |
| 960 int baseline = styleToUse->fontMetrics().ascent(); | 953 int baseline = styleToUse->fontMetrics().ascent(); |
| 961 | 954 |
| 962 // Set the thick of the line to be 10% (or something else ?)of the computed font size and not less than 1px. | 955 // Set the thick of the line to be 10% (or something else ?)of the computed font size and not less than 1px. |
| 963 | 956 |
| 964 // Update Underline thickness, in case we have Faulty Font Metrics calculati ng underline thickness by old method. | 957 // Update Underline thickness, in case we have Faulty Font Metrics calculati ng underline thickness by old method. |
| 965 float textDecorationThickness = styleToUse->fontMetrics().underlineThickness (); | 958 float textDecorationThickness = styleToUse->fontMetrics().underlineThickness (); // TODO(ianh): Make this author-controllable |
| 966 int fontHeightInt = (int)(styleToUse->fontMetrics().floatHeight() + 0.5); | 959 int fontHeightInt = (int)(styleToUse->fontMetrics().floatHeight() + 0.5); |
| 967 if ((textDecorationThickness == 0.f) || (textDecorationThickness >= (fontHei ghtInt >> 1))) | 960 if ((textDecorationThickness == 0.f) || (textDecorationThickness >= (fontHei ghtInt >> 1))) |
| 968 textDecorationThickness = std::max(1.f, styleToUse->computedFontSize() / 10.f); | 961 textDecorationThickness = std::max(1.f, styleToUse->computedFontSize() / 10.f); |
| 969 | 962 |
| 970 context->setStrokeThickness(textDecorationThickness); | 963 context->setStrokeThickness(textDecorationThickness); |
| 971 | 964 |
| 972 bool antialiasDecoration = shouldSetDecorationAntialias(overline.style, unde rline.style, linethrough.style) | 965 bool antialiasDecoration = shouldSetDecorationAntialias(overline.style, unde rline.style, linethrough.style) |
| 973 && RenderBoxModelObject::shouldAntialiasLines(context); | 966 && RenderBoxModelObject::shouldAntialiasLines(context); |
| 974 | 967 |
| 975 // Offset between lines - always non-zero, so lines never cross each other. | 968 // Offset between lines - always non-zero, so lines never cross each other. |
| (...skipping 359 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1335 printedCharacters = fprintf(stderr, "\t%s %p", obj.renderName(), &obj); | 1328 printedCharacters = fprintf(stderr, "\t%s %p", obj.renderName(), &obj); |
| 1336 const int rendererCharacterOffset = 24; | 1329 const int rendererCharacterOffset = 24; |
| 1337 for (; printedCharacters < rendererCharacterOffset; printedCharacters++) | 1330 for (; printedCharacters < rendererCharacterOffset; printedCharacters++) |
| 1338 fputc(' ', stderr); | 1331 fputc(' ', stderr); |
| 1339 fprintf(stderr, "(%d,%d) \"%s\"\n", start(), start() + len(), value.utf8().d ata()); | 1332 fprintf(stderr, "(%d,%d) \"%s\"\n", start(), start() + len(), value.utf8().d ata()); |
| 1340 } | 1333 } |
| 1341 | 1334 |
| 1342 #endif | 1335 #endif |
| 1343 | 1336 |
| 1344 } // namespace blink | 1337 } // namespace blink |
| OLD | NEW |