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:
parent
9d01fbc964
commit
44a97d508e
@ -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)
|
||||||
|
Loading…
Reference in New Issue
Block a user