aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/pdf/SkPDFDevice.cpp
diff options
context:
space:
mode:
authorGravatar Mike Reed <reed@google.com>2017-03-07 09:37:29 -0500
committerGravatar Skia Commit-Bot <skia-commit-bot@chromium.org>2017-03-07 15:43:03 +0000
commita1361364e64138adda3dc5f71d50d7503838bb6d (patch)
tree13dd723a62883d7bf3e8d280a0a454fae02081a2 /src/pdf/SkPDFDevice.cpp
parent467921e5e6479fe9cebba125657d8e33d89004ae (diff)
Revert[6] "Remove SkDraw from device-draw methods, and enable device-centric clipping.""""""
Previous failure was failure to detect that the clip wasn't wide-open when optimizing for retain-vs-discard in copy-on-write. gm:copy_on_write_retain detected this. Now fixed by adding new method to SkBaseDevice.h This reverts commit 27d07f0acb85eea4062075dfbe9148ce12d92c66. BUG=skia:6214 Change-Id: I532d16ec075a4525c2a550b1157bcec695dd8efd Reviewed-on: https://skia-review.googlesource.com/9341 Reviewed-by: Florin Malita <fmalita@chromium.org> Commit-Queue: Mike Reed <reed@google.com>
Diffstat (limited to 'src/pdf/SkPDFDevice.cpp')
-rw-r--r--src/pdf/SkPDFDevice.cpp356
1 files changed, 161 insertions, 195 deletions
diff --git a/src/pdf/SkPDFDevice.cpp b/src/pdf/SkPDFDevice.cpp
index d54441e92d..26dd09fcd9 100644
--- a/src/pdf/SkPDFDevice.cpp
+++ b/src/pdf/SkPDFDevice.cpp
@@ -48,6 +48,23 @@
// Utility functions
+static void draw_points(SkCanvas::PointMode mode,
+ size_t count,
+ const SkPoint* points,
+ const SkPaint& paint,
+ const SkIRect& bounds,
+ const SkMatrix& ctm,
+ SkBaseDevice* device) {
+ SkRasterClip rc(bounds);
+ SkDraw draw;
+ draw.fDst = SkPixmap(SkImageInfo::MakeUnknown(bounds.right(), bounds.bottom()), nullptr, 0);
+ draw.fMatrix = &ctm;
+ draw.fRC = &rc;
+ draw.drawPoints(mode, count, points, paint, device);
+}
+
+static SkIRect size(const SkBaseDevice& dev) { return {0, 0, dev.width(), dev.height()}; }
+
// If the paint will definitely draw opaquely, replace kSrc with
// kSrcOver. http://crbug.com/473572
static void replace_srcmode_on_opaque_paint(SkPaint* paint) {
@@ -381,23 +398,26 @@ SkPDFCanon* SkPDFDevice::getCanon() const { return fDocument->canon(); }
// drawing method and maintain the state needed between set up and finish.
class ScopedContentEntry {
public:
- ScopedContentEntry(SkPDFDevice* device, const SkDraw& draw,
- const SkPaint& paint, bool hasText = false)
- : fDevice(device),
- fContentEntry(nullptr),
- fBlendMode(SkBlendMode::kSrcOver),
- fDstFormXObject(nullptr) {
- init(draw.fClipStack, *draw.fMatrix, paint, hasText);
- }
- ScopedContentEntry(SkPDFDevice* device, const SkClipStack* clipStack,
+ ScopedContentEntry(SkPDFDevice* device,
+ const SkClipStack& clipStack,
const SkMatrix& matrix,
- const SkPaint& paint, bool hasText = false)
- : fDevice(device),
- fContentEntry(nullptr),
- fBlendMode(SkBlendMode::kSrcOver),
- fDstFormXObject(nullptr) {
- init(clipStack, matrix, paint, hasText);
+ const SkPaint& paint,
+ bool hasText = false)
+ : fDevice(device)
+ , fContentEntry(nullptr)
+ , fBlendMode(SkBlendMode::kSrcOver)
+ , fDstFormXObject(nullptr)
+ {
+ if (matrix.hasPerspective()) {
+ NOT_IMPLEMENTED(!matrix.hasPerspective(), false);
+ return;
+ }
+ fBlendMode = paint.getBlendMode();
+ fContentEntry =
+ fDevice->setUpContentEntry(clipStack, matrix, paint, hasText, &fDstFormXObject);
}
+ ScopedContentEntry(SkPDFDevice* dev, const SkPaint& paint, bool hasText = false)
+ : ScopedContentEntry(dev, dev->cs(), dev->ctm(), paint, hasText) {}
~ScopedContentEntry() {
if (fContentEntry) {
@@ -451,18 +471,6 @@ private:
SkBlendMode fBlendMode;
sk_sp<SkPDFObject> fDstFormXObject;
SkPath fShape;
-
- void init(const SkClipStack* clipStack,
- const SkMatrix& matrix, const SkPaint& paint, bool hasText) {
- // Shape has to be flatten before we get here.
- if (matrix.hasPerspective()) {
- NOT_IMPLEMENTED(!matrix.hasPerspective(), false);
- return;
- }
- fBlendMode = paint.getBlendMode();
- fContentEntry = fDevice->setUpContentEntry(clipStack, matrix, paint, hasText,
- &fDstFormXObject);
- }
};
////////////////////////////////////////////////////////////////////////////////
@@ -503,25 +511,44 @@ void SkPDFDevice::cleanUp() {
fShaderResources.unrefAll();
}
-void SkPDFDevice::drawAnnotation(const SkDraw& d, const SkRect& rect, const char key[],
- SkData* value) {
+void SkPDFDevice::drawAnnotation(const SkRect& rect, const char key[], SkData* value) {
if (!value) {
return;
}
if (rect.isEmpty()) {
- this->handlePointAnnotation({ rect.x(), rect.y() }, *d.fMatrix, key, value);
- } else {
- this->handleRectAnnotation(rect, d, key, value);
+ if (!strcmp(SkAnnotationKeys::Define_Named_Dest_Key(), key)) {
+ SkPoint transformedPoint;
+ this->ctm().mapXY(rect.x(), rect.y(), &transformedPoint);
+ fNamedDestinations.emplace_back(value, transformedPoint);
+ }
+ return;
+ }
+ // Convert to path to handle non-90-degree rotations.
+ SkPath path;
+ path.addRect(rect);
+ path.transform(this->ctm(), &path);
+ SkPath clip;
+ (void)this->cs().asPath(&clip);
+ Op(clip, path, kIntersect_SkPathOp, &path);
+ // PDF wants a rectangle only.
+ SkRect transformedRect = path.getBounds();
+ if (transformedRect.isEmpty()) {
+ return;
+ }
+ if (!strcmp(SkAnnotationKeys::URL_Key(), key)) {
+ fLinkToURLs.emplace_back(transformedRect, value);
+ } else if (!strcmp(SkAnnotationKeys::Link_Named_Dest_Key(), key)) {
+ fLinkToDestinations.emplace_back(transformedRect, value);
}
}
-void SkPDFDevice::drawPaint(const SkDraw& d, const SkPaint& paint) {
+void SkPDFDevice::drawPaint(const SkPaint& paint) {
SkPaint newPaint = paint;
replace_srcmode_on_opaque_paint(&newPaint);
newPaint.setStyle(SkPaint::kFill_Style);
- ScopedContentEntry content(this, d, newPaint);
- internalDrawPaint(newPaint, content.entry());
+ ScopedContentEntry content(this, newPaint);
+ this->internalDrawPaint(newPaint, content.entry());
}
void SkPDFDevice::internalDrawPaint(const SkPaint& paint,
@@ -542,8 +569,7 @@ void SkPDFDevice::internalDrawPaint(const SkPaint& paint,
&contentEntry->fContent);
}
-void SkPDFDevice::drawPoints(const SkDraw& d,
- SkCanvas::PointMode mode,
+void SkPDFDevice::drawPoints(SkCanvas::PointMode mode,
size_t count,
const SkPoint* points,
const SkPaint& srcPaint) {
@@ -558,10 +584,11 @@ void SkPDFDevice::drawPoints(const SkDraw& d,
// We only use this when there's a path effect because of the overhead
// of multiple calls to setUpContentEntry it causes.
if (passedPaint.getPathEffect()) {
- if (d.fClipStack->isEmpty(this->getGlobalBounds())) {
+ if (this->cs().isEmpty(size(*this))) {
return;
}
- d.drawPoints(mode, count, points, passedPaint, this);
+ draw_points(mode, count, points, passedPaint,
+ this->devClipBounds(), this->ctm(), this);
return;
}
@@ -581,7 +608,7 @@ void SkPDFDevice::drawPoints(const SkDraw& d,
for (size_t i = 0; i < count; i++) {
SkRect r = SkRect::MakeXYWH(points[i].fX, points[i].fY, 0, 0);
r.inset(-halfStroke, -halfStroke);
- drawRect(d, r, modifiedPaint);
+ this->drawRect(r, modifiedPaint);
}
return;
} else {
@@ -589,7 +616,7 @@ void SkPDFDevice::drawPoints(const SkDraw& d,
}
}
- ScopedContentEntry content(this, d, *paint);
+ ScopedContentEntry content(this, *paint);
if (!content.entry()) {
return;
}
@@ -671,8 +698,7 @@ static sk_sp<SkPDFDict> create_link_named_dest(const SkData* nameData,
return annotation;
}
-void SkPDFDevice::drawRect(const SkDraw& d,
- const SkRect& rect,
+void SkPDFDevice::drawRect(const SkRect& rect,
const SkPaint& srcPaint) {
SkPaint paint = srcPaint;
replace_srcmode_on_opaque_paint(&paint);
@@ -680,16 +706,16 @@ void SkPDFDevice::drawRect(const SkDraw& d,
r.sort();
if (paint.getPathEffect()) {
- if (d.fClipStack->isEmpty(this->getGlobalBounds())) {
+ if (this->cs().isEmpty(size(*this))) {
return;
}
SkPath path;
path.addRect(r);
- drawPath(d, path, paint, nullptr, true);
+ this->drawPath(path, paint, nullptr, true);
return;
}
- ScopedContentEntry content(this, d, paint);
+ ScopedContentEntry content(this, paint);
if (!content.entry()) {
return;
}
@@ -698,37 +724,44 @@ void SkPDFDevice::drawRect(const SkDraw& d,
&content.entry()->fContent);
}
-void SkPDFDevice::drawRRect(const SkDraw& draw,
- const SkRRect& rrect,
+void SkPDFDevice::drawRRect(const SkRRect& rrect,
const SkPaint& srcPaint) {
SkPaint paint = srcPaint;
replace_srcmode_on_opaque_paint(&paint);
SkPath path;
path.addRRect(rrect);
- this->drawPath(draw, path, paint, nullptr, true);
+ this->drawPath(path, paint, nullptr, true);
}
-void SkPDFDevice::drawOval(const SkDraw& draw,
- const SkRect& oval,
+void SkPDFDevice::drawOval(const SkRect& oval,
const SkPaint& srcPaint) {
SkPaint paint = srcPaint;
replace_srcmode_on_opaque_paint(&paint);
SkPath path;
path.addOval(oval);
- this->drawPath(draw, path, paint, nullptr, true);
+ this->drawPath(path, paint, nullptr, true);
}
-void SkPDFDevice::drawPath(const SkDraw& d,
- const SkPath& origPath,
+void SkPDFDevice::drawPath(const SkPath& origPath,
const SkPaint& srcPaint,
const SkMatrix* prePathMatrix,
bool pathIsMutable) {
+ this->internalDrawPath(
+ this->cs(), this->ctm(), origPath, srcPaint, prePathMatrix, pathIsMutable);
+}
+
+void SkPDFDevice::internalDrawPath(const SkClipStack& clipStack,
+ const SkMatrix& ctm,
+ const SkPath& origPath,
+ const SkPaint& srcPaint,
+ const SkMatrix* prePathMatrix,
+ bool pathIsMutable) {
SkPaint paint = srcPaint;
replace_srcmode_on_opaque_paint(&paint);
SkPath modifiedPath;
SkPath* pathPtr = const_cast<SkPath*>(&origPath);
- SkMatrix matrix = *d.fMatrix;
+ SkMatrix matrix = ctm;
if (prePathMatrix) {
if (paint.getPathEffect() || paint.getStyle() != SkPaint::kFill_Style) {
if (!pathIsMutable) {
@@ -742,7 +775,7 @@ void SkPDFDevice::drawPath(const SkDraw& d,
}
if (paint.getPathEffect()) {
- if (d.fClipStack->isEmpty(this->getGlobalBounds())) {
+ if (clipStack.isEmpty(size(*this))) {
return;
}
if (!pathIsMutable) {
@@ -759,15 +792,15 @@ void SkPDFDevice::drawPath(const SkDraw& d,
noEffectPaint.setStyle(SkPaint::kStroke_Style);
noEffectPaint.setStrokeWidth(0);
}
- drawPath(d, *pathPtr, noEffectPaint, nullptr, true);
+ this->internalDrawPath(clipStack, ctm, *pathPtr, noEffectPaint, nullptr, true);
return;
}
- if (handleInversePath(d, origPath, paint, pathIsMutable, prePathMatrix)) {
+ if (this->handleInversePath(origPath, paint, pathIsMutable, prePathMatrix)) {
return;
}
- ScopedContentEntry content(this, d.fClipStack, matrix, paint);
+ ScopedContentEntry content(this, clipStack, matrix, paint);
if (!content.entry()) {
return;
}
@@ -786,8 +819,7 @@ void SkPDFDevice::drawPath(const SkDraw& d,
}
-void SkPDFDevice::drawImageRect(const SkDraw& d,
- const SkImage* image,
+void SkPDFDevice::drawImageRect(const SkImage* image,
const SkRect* src,
const SkRect& dst,
const SkPaint& srcPaint,
@@ -815,17 +847,15 @@ void SkPDFDevice::drawImageRect(const SkDraw& d,
if (!imageSubset.isValid()) {
return;
}
- transform.postConcat(*d.fMatrix);
- this->internalDrawImage(transform, d.fClipStack,
- std::move(imageSubset), paint);
+ transform.postConcat(this->ctm());
+ this->internalDrawImage(transform, this->cs(), std::move(imageSubset), paint);
}
-void SkPDFDevice::drawBitmapRect(const SkDraw& d,
- const SkBitmap& bitmap,
+void SkPDFDevice::drawBitmapRect(const SkBitmap& bitmap,
const SkRect* src,
const SkRect& dst,
- const SkPaint& srcPaint,
- SkCanvas::SrcRectConstraint) {
+ const SkPaint& srcPaint,
+ SkCanvas::SrcRectConstraint) {
if (bitmap.drawsNothing()) {
return;
}
@@ -853,16 +883,14 @@ void SkPDFDevice::drawBitmapRect(const SkDraw& d,
if (!imageSubset.isValid()) {
return;
}
- transform.postConcat(*d.fMatrix);
- this->internalDrawImage(transform, d.fClipStack,
- std::move(imageSubset), paint);
+ transform.postConcat(this->ctm());
+ this->internalDrawImage(transform, this->cs(), std::move(imageSubset), paint);
}
-void SkPDFDevice::drawBitmap(const SkDraw& d,
- const SkBitmap& bitmap,
+void SkPDFDevice::drawBitmap(const SkBitmap& bitmap,
const SkMatrix& matrix,
const SkPaint& srcPaint) {
- if (bitmap.drawsNothing() || d.fClipStack->isEmpty(this->getGlobalBounds())) {
+ if (bitmap.drawsNothing() || this->cs().isEmpty(size(*this))) {
return;
}
SkPaint paint = srcPaint;
@@ -874,17 +902,15 @@ void SkPDFDevice::drawBitmap(const SkDraw& d,
return;
}
SkMatrix transform = matrix;
- transform.postConcat(*d.fMatrix);
- this->internalDrawImage(
- transform, d.fClipStack, std::move(imageSubset), paint);
+ transform.postConcat(this->ctm());
+ this->internalDrawImage(transform, this->cs(), std::move(imageSubset), paint);
}
-void SkPDFDevice::drawSprite(const SkDraw& d,
- const SkBitmap& bitmap,
+void SkPDFDevice::drawSprite(const SkBitmap& bitmap,
int x,
int y,
const SkPaint& srcPaint) {
- if (bitmap.drawsNothing() || d.fClipStack->isEmpty(this->getGlobalBounds())) {
+ if (bitmap.drawsNothing() || this->cs().isEmpty(size(*this))) {
return;
}
SkPaint paint = srcPaint;
@@ -896,12 +922,10 @@ void SkPDFDevice::drawSprite(const SkDraw& d,
return;
}
SkMatrix transform = SkMatrix::MakeTrans(SkIntToScalar(x), SkIntToScalar(y));
- this->internalDrawImage(
- transform, d.fClipStack, std::move(imageSubset), paint);
+ this->internalDrawImage(transform, this->cs(), std::move(imageSubset), paint);
}
-void SkPDFDevice::drawImage(const SkDraw& draw,
- const SkImage* image,
+void SkPDFDevice::drawImage(const SkImage* image,
SkScalar x,
SkScalar y,
const SkPaint& srcPaint) {
@@ -917,9 +941,8 @@ void SkPDFDevice::drawImage(const SkDraw& draw,
return;
}
SkMatrix transform = SkMatrix::MakeTrans(x, y);
- transform.postConcat(*draw.fMatrix);
- this->internalDrawImage(
- transform, draw.fClipStack, std::move(imageSubset), paint);
+ transform.postConcat(this->ctm());
+ this->internalDrawImage(transform, this->cs(), std::move(imageSubset), paint);
}
namespace {
@@ -1213,7 +1236,7 @@ static void update_font(SkWStream* wStream, int fontIndex, SkScalar textSize) {
}
void SkPDFDevice::internalDrawText(
- const SkDraw& d, const void* sourceText, size_t sourceByteCount,
+ const void* sourceText, size_t sourceByteCount,
const SkScalar pos[], SkTextBlob::GlyphPositioning positioning,
SkPoint offset, const SkPaint& srcPaint, const uint32_t* clusters,
uint32_t textByteLength, const char* utf8Text) {
@@ -1297,7 +1320,7 @@ void SkPDFDevice::internalDrawText(
}
offset.offset(alignmentFactor * advance, 0);
}
- ScopedContentEntry content(this, d, paint, true);
+ ScopedContentEntry content(this, paint, true);
if (!content.entry()) {
return;
}
@@ -1396,20 +1419,20 @@ void SkPDFDevice::internalDrawText(
}
}
-void SkPDFDevice::drawText(const SkDraw& d, const void* text, size_t len,
+void SkPDFDevice::drawText(const void* text, size_t len,
SkScalar x, SkScalar y, const SkPaint& paint) {
- this->internalDrawText(d, text, len, nullptr, SkTextBlob::kDefault_Positioning,
+ this->internalDrawText(text, len, nullptr, SkTextBlob::kDefault_Positioning,
SkPoint{x, y}, paint, nullptr, 0, nullptr);
}
-void SkPDFDevice::drawPosText(const SkDraw& d, const void* text, size_t len,
+void SkPDFDevice::drawPosText(const void* text, size_t len,
const SkScalar pos[], int scalarsPerPos,
const SkPoint& offset, const SkPaint& paint) {
- this->internalDrawText(d, text, len, pos, (SkTextBlob::GlyphPositioning)scalarsPerPos,
+ this->internalDrawText(text, len, pos, (SkTextBlob::GlyphPositioning)scalarsPerPos,
offset, paint, nullptr, 0, nullptr);
}
-void SkPDFDevice::drawTextBlob(const SkDraw& draw, const SkTextBlob* blob, SkScalar x, SkScalar y,
+void SkPDFDevice::drawTextBlob(const SkTextBlob* blob, SkScalar x, SkScalar y,
const SkPaint &paint, SkDrawFilter* drawFilter) {
for (SkTextBlobRunIterator it(blob); !it.done(); it.next()) {
SkPaint runPaint(paint);
@@ -1419,25 +1442,24 @@ void SkPDFDevice::drawTextBlob(const SkDraw& draw, const SkTextBlob* blob, SkSca
}
runPaint.setFlags(this->filterTextFlags(runPaint));
SkPoint offset = it.offset() + SkPoint{x, y};
- this->internalDrawText(draw, it.glyphs(), sizeof(SkGlyphID) * it.glyphCount(),
+ this->internalDrawText(it.glyphs(), sizeof(SkGlyphID) * it.glyphCount(),
it.pos(), it.positioning(), offset, runPaint,
it.clusters(), it.textSize(), it.text());
}
}
-void SkPDFDevice::drawVertices(const SkDraw& d, SkCanvas::VertexMode,
+void SkPDFDevice::drawVertices(SkCanvas::VertexMode,
int vertexCount, const SkPoint verts[],
const SkPoint texs[], const SkColor colors[],
SkBlendMode, const uint16_t indices[],
int indexCount, const SkPaint& paint) {
- if (d.fClipStack->isEmpty(this->getGlobalBounds())) {
+ if (this->cs().isEmpty(size(*this))) {
return;
}
// TODO: implement drawVertices
}
-void SkPDFDevice::drawDevice(const SkDraw& d, SkBaseDevice* device,
- int x, int y, const SkPaint& paint) {
+void SkPDFDevice::drawDevice(SkBaseDevice* device, int x, int y, const SkPaint& paint) {
SkASSERT(!paint.getImageFilter());
// Check if the source device is really a bitmapdevice (because that's what we returned
@@ -1446,7 +1468,7 @@ void SkPDFDevice::drawDevice(const SkDraw& d, SkBaseDevice* device,
if (device->peekPixels(&pmap)) {
SkBitmap bitmap;
bitmap.installPixels(pmap);
- this->drawSprite(d, bitmap, x, y, paint);
+ this->drawSprite(bitmap, x, y, paint);
return;
}
@@ -1472,9 +1494,8 @@ void SkPDFDevice::drawDevice(const SkDraw& d, SkBaseDevice* device,
return;
}
- SkMatrix matrix;
- matrix.setTranslate(SkIntToScalar(x), SkIntToScalar(y));
- ScopedContentEntry content(this, d.fClipStack, matrix, paint);
+ SkMatrix matrix = SkMatrix::MakeTrans(SkIntToScalar(x), SkIntToScalar(y));
+ ScopedContentEntry content(this, this->cs(), matrix, paint);
if (!content.entry()) {
return;
}
@@ -1530,11 +1551,8 @@ std::unique_ptr<SkStreamAsset> SkPDFDevice::content() const {
GraphicStackState gsState(fExistingClipStack, &buffer);
for (const auto& entry : fContentEntries) {
- SkPoint translation;
- translation.iset(this->getOrigin());
- translation.negate();
gsState.updateClip(entry.fState.fClipStack,
- translation, SkRect::Make(this->getGlobalBounds()));
+ {0, 0}, SkRect::Make(size(*this)));
gsState.updateMatrix(entry.fState.fMatrix);
gsState.updateDrawingState(entry.fState);
@@ -1555,14 +1573,14 @@ std::unique_ptr<SkStreamAsset> SkPDFDevice::content() const {
* either as a (incorrect) fallback or because the path was not inverse
* in the first place.
*/
-bool SkPDFDevice::handleInversePath(const SkDraw& d, const SkPath& origPath,
+bool SkPDFDevice::handleInversePath(const SkPath& origPath,
const SkPaint& paint, bool pathIsMutable,
const SkMatrix* prePathMatrix) {
if (!origPath.isInverseFillType()) {
return false;
}
- if (d.fClipStack->isEmpty(this->getGlobalBounds())) {
+ if (this->cs().isEmpty(size(*this))) {
return false;
}
@@ -1582,7 +1600,7 @@ bool SkPDFDevice::handleInversePath(const SkDraw& d, const SkPath& origPath,
// To be consistent with the raster output, hairline strokes
// are rendered as non-inverted.
modifiedPath.toggleInverseFillType();
- drawPath(d, modifiedPath, paint, nullptr, true);
+ this->drawPath(modifiedPath, paint, nullptr, true);
return true;
}
}
@@ -1590,16 +1608,14 @@ bool SkPDFDevice::handleInversePath(const SkDraw& d, const SkPath& origPath,
// Get bounds of clip in current transform space
// (clip bounds are given in device space).
SkMatrix transformInverse;
- SkMatrix totalMatrix = *d.fMatrix;
+ SkMatrix totalMatrix = this->ctm();
if (prePathMatrix) {
totalMatrix.preConcat(*prePathMatrix);
}
if (!totalMatrix.invert(&transformInverse)) {
return false;
}
- SkRect bounds = d.fClipStack->bounds(this->getGlobalBounds());
- SkIPoint deviceOrigin = this->getOrigin();
- bounds.offset(-deviceOrigin.x(), -deviceOrigin.y());
+ SkRect bounds = this->cs().bounds(size(*this));
transformInverse.mapRect(&bounds);
// Extend the bounds by the line width (plus some padding)
@@ -1611,48 +1627,10 @@ bool SkPDFDevice::handleInversePath(const SkDraw& d, const SkPath& origPath,
return false;
}
- drawPath(d, modifiedPath, noInversePaint, prePathMatrix, true);
+ this->drawPath(modifiedPath, noInversePaint, prePathMatrix, true);
return true;
}
-void SkPDFDevice::handlePointAnnotation(const SkPoint& point,
- const SkMatrix& matrix,
- const char key[], SkData* value) {
- SkASSERT(value);
- if (!strcmp(SkAnnotationKeys::Define_Named_Dest_Key(), key)) {
- SkPoint transformedPoint;
- matrix.mapXY(point.x(), point.y(), &transformedPoint);
- fNamedDestinations.emplace_back(value, transformedPoint);
- }
-}
-
-void SkPDFDevice::handleRectAnnotation(const SkRect& rect,
- const SkDraw& d,
- const char key[], SkData* value) {
- SkASSERT(value);
- // Convert to path to handle non-90-degree rotations.
- SkPath path;
- path.addRect(rect);
- path.transform(*d.fMatrix, &path);
- SkPath clip;
- (void)d.fClipStack->asPath(&clip);
- SkIPoint deviceOrigin = this->getOrigin();
- clip.offset(-deviceOrigin.x(), -deviceOrigin.y());
- // Offset here to make clip and path share coordinates.
- // We remove the offset in SkPDFDevice::drawDevice().
- Op(clip, path, kIntersect_SkPathOp, &path);
- // PDF wants a rectangle only.
- SkRect transformedRect = path.getBounds();
-
- if (!transformedRect.isEmpty()) {
- if (!strcmp(SkAnnotationKeys::URL_Key(), key)) {
- fLinkToURLs.emplace_back(transformedRect, value);
- } else if (!strcmp(SkAnnotationKeys::Link_Named_Dest_Key(), key)) {
- fLinkToDestinations.emplace_back(transformedRect, value);
- }
- }
-}
-
void SkPDFDevice::appendAnnotations(SkPDFArray* array) const {
array->reserve(fLinkToURLs.count() + fLinkToDestinations.count());
for (const RectWithData& rectWithURL : fLinkToURLs) {
@@ -1704,10 +1682,10 @@ sk_sp<SkPDFObject> SkPDFDevice::makeFormXObjectFromDevice() {
void SkPDFDevice::drawFormXObjectWithMask(int xObjectIndex,
sk_sp<SkPDFObject> mask,
- const SkClipStack* clipStack,
+ const SkClipStack& clipStack,
SkBlendMode mode,
bool invertClip) {
- if (!invertClip && clipStack->isEmpty(this->getGlobalBounds())) {
+ if (!invertClip && clipStack.isEmpty(size(*this))) {
return;
}
@@ -1715,11 +1693,9 @@ void SkPDFDevice::drawFormXObjectWithMask(int xObjectIndex,
std::move(mask), invertClip,
SkPDFGraphicState::kAlpha_SMaskMode, fDocument->canon());
- SkMatrix identity;
- identity.reset();
SkPaint paint;
paint.setBlendMode(mode);
- ScopedContentEntry content(this, clipStack, identity, paint);
+ ScopedContentEntry content(this, clipStack, SkMatrix::I(), paint);
if (!content.entry()) {
return;
}
@@ -1735,13 +1711,12 @@ void SkPDFDevice::drawFormXObjectWithMask(int xObjectIndex,
&content.entry()->fContent);
}
-SkPDFDevice::ContentEntry* SkPDFDevice::setUpContentEntry(const SkClipStack* clipStack,
+SkPDFDevice::ContentEntry* SkPDFDevice::setUpContentEntry(const SkClipStack& clipStack,
const SkMatrix& matrix,
const SkPaint& paint,
bool hasText,
sk_sp<SkPDFObject>* dst) {
*dst = nullptr;
- SkASSERT(clipStack);
SkBlendMode blendMode = paint.getBlendMode();
// For the following modes, we want to handle source and destination
@@ -1781,7 +1756,7 @@ SkPDFDevice::ContentEntry* SkPDFDevice::setUpContentEntry(const SkClipStack* cli
} else {
entry = fContentEntries.emplace_front();
}
- populateGraphicStateEntryFromPaint(matrix, *clipStack, paint, hasText, &entry->fState);
+ populateGraphicStateEntryFromPaint(matrix, clipStack, paint, hasText, &entry->fState);
return entry;
}
@@ -1826,8 +1801,6 @@ void SkPDFDevice::finishContentEntry(SkBlendMode blendMode,
SkClipStack clipStack = fContentEntries.front()->fState.fClipStack;
- SkMatrix identity;
- identity.reset();
SkPaint stockPaint;
sk_sp<SkPDFObject> srcFormXObject;
@@ -1839,7 +1812,7 @@ void SkPDFDevice::finishContentEntry(SkBlendMode blendMode,
// reduces to Dst.
if (shape == nullptr || blendMode == SkBlendMode::kDstOut ||
blendMode == SkBlendMode::kSrcATop) {
- ScopedContentEntry content(this, &fExistingClipStack, identity, stockPaint);
+ ScopedContentEntry content(this, fExistingClipStack, SkMatrix::I(), stockPaint);
// TODO: addXObjectResource take sk_sp
SkPDFUtils::DrawFormXObject(this->addXObjectResource(dst.get()),
&content.entry()->fContent);
@@ -1860,28 +1833,23 @@ void SkPDFDevice::finishContentEntry(SkBlendMode blendMode,
// the non-transparent parts of the device and the outlines (shape) of
// all images and devices drawn.
drawFormXObjectWithMask(addXObjectResource(srcFormXObject.get()), dst,
- &fExistingClipStack, SkBlendMode::kSrcOver, true);
+ fExistingClipStack, SkBlendMode::kSrcOver, true);
} else {
if (shape != nullptr) {
// Draw shape into a form-xobject.
- SkRasterClip rc;
- SkDraw d;
- d.fMatrix = &identity;
- d.fRC = &rc;
- d.fClipStack = &clipStack;
SkPaint filledPaint;
filledPaint.setColor(SK_ColorBLACK);
filledPaint.setStyle(SkPaint::kFill_Style);
- this->drawPath(d, *shape, filledPaint, nullptr, true);
- drawFormXObjectWithMask(addXObjectResource(dst.get()),
- this->makeFormXObjectFromDevice(),
- &fExistingClipStack,
- SkBlendMode::kSrcOver, true);
-
+ this->internalDrawPath(clipStack, SkMatrix::I(), *shape, filledPaint, nullptr, true);
+ this->drawFormXObjectWithMask(this->addXObjectResource(dst.get()),
+ this->makeFormXObjectFromDevice(),
+ fExistingClipStack,
+ SkBlendMode::kSrcOver, true);
} else {
- drawFormXObjectWithMask(addXObjectResource(dst.get()), srcFormXObject,
- &fExistingClipStack,
- SkBlendMode::kSrcOver, true);
+ this->drawFormXObjectWithMask(this->addXObjectResource(dst.get()),
+ srcFormXObject,
+ fExistingClipStack,
+ SkBlendMode::kSrcOver, true);
}
}
@@ -1889,7 +1857,7 @@ void SkPDFDevice::finishContentEntry(SkBlendMode blendMode,
return;
} else if (blendMode == SkBlendMode::kSrc ||
blendMode == SkBlendMode::kDstATop) {
- ScopedContentEntry content(this, &fExistingClipStack, identity, stockPaint);
+ ScopedContentEntry content(this, fExistingClipStack, SkMatrix::I(), stockPaint);
if (content.entry()) {
SkPDFUtils::DrawFormXObject(
this->addXObjectResource(srcFormXObject.get()),
@@ -1899,8 +1867,8 @@ void SkPDFDevice::finishContentEntry(SkBlendMode blendMode,
return;
}
} else if (blendMode == SkBlendMode::kSrcATop) {
- ScopedContentEntry content(this, &fExistingClipStack,
- identity, stockPaint);
+ ScopedContentEntry content(this, fExistingClipStack,
+ SkMatrix::I(), stockPaint);
if (content.entry()) {
SkPDFUtils::DrawFormXObject(this->addXObjectResource(dst.get()),
&content.entry()->fContent);
@@ -1920,7 +1888,7 @@ void SkPDFDevice::finishContentEntry(SkBlendMode blendMode,
blendMode == SkBlendMode::kSrcATop) {
drawFormXObjectWithMask(addXObjectResource(srcFormXObject.get()),
std::move(dst),
- &fExistingClipStack,
+ fExistingClipStack,
SkBlendMode::kSrcOver,
blendMode == SkBlendMode::kSrcOut);
return;
@@ -1929,12 +1897,12 @@ void SkPDFDevice::finishContentEntry(SkBlendMode blendMode,
int resourceID = addXObjectResource(dst.get());
if (blendMode == SkBlendMode::kModulate) {
drawFormXObjectWithMask(addXObjectResource(srcFormXObject.get()),
- std::move(dst), &fExistingClipStack,
+ std::move(dst), fExistingClipStack,
SkBlendMode::kSrcOver, false);
mode = SkBlendMode::kMultiply;
}
drawFormXObjectWithMask(resourceID, std::move(srcFormXObject),
- &fExistingClipStack, mode,
+ fExistingClipStack, mode,
blendMode == SkBlendMode::kDstOut);
return;
}
@@ -1986,9 +1954,7 @@ void SkPDFDevice::populateGraphicStateEntryFromPaint(
// PDF doesn't support kClamp_TileMode, so we simulate it by making
// a pattern the size of the current clip.
- SkRect clipStackBounds = clipStack.bounds(this->getGlobalBounds());
- SkIPoint deviceOrigin = this->getOrigin();
- clipStackBounds.offset(-deviceOrigin.x(), -deviceOrigin.y());
+ SkRect clipStackBounds = clipStack.bounds(size(*this));
// We need to apply the initial transform to bounds in order to get
// bounds in a consistent coordinate system.
@@ -2095,7 +2061,7 @@ static sk_sp<SkImage> color_filter(const SkImageSubset& imageSubset,
////////////////////////////////////////////////////////////////////////////////
void SkPDFDevice::internalDrawImage(const SkMatrix& origMatrix,
- const SkClipStack* clipStack,
+ const SkClipStack& clipStack,
SkImageSubset imageSubset,
const SkPaint& paint) {
if (imageSubset.dimensions().isZero()) {
@@ -2237,8 +2203,8 @@ void SkPDFDevice::internalDrawImage(const SkMatrix& origMatrix,
#include "SkSpecialImage.h"
#include "SkImageFilter.h"
-void SkPDFDevice::drawSpecial(const SkDraw& draw, SkSpecialImage* srcImg, int x, int y,
- const SkPaint& paint) {
+void SkPDFDevice::drawSpecial(SkSpecialImage* srcImg, int x, int y,
+ const SkPaint& paint) {
SkASSERT(!srcImg->isTextureBacked());
SkBitmap resultBM;
@@ -2246,10 +2212,10 @@ void SkPDFDevice::drawSpecial(const SkDraw& draw, SkSpecialImage* srcImg, int x,
SkImageFilter* filter = paint.getImageFilter();
if (filter) {
SkIPoint offset = SkIPoint::Make(0, 0);
- SkMatrix matrix = *draw.fMatrix;
+ SkMatrix matrix = this->ctm();
matrix.postTranslate(SkIntToScalar(-x), SkIntToScalar(-y));
const SkIRect clipBounds =
- draw.fClipStack->bounds(this->imageInfo().bounds()).roundOut().makeOffset(-x, -y);
+ this->cs().bounds(this->imageInfo().bounds()).roundOut().makeOffset(-x, -y);
sk_sp<SkImageFilterCache> cache(this->getImageFilterCache());
// TODO: Should PDF be operating in a specified color space? For now, run the filter
// in the same color space as the source (this is different from all other backends).
@@ -2261,12 +2227,12 @@ void SkPDFDevice::drawSpecial(const SkDraw& draw, SkSpecialImage* srcImg, int x,
SkPaint tmpUnfiltered(paint);
tmpUnfiltered.setImageFilter(nullptr);
if (resultImg->getROPixels(&resultBM)) {
- this->drawSprite(draw, resultBM, x + offset.x(), y + offset.y(), tmpUnfiltered);
+ this->drawSprite(resultBM, x + offset.x(), y + offset.y(), tmpUnfiltered);
}
}
} else {
if (srcImg->getROPixels(&resultBM)) {
- this->drawSprite(draw, resultBM, x, y, paint);
+ this->drawSprite(resultBM, x, y, paint);
}
}
}