Commit 18ee61ec authored by Federico Paredes's avatar Federico Paredes Committed by Commit Bot

Added support for quadratic Bezier curves in Skia icons.

Quadratic Bezier curves are represented in SVGs through the q and t path
parameters (or Q and T for absolute coordinates). Currently, we only
take cubic bezier curves (c and s) into account in paint_vector_icon.cc.

Change-Id: I06dd63894e090a27583841a336501975011c2858
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2138555Reviewed-by: default avatarEvan Stade <estade@chromium.org>
Commit-Queue: Federico Paredes <fedpar@microsoft.com>
Cr-Commit-Position: refs/heads/master@{#757171}
parent e1fd1819
...@@ -116,6 +116,8 @@ class PathParser { ...@@ -116,6 +116,8 @@ class PathParser {
case R_MOVE_TO: case R_MOVE_TO:
case LINE_TO: case LINE_TO:
case R_LINE_TO: case R_LINE_TO:
case QUADRATIC_TO_SHORTHAND:
case R_QUADRATIC_TO_SHORTHAND:
return 2; return 2;
case CIRCLE: case CIRCLE:
...@@ -124,6 +126,9 @@ class PathParser { ...@@ -124,6 +126,9 @@ class PathParser {
case PATH_COLOR_ARGB: case PATH_COLOR_ARGB:
case CUBIC_TO_SHORTHAND: case CUBIC_TO_SHORTHAND:
case CLIP: case CLIP:
case QUADRATIC_TO:
case R_QUADRATIC_TO:
case OVAL:
return 4; return 4;
case ROUND_RECT: case ROUND_RECT:
...@@ -182,7 +187,12 @@ CommandType CommandFromString(const std::string& source) { ...@@ -182,7 +187,12 @@ CommandType CommandFromString(const std::string& source) {
RETURN_IF_IS(CUBIC_TO); RETURN_IF_IS(CUBIC_TO);
RETURN_IF_IS(R_CUBIC_TO); RETURN_IF_IS(R_CUBIC_TO);
RETURN_IF_IS(CUBIC_TO_SHORTHAND); RETURN_IF_IS(CUBIC_TO_SHORTHAND);
RETURN_IF_IS(QUADRATIC_TO);
RETURN_IF_IS(R_QUADRATIC_TO);
RETURN_IF_IS(QUADRATIC_TO_SHORTHAND);
RETURN_IF_IS(R_QUADRATIC_TO_SHORTHAND);
RETURN_IF_IS(CIRCLE); RETURN_IF_IS(CIRCLE);
RETURN_IF_IS(OVAL);
RETURN_IF_IS(ROUND_RECT); RETURN_IF_IS(ROUND_RECT);
RETURN_IF_IS(CLOSE); RETURN_IF_IS(CLOSE);
RETURN_IF_IS(CANVAS_DIMENSIONS); RETURN_IF_IS(CANVAS_DIMENSIONS);
...@@ -212,6 +222,13 @@ std::vector<PathElement> PathFromSource(const std::string& source) { ...@@ -212,6 +222,13 @@ std::vector<PathElement> PathFromSource(const std::string& source) {
return path; return path;
} }
bool IsCommandTypeCurve(CommandType command) {
return command == CUBIC_TO || command == R_CUBIC_TO ||
command == CUBIC_TO_SHORTHAND || command == QUADRATIC_TO ||
command == R_QUADRATIC_TO || command == QUADRATIC_TO_SHORTHAND ||
command == R_QUADRATIC_TO_SHORTHAND;
}
void PaintPath(Canvas* canvas, void PaintPath(Canvas* canvas,
const PathElement* path_elements, const PathElement* path_elements,
size_t path_size, size_t path_size,
...@@ -348,28 +365,55 @@ void PaintPath(Canvas* canvas, ...@@ -348,28 +365,55 @@ void PaintPath(Canvas* canvas,
path.rCubicTo(arg(0), arg(1), arg(2), arg(3), arg(4), arg(5)); path.rCubicTo(arg(0), arg(1), arg(2), arg(3), arg(4), arg(5));
break; break;
case CUBIC_TO_SHORTHAND: { case CUBIC_TO_SHORTHAND:
// Compute the first control point (|x1| and |y1|) as the reflection case QUADRATIC_TO_SHORTHAND:
// of the second control point on the previous command relative to case R_QUADRATIC_TO_SHORTHAND: {
// the current point. If there is no previous command or if the // Compute the first control point (|x1| and |y1|) as the reflection of
// previous command is not a cubic Bezier curve, the first control // the last control point on the previous command relative to the
// point is coincident with the current point. Refer to the SVG // current point. If there is no previous command or if the previous
// path specs for further details. // command is not a Bezier curve, the first control point is coincident
// with the current point. Refer to the SVG path specs for further
// details.
// Note that |x1| and |y1| will correspond to the sole control point if
// calculating a quadratic curve.
SkPoint last_point; SkPoint last_point;
path.getLastPt(&last_point); path.getLastPt(&last_point);
SkScalar delta_x = 0; SkScalar delta_x = 0;
SkScalar delta_y = 0; SkScalar delta_y = 0;
if (previous_command_type == CUBIC_TO || if (IsCommandTypeCurve(previous_command_type)) {
previous_command_type == R_CUBIC_TO ||
previous_command_type == CUBIC_TO_SHORTHAND) {
SkPoint last_control_point = path.getPoint(path.countPoints() - 2); SkPoint last_control_point = path.getPoint(path.countPoints() - 2);
// We find what the delta was between the last curve's starting point
// and the control point. This difference is what we will reflect on
// the current point, creating our new control point.
delta_x = last_point.fX - last_control_point.fX; delta_x = last_point.fX - last_control_point.fX;
delta_y = last_point.fY - last_control_point.fY; delta_y = last_point.fY - last_control_point.fY;
} }
SkScalar x1 = last_point.fX + delta_x; SkScalar x1 = last_point.fX + delta_x;
SkScalar y1 = last_point.fY + delta_y; SkScalar y1 = last_point.fY + delta_y;
path.cubicTo(x1, y1, arg(0), arg(1), arg(2), arg(3)); if (command_type == CUBIC_TO_SHORTHAND)
path.cubicTo(x1, y1, arg(0), arg(1), arg(2), arg(3));
else if (command_type == QUADRATIC_TO_SHORTHAND)
path.quadTo(x1, y1, arg(0), arg(1));
else if (command_type == R_QUADRATIC_TO_SHORTHAND)
path.rQuadTo(x1, y1, arg(0), arg(1));
break;
}
case QUADRATIC_TO:
path.quadTo(arg(0), arg(1), arg(2), arg(3));
break;
case R_QUADRATIC_TO:
path.rQuadTo(arg(0), arg(1), arg(2), arg(3));
break;
case OVAL: {
SkScalar x = arg(0);
SkScalar y = arg(1);
SkScalar rx = arg(2);
SkScalar ry = arg(3);
path.addOval(SkRect::MakeLTRB(x - rx, y - ry, x + rx, y + ry));
break; break;
} }
......
...@@ -46,7 +46,12 @@ namespace gfx { ...@@ -46,7 +46,12 @@ namespace gfx {
DECLARE_VECTOR_COMMAND(CUBIC_TO) \ DECLARE_VECTOR_COMMAND(CUBIC_TO) \
DECLARE_VECTOR_COMMAND(R_CUBIC_TO) \ DECLARE_VECTOR_COMMAND(R_CUBIC_TO) \
DECLARE_VECTOR_COMMAND(CUBIC_TO_SHORTHAND) \ DECLARE_VECTOR_COMMAND(CUBIC_TO_SHORTHAND) \
DECLARE_VECTOR_COMMAND(QUADRATIC_TO) \
DECLARE_VECTOR_COMMAND(R_QUADRATIC_TO) \
DECLARE_VECTOR_COMMAND(QUADRATIC_TO_SHORTHAND) \
DECLARE_VECTOR_COMMAND(R_QUADRATIC_TO_SHORTHAND) \
DECLARE_VECTOR_COMMAND(CIRCLE) \ DECLARE_VECTOR_COMMAND(CIRCLE) \
DECLARE_VECTOR_COMMAND(OVAL) \
DECLARE_VECTOR_COMMAND(ROUND_RECT) \ DECLARE_VECTOR_COMMAND(ROUND_RECT) \
DECLARE_VECTOR_COMMAND(CLOSE) \ DECLARE_VECTOR_COMMAND(CLOSE) \
/* Sets the dimensions of the canvas in dip. */ \ /* Sets the dimensions of the canvas in dip. */ \
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment