SkPDF: use RasterClip and Region less.

* GraphicStackState::updateClip() uses device bounds, not region bounds
  * SkPDFDevice::handleInversePath() uses clipstack, not rasterclip

Rendered PDF Changes: unnoticable.

Change-Id: Ibf9c169a5ada828c8fefedf2bcb37f6de34f3528
Reviewed-on: https://skia-review.googlesource.com/8885
Reviewed-by: Mike Reed <reed@google.com>
Commit-Queue: Hal Canary <halcanary@google.com>
This commit is contained in:
Hal Canary 2017-02-22 10:45:25 -05:00 committed by Skia Commit-Bot
parent 9d01fbc964
commit 44a97d508e

View File

@ -137,7 +137,7 @@ public:
} }
void updateClip(const SkClipStack& clipStack, const SkRegion& clipRegion, void updateClip(const SkClipStack& clipStack, const SkRegion& clipRegion,
const SkPoint& translation); const SkPoint& translation, const SkRect& bounds);
void updateMatrix(const SkMatrix& matrix); void updateMatrix(const SkMatrix& matrix);
void updateDrawingState(const SkPDFDevice::GraphicStateEntry& state); void updateDrawingState(const SkPDFDevice::GraphicStateEntry& state);
@ -188,21 +188,24 @@ static bool calculate_inverse_path(const SkRect& bounds, const SkPath& invPath,
return Op(clipPath, invPath, kIntersect_SkPathOp, outPath); return Op(clipPath, invPath, kIntersect_SkPathOp, outPath);
} }
// Sanity check the numerical values of the SkRegion ops and PathOps ops bool apply_clip(SkClipOp op, const SkPath& u, const SkPath& v, SkPath* r) {
// enums so region_op_to_pathops_op can do a straight passthrough cast. switch (op) {
// If these are failing, it may be necessary to make region_op_to_pathops_op case SkClipOp::kDifference:
// do more. return Op(u, v, kDifference_SkPathOp, r);
static_assert(SkRegion::kDifference_Op == (int)kDifference_SkPathOp, "region_pathop_mismatch"); case SkClipOp::kIntersect:
static_assert(SkRegion::kIntersect_Op == (int)kIntersect_SkPathOp, "region_pathop_mismatch"); return Op(u, v, kIntersect_SkPathOp, r);
static_assert(SkRegion::kUnion_Op == (int)kUnion_SkPathOp, "region_pathop_mismatch"); case SkClipOp::kUnion_deprecated:
static_assert(SkRegion::kXOR_Op == (int)kXOR_SkPathOp, "region_pathop_mismatch"); return Op(u, v, kUnion_SkPathOp, r);
static_assert(SkRegion::kReverseDifference_Op == (int)kReverseDifference_SkPathOp, case SkClipOp::kXOR_deprecated:
"region_pathop_mismatch"); return Op(u, v, kXOR_SkPathOp, r);
case SkClipOp::kReverseDifference_deprecated:
static SkPathOp region_op_to_pathops_op(SkClipOp op) { return Op(u, v, kReverseDifference_SkPathOp, r);
SkASSERT(static_cast<int>(op) >= 0); case SkClipOp::kReplace_deprecated:
SkASSERT(static_cast<int>(op) <= static_cast<int>(kReverseDifference_SkClipOp)); *r = v;
return (SkPathOp)op; return true;
default:
return false;
}
} }
/* Uses Path Ops to calculate a vector SkPath clip from a clip stack. /* Uses Path Ops to calculate a vector SkPath clip from a clip stack.
@ -213,7 +216,7 @@ static SkPathOp region_op_to_pathops_op(SkClipOp op) {
*/ */
static bool get_clip_stack_path(const SkMatrix& transform, static bool get_clip_stack_path(const SkMatrix& transform,
const SkClipStack& clipStack, const SkClipStack& clipStack,
const SkRegion& clipRegion, const SkRect& bounds,
SkPath* outClipPath) { SkPath* outClipPath) {
outClipPath->reset(); outClipPath->reset();
outClipPath->setFillType(SkPath::kInverseWinding_FillType); outClipPath->setFillType(SkPath::kInverseWinding_FillType);
@ -231,14 +234,8 @@ static bool get_clip_stack_path(const SkMatrix& transform,
clipEntry->asPath(&entryPath); clipEntry->asPath(&entryPath);
} }
entryPath.transform(transform); entryPath.transform(transform);
if (!apply_clip(clipEntry->getOp(), *outClipPath, entryPath, outClipPath)) {
if (kReplace_SkClipOp == clipEntry->getOp()) { return false;
*outClipPath = entryPath;
} else {
SkPathOp op = region_op_to_pathops_op(clipEntry->getOp());
if (!Op(*outClipPath, entryPath, op, outClipPath)) {
return false;
}
} }
} }
@ -246,7 +243,7 @@ static bool get_clip_stack_path(const SkMatrix& transform,
// The bounds are slightly outset to ensure this is correct in the // The bounds are slightly outset to ensure this is correct in the
// face of floating-point accuracy and possible SkRegion bitmap // face of floating-point accuracy and possible SkRegion bitmap
// approximations. // approximations.
SkRect clipBounds = SkRect::Make(clipRegion.getBounds()); SkRect clipBounds = bounds;
clipBounds.outset(SK_Scalar1, SK_Scalar1); clipBounds.outset(SK_Scalar1, SK_Scalar1);
if (!calculate_inverse_path(clipBounds, *outClipPath, outClipPath)) { if (!calculate_inverse_path(clipBounds, *outClipPath, outClipPath)) {
return false; return false;
@ -260,7 +257,8 @@ static bool get_clip_stack_path(const SkMatrix& transform,
// on the page to optimize this. // on the page to optimize this.
void GraphicStackState::updateClip(const SkClipStack& clipStack, void GraphicStackState::updateClip(const SkClipStack& clipStack,
const SkRegion& clipRegion, const SkRegion& clipRegion,
const SkPoint& translation) { const SkPoint& translation,
const SkRect& bounds) {
if (clipStack == currentEntry()->fClipStack) { if (clipStack == currentEntry()->fClipStack) {
return; return;
} }
@ -280,7 +278,7 @@ void GraphicStackState::updateClip(const SkClipStack& clipStack,
transform.setTranslate(translation.fX, translation.fY); transform.setTranslate(translation.fX, translation.fY);
SkPath clipPath; SkPath clipPath;
if (get_clip_stack_path(transform, clipStack, clipRegion, &clipPath)) { if (get_clip_stack_path(transform, clipStack, bounds, &clipPath)) {
SkPDFUtils::EmitPath(clipPath, SkPaint::kFill_Style, fContentStream); SkPDFUtils::EmitPath(clipPath, SkPaint::kFill_Style, fContentStream);
SkPath::FillType clipFill = clipPath.getFillType(); SkPath::FillType clipFill = clipPath.getFillType();
NOT_IMPLEMENTED(clipFill == SkPath::kInverseEvenOdd_FillType, false); NOT_IMPLEMENTED(clipFill == SkPath::kInverseEvenOdd_FillType, false);
@ -1541,7 +1539,7 @@ std::unique_ptr<SkStreamAsset> SkPDFDevice::content() const {
translation.iset(this->getOrigin()); translation.iset(this->getOrigin());
translation.negate(); translation.negate();
gsState.updateClip(entry.fState.fClipStack, entry.fState.fClipRegion, gsState.updateClip(entry.fState.fClipStack, entry.fState.fClipRegion,
translation); translation, SkRect::Make(this->getGlobalBounds()));
gsState.updateMatrix(entry.fState.fMatrix); gsState.updateMatrix(entry.fState.fMatrix);
gsState.updateDrawingState(entry.fState); gsState.updateDrawingState(entry.fState);
@ -1604,7 +1602,9 @@ bool SkPDFDevice::handleInversePath(const SkDraw& d, const SkPath& origPath,
if (!totalMatrix.invert(&transformInverse)) { if (!totalMatrix.invert(&transformInverse)) {
return false; return false;
} }
SkRect bounds = SkRect::Make(d.fRC->getBounds()); SkRect bounds = d.fClipStack->bounds(this->getGlobalBounds());
SkIPoint deviceOrigin = this->getOrigin();
bounds.offset(-deviceOrigin.x(), -deviceOrigin.y());
transformInverse.mapRect(&bounds); transformInverse.mapRect(&bounds);
// Extend the bounds by the line width (plus some padding) // Extend the bounds by the line width (plus some padding)