Chromium Code Reviews| Index: sky/engine/core/rendering/InlineTextBox.cpp |
| diff --git a/sky/engine/core/rendering/InlineTextBox.cpp b/sky/engine/core/rendering/InlineTextBox.cpp |
| index 3132df88be7b7b532de198962c128f8e9521b601..feb203950d1c68cb494bc86bf40aeb6f37b78684 100644 |
| --- a/sky/engine/core/rendering/InlineTextBox.cpp |
| +++ b/sky/engine/core/rendering/InlineTextBox.cpp |
| @@ -796,10 +796,25 @@ static void adjustStepToDecorationLength(float& step, float& controlPointDistanc |
| controlPointDistance += adjustment; |
| } |
| +struct CurveAlongX { |
| + static inline float y(FloatPoint p) { return p.y(); } |
| + static inline float x(FloatPoint p) { return p.x(); } |
| + static inline FloatPoint p(float x, float y) { return FloatPoint(x, y); } |
| + 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
|
| +}; |
| + |
| +struct CurveAlongY { |
| + static inline float y(FloatPoint p) { return p.x(); } |
| + static inline float x(FloatPoint p) { return p.y(); } |
| + static inline FloatPoint p(float x, float y) { return FloatPoint(y, x); } |
| + static inline void setX(FloatPoint& p, double x) { p.setY(x); } |
|
abarth-chromium
2015/06/19 23:00:45
ditto
|
| +}; |
| + |
| /* |
| - * Draw one cubic Bezier curve and repeat the same pattern long the the decoration's axis. |
| - * The start point (p1), controlPoint1, controlPoint2 and end point (p2) of the Bezier curve |
| - * form a diamond shape: |
| + * Draw one cubic Bezier curve and repeat the same pattern along the |
| + * the decoration's axis. The start point (p1), controlPoint1, |
| + * controlPoint2 and end point (p2) of the Bezier curve form a diamond |
| + * shape, as follows (the four points marked +): |
| * |
| * step |
| * |-----------| |
| @@ -822,84 +837,62 @@ static void adjustStepToDecorationLength(float& step, float& controlPointDistanc |
| * |
| * |-----------| |
| * step |
| + * |
| + * strokeWavyTextDecorationInternal() takes two points, p1 and p2. |
| + * These must be axis-aligned. If they are horizontally-aligned, |
| + * specialize it with CurveAlongX; if they are vertically aligned, |
| + * specialize it with CurveAlongY. The function is written as if it |
| + * was doing everything along the X axis; CurveAlongY just flips the |
| + * coordinates around. |
| */ |
| -static void strokeWavyTextDecoration(GraphicsContext* context, FloatPoint p1, FloatPoint p2, float strokeThickness) |
| +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.
|
| { |
| + ASSERT(T::y(p1) == T::y(p2)); // verify that this is indeed axis-aligned |
| + |
| context->adjustLineToPixelBoundaries(p1, p2, strokeThickness, context->strokeStyle()); |
| Path path; |
| path.moveTo(p1); |
| - // Distance between decoration's axis and Bezier curve's control points. |
| - // The height of the curve is based on this distance. Use a minimum of 6 pixels distance since |
| - // the actual curve passes approximately at half of that distance, that is 3 pixels. |
| - // The minimum height of the curve is also approximately 3 pixels. Increases the curve's height |
| - // as strockThickness increases to make the curve looks better. |
| - float controlPointDistance = 3 * std::max<float>(2, strokeThickness); |
| - |
| - // Increment used to form the diamond shape between start point (p1), control |
| - // points and end point (p2) along the axis of the decoration. Makes the |
| - // curve wider as strockThickness increases to make the curve looks better. |
| - float step = 2 * std::max<float>(2, strokeThickness); |
| - |
| - bool isVerticalLine = (p1.x() == p2.x()); |
| - |
| - if (isVerticalLine) { |
| - ASSERT(p1.x() == p2.x()); |
| - |
| - float xAxis = p1.x(); |
| - float y1; |
| - float y2; |
| - |
| - if (p1.y() < p2.y()) { |
| - y1 = p1.y(); |
| - y2 = p2.y(); |
| - } else { |
| - y1 = p2.y(); |
| - y2 = p1.y(); |
| - } |
| + float controlPointDistance = 2 * strokeThickness; |
| + float step = controlPointDistance; |
| - adjustStepToDecorationLength(step, controlPointDistance, y2 - y1); |
| - FloatPoint controlPoint1(xAxis + controlPointDistance, 0); |
| - FloatPoint controlPoint2(xAxis - controlPointDistance, 0); |
| + float yAxis = T::y(p1); |
| + float x1; |
| + float x2; |
| - for (float y = y1; y + 2 * step <= y2;) { |
| - controlPoint1.setY(y + step); |
| - controlPoint2.setY(y + step); |
| - y += 2 * step; |
| - path.addBezierCurveTo(controlPoint1, controlPoint2, FloatPoint(xAxis, y)); |
| - } |
| + if (T::x(p1) < T::x(p2)) { |
| + x1 = T::x(p1); |
| + x2 = T::x(p2); |
|
abarth-chromium
2015/06/19 23:00:45
Should we give these more semantic names, like |ma
|
| } else { |
| - ASSERT(p1.y() == p2.y()); |
| - |
| - float yAxis = p1.y(); |
| - float x1; |
| - float x2; |
| - |
| - if (p1.x() < p2.x()) { |
| - x1 = p1.x(); |
| - x2 = p2.x(); |
| - } else { |
| - x1 = p2.x(); |
| - x2 = p1.x(); |
| - } |
| + x1 = T::x(p2); |
| + x2 = T::x(p1); |
| + } |
| - adjustStepToDecorationLength(step, controlPointDistance, x2 - x1); |
| - FloatPoint controlPoint1(0, yAxis + controlPointDistance); |
| - FloatPoint controlPoint2(0, yAxis - controlPointDistance); |
| + adjustStepToDecorationLength(step, controlPointDistance, x2 - x1); |
| - for (float x = x1; x + 2 * step <= x2;) { |
| - controlPoint1.setX(x + step); |
| - controlPoint2.setX(x + step); |
| - x += 2 * step; |
| - path.addBezierCurveTo(controlPoint1, controlPoint2, FloatPoint(x, yAxis)); |
| - } |
| + FloatPoint controlPoint1 = T::p(0, yAxis + controlPointDistance); |
| + FloatPoint controlPoint2 = T::p(0, yAxis - controlPointDistance); |
| + |
| + for (float x = x1; x + 2 * step <= x2;) { |
| + T::setX(controlPoint1, x + step); |
| + T::setX(controlPoint2, x + step); |
| + x += 2 * step; |
| + path.addBezierCurveTo(controlPoint1, controlPoint2, T::p(x, yAxis)); |
| } |
| context->setShouldAntialias(true); |
| context->strokePath(path); |
| } |
| +static void strokeWavyTextDecoration(GraphicsContext* context, FloatPoint p1, FloatPoint p2, float strokeThickness) |
| +{ |
| + if (p1.y() == p2.y()) // horizontal line |
| + strokeWavyTextDecorationInternal<CurveAlongX>(context, p1, p2, strokeThickness); |
| + else // vertical line |
| + strokeWavyTextDecorationInternal<CurveAlongY>(context, p1, p2, strokeThickness); |
| +} |
| + |
| static bool shouldSetDecorationAntialias(TextDecorationStyle decorationStyle) |
| { |
| return decorationStyle == TextDecorationStyleDotted || decorationStyle == TextDecorationStyleDashed; |
| @@ -962,7 +955,7 @@ void InlineTextBox::paintDecoration(GraphicsContext* context, const FloatPoint& |
| // Set the thick of the line to be 10% (or something else ?)of the computed font size and not less than 1px. |
| // Update Underline thickness, in case we have Faulty Font Metrics calculating underline thickness by old method. |
| - float textDecorationThickness = styleToUse->fontMetrics().underlineThickness(); |
| + float textDecorationThickness = styleToUse->fontMetrics().underlineThickness(); // TODO(ianh): Make this author-controllable |
| int fontHeightInt = (int)(styleToUse->fontMetrics().floatHeight() + 0.5); |
| if ((textDecorationThickness == 0.f) || (textDecorationThickness >= (fontHeightInt >> 1))) |
| textDecorationThickness = std::max(1.f, styleToUse->computedFontSize() / 10.f); |