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:
Hal Canary 2017-02-13 11:03:23 -05:00 committed by Skia Commit-Bot
parent ea479576ec
commit 385468f6e2
5 changed files with 35 additions and 11 deletions

22
gm/crbug_691386.cpp Normal file
View 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);
}

View File

@ -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",

View File

@ -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);
}

View File

@ -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.
@ -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], &currentSegment);
}
@ -183,9 +183,7 @@ void SkPDFUtils::EmitPath(const SkPath& path, SkPaint::Style paintStyle,
fillState = kNonSingleLine_SkipFillState;
break;
case SkPath::kClose_Verb:
ClosePath(&currentSegment);
currentSegment.writeToStream(content);
currentSegment.reset();
break;

View File

@ -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,