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

Side by Side Diff: sky/engine/core/rendering/InlineTextBox.cpp

Issue 1201503003: Turn on wavy underlines. The waves aren't very pretty yet (they are too short somehow), I'll fix th… (Closed) Base URL: https://github.com/domokit/mojo.git@master
Patch Set: Created 5 years, 6 months 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
« no previous file with comments | « no previous file | sky/engine/platform/RuntimeEnabledFeatures.in » ('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 778 matching lines...) Expand 10 before | Expand all | Expand 10 after
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
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
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
OLDNEW
« no previous file with comments | « no previous file | sky/engine/platform/RuntimeEnabledFeatures.in » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698