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

Unified 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « no previous file | sky/engine/platform/RuntimeEnabledFeatures.in » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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);
« 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