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 |