SkPDF: better tolerance path conversion to quadratics
BUG=chromium:691386 Change-Id: I2cb9be7dd606b2ba61ff609f9fd81a55655901f6 Reviewed-on: https://skia-review.googlesource.com/8381 Commit-Queue: Hal Canary <halcanary@google.com> Reviewed-by: Ben Wagner <bungeman@google.com> Reviewed-by: Cary Clark <caryclark@google.com>
This commit is contained in:
parent
ea479576ec
commit
385468f6e2
22
gm/crbug_691386.cpp
Normal file
22
gm/crbug_691386.cpp
Normal file
@ -0,0 +1,22 @@
|
||||
/*
|
||||
* Copyright 2017 Google Inc.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license that can be
|
||||
* found in the LICENSE file.
|
||||
*/
|
||||
|
||||
#include "gm.h"
|
||||
#include "SkParsePath.h"
|
||||
|
||||
DEF_SIMPLE_GM(crbug_691386, canvas, 256, 256) {
|
||||
SkPath path;
|
||||
if (!SkParsePath::FromSVGString("M -1 0 A 1 1 0 0 0 1 0 Z", &path)) {
|
||||
return;
|
||||
}
|
||||
SkPaint p;
|
||||
p.setStyle(SkPaint::kStroke_Style);
|
||||
p.setStrokeWidth(0.025f);
|
||||
canvas->scale(96.0f, 96.0f);
|
||||
canvas->translate(1.25f, 1.25f);
|
||||
canvas->drawPath(path, p);
|
||||
}
|
@ -84,6 +84,7 @@ gm_sources = [
|
||||
"$_gm/convexpolyclip.cpp",
|
||||
"$_gm/convexpolyeffect.cpp",
|
||||
"$_gm/copyTo4444.cpp",
|
||||
"$_gm/crbug_691386.cpp",
|
||||
"$_gm/croppedrects.cpp",
|
||||
"$_gm/cubicpaths.cpp",
|
||||
"$_gm/dashcircle.cpp",
|
||||
|
@ -781,13 +781,16 @@ void SkPDFDevice::drawPath(const SkDraw& d,
|
||||
if (!content.entry()) {
|
||||
return;
|
||||
}
|
||||
SkScalar matrixScale = matrix.mapRadius(1.0f);
|
||||
SkScalar tolerance = matrixScale > 0.0f ? 0.25f / matrixScale : 0.25f;
|
||||
bool consumeDegeratePathSegments =
|
||||
paint.getStyle() == SkPaint::kFill_Style ||
|
||||
(paint.getStrokeCap() != SkPaint::kRound_Cap &&
|
||||
paint.getStrokeCap() != SkPaint::kSquare_Cap);
|
||||
SkPDFUtils::EmitPath(*pathPtr, paint.getStyle(),
|
||||
consumeDegeratePathSegments,
|
||||
&content.entry()->fContent);
|
||||
&content.entry()->fContent,
|
||||
tolerance);
|
||||
SkPDFUtils::PaintPath(paint.getStyle(), pathPtr->getFillType(),
|
||||
&content.entry()->fContent);
|
||||
}
|
||||
|
@ -117,7 +117,8 @@ void SkPDFUtils::AppendRectangle(const SkRect& rect, SkWStream* content) {
|
||||
|
||||
// static
|
||||
void SkPDFUtils::EmitPath(const SkPath& path, SkPaint::Style paintStyle,
|
||||
bool doConsumeDegerates, SkWStream* content) {
|
||||
bool doConsumeDegerates, SkWStream* content,
|
||||
SkScalar tolerance) {
|
||||
// Filling a path with no area results in a drawing in PDF renderers but
|
||||
// Chrome expects to be able to draw some such entities with no visible
|
||||
// result, so we detect those cases and discard the drawing for them.
|
||||
@ -131,7 +132,7 @@ void SkPDFUtils::EmitPath(const SkPath& path, SkPaint::Style paintStyle,
|
||||
{
|
||||
SkPDFUtils::AppendRectangle(rect, content);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
enum SkipFillState {
|
||||
kEmpty_SkipFillState,
|
||||
@ -169,9 +170,8 @@ void SkPDFUtils::EmitPath(const SkPath& path, SkPaint::Style paintStyle,
|
||||
fillState = kNonSingleLine_SkipFillState;
|
||||
break;
|
||||
case SkPath::kConic_Verb: {
|
||||
const SkScalar tol = SK_Scalar1 / 4;
|
||||
SkAutoConicToQuads converter;
|
||||
const SkPoint* quads = converter.computeQuads(args, iter.conicWeight(), tol);
|
||||
const SkPoint* quads = converter.computeQuads(args, iter.conicWeight(), tolerance);
|
||||
for (int i = 0; i < converter.countQuads(); ++i) {
|
||||
append_quad(&quads[i * 2], ¤tSegment);
|
||||
}
|
||||
@ -183,9 +183,7 @@ void SkPDFUtils::EmitPath(const SkPath& path, SkPaint::Style paintStyle,
|
||||
fillState = kNonSingleLine_SkipFillState;
|
||||
break;
|
||||
case SkPath::kClose_Verb:
|
||||
|
||||
ClosePath(¤tSegment);
|
||||
|
||||
ClosePath(¤tSegment);
|
||||
currentSegment.writeToStream(content);
|
||||
currentSegment.reset();
|
||||
break;
|
||||
|
@ -45,10 +45,10 @@ void AppendCubic(SkScalar ctl1X, SkScalar ctl1Y,
|
||||
SkScalar dstX, SkScalar dstY, SkWStream* content);
|
||||
void AppendRectangle(const SkRect& rect, SkWStream* content);
|
||||
void EmitPath(const SkPath& path, SkPaint::Style paintStyle,
|
||||
bool doConsumeDegerates, SkWStream* content);
|
||||
bool doConsumeDegerates, SkWStream* content, SkScalar tolerance = 0.25f);
|
||||
inline void EmitPath(const SkPath& path, SkPaint::Style paintStyle,
|
||||
SkWStream* content) {
|
||||
SkPDFUtils::EmitPath(path, paintStyle, true, content);
|
||||
SkWStream* content, SkScalar tolerance = 0.25f) {
|
||||
SkPDFUtils::EmitPath(path, paintStyle, true, content, tolerance);
|
||||
}
|
||||
void ClosePath(SkWStream* content);
|
||||
void PaintPath(SkPaint::Style style, SkPath::FillType fill,
|
||||
|
Loading…
Reference in New Issue
Block a user