Commit a73c35d5 authored by Fredrik Söderquist's avatar Fredrik Söderquist Committed by Commit Bot

Handle degenerate curve segments for marker orientation

When a cubic or quadratic curve have a point that coincide with another
of its point such that either the start or end tangent vector is
degenerate, the orientation in that point will be 0. In such cases try
to use the next/previous non-degenerate tangent vector (if any) instead.

Bug: 450368
Change-Id: I35db404b3f82cf61b10427678feecc2157eeeb26
Reviewed-on: https://chromium-review.googlesource.com/1196503Reviewed-by: default avatarStephen Chenney <schenney@chromium.org>
Commit-Queue: Fredrik Söderquist <fs@opera.com>
Cr-Commit-Position: refs/heads/master@{#587743}
parent 3d00d1e7
<!DOCTYPE html>
<div style="width: 400px; height: 100px; background-color: green"></div>
<!DOCTYPE html>
<svg width="400">
<marker id="me" orient="auto" overflow="visible">
<rect x="-1" y="-0.5" width="1" height="1" fill="green"/>
</marker>
<g marker-end="url(#me)" stroke-width="100" stroke="red">
<!-- Points 3 and 4 coincident -->
<path d="M50,0C50,50 50,100 50,100"/>
<!-- Points 2, 3 and 4 coincident -->
<path d="M50,0C50,100 50,100 50,100" transform="translate(100 0)"/>
</g>
<marker id="ms" orient="auto" overflow="visible">
<rect x="0" y="-0.5" width="1" height="1" fill="green"/>
</marker>
<g marker-start="url(#ms)" stroke-width="100" stroke="red" transform="translate(200 0)">
<!-- Points 1 and 2 coincident -->
<path d="M50,0C50,0 50,50 50,100"/>
<!-- Points 1, 2 and 3 coincident -->
<path d="M50,0C50,0 50,0 50,100" transform="translate(100 0)"/>
</g>
</svg>
<!DOCTYPE html>
<div style="width: 200px; height: 100px; background-color: green"></div>
<!DOCTYPE html>
<svg width="400">
<marker id="me" orient="auto" overflow="visible">
<rect x="-1" y="-0.5" width="1" height="1" fill="green"/>
</marker>
<g marker-end="url(#me)" stroke-width="100" stroke="red">
<!-- Points 2 and 3 coincident -->
<path d="M50,0Q50,100 50,100"/>
</g>
<marker id="ms" orient="auto" overflow="visible">
<rect x="0" y="-0.5" width="1" height="1" fill="green"/>
</marker>
<g marker-start="url(#ms)" stroke-width="100" stroke="red" transform="translate(100 0)">
<!-- Points 1 and 2 coincident -->
<path d="M50,0Q50,0 50,100"/>
</g>
</svg>
......@@ -113,6 +113,18 @@ class SVGMarkerData {
FloatPoint position; // The end point of the segment.
};
static void ComputeQuadTangents(SegmentData& data,
const FloatPoint& start,
const FloatPoint& control,
const FloatPoint& end) {
data.start_tangent = control - start;
data.end_tangent = end - control;
if (data.start_tangent.IsZero())
data.start_tangent = data.end_tangent;
else if (data.end_tangent.IsZero())
data.end_tangent = data.start_tangent;
}
SegmentData ExtractPathElementFeatures(const PathElement& element) const {
SegmentData data;
const FloatPoint* points = element.points;
......@@ -121,11 +133,14 @@ class SVGMarkerData {
data.position = points[2];
data.start_tangent = points[0] - origin_;
data.end_tangent = points[2] - points[1];
if (data.start_tangent.IsZero())
ComputeQuadTangents(data, points[0], points[1], points[2]);
else if (data.end_tangent.IsZero())
ComputeQuadTangents(data, origin_, points[0], points[1]);
break;
case kPathElementAddQuadCurveToPoint:
data.position = points[1];
data.start_tangent = points[0] - origin_;
data.end_tangent = points[1] - points[0];
ComputeQuadTangents(data, origin_, points[0], points[1]);
break;
case kPathElementMoveToPoint:
case kPathElementAddLineToPoint:
......
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