diff options
author | halcanary <halcanary@google.com> | 2016-03-21 14:33:17 -0700 |
---|---|---|
committer | Commit bot <commit-bot@chromium.org> | 2016-03-21 14:33:17 -0700 |
commit | 989da4a32cd6823359f31c971c3b3f31425e905e (patch) | |
tree | 0ff6449e003fdbd7413bc5604b16f2a2a4c878dc | |
parent | 2cab66be9c47660da6a2cc94b469c14d5bed958e (diff) |
SkPDF: SkPDFDevice has ptr to SkPDFDocument
This is necessary for pre-serialization of images.
BUG=skia:5087
GOLD_TRYBOT_URL= https://gold.skia.org/search2?unt=true&query=source_type%3Dgm&master=false&issue=1802963002
Review URL: https://codereview.chromium.org/1802963002
-rw-r--r-- | src/pdf/SkPDFDevice.cpp | 41 | ||||
-rw-r--r-- | src/pdf/SkPDFDevice.h | 22 | ||||
-rw-r--r-- | src/pdf/SkPDFDocument.cpp | 2 | ||||
-rw-r--r-- | src/pdf/SkPDFDocument.h | 2 | ||||
-rw-r--r-- | src/pdf/SkPDFShader.cpp | 32 | ||||
-rw-r--r-- | src/pdf/SkPDFShader.h | 7 |
6 files changed, 62 insertions, 44 deletions
diff --git a/src/pdf/SkPDFDevice.cpp b/src/pdf/SkPDFDevice.cpp index 9cc2563caf..514cd88408 100644 --- a/src/pdf/SkPDFDevice.cpp +++ b/src/pdf/SkPDFDevice.cpp @@ -19,6 +19,7 @@ #include "SkPathOps.h" #include "SkPDFBitmap.h" #include "SkPDFCanon.h" +#include "SkPDFDocument.h" #include "SkPDFFont.h" #include "SkPDFFormXObject.h" #include "SkPDFGraphicState.h" @@ -584,9 +585,11 @@ SkBaseDevice* SkPDFDevice::onCreateDevice(const CreateInfo& cinfo, const SkPaint return nullptr; } SkISize size = SkISize::Make(cinfo.fInfo.width(), cinfo.fInfo.height()); - return SkPDFDevice::Create(size, fRasterDpi, fCanon); + return SkPDFDevice::Create(size, fRasterDpi, fDocument); } +SkPDFCanon* SkPDFDevice::getCanon() const { return fDocument->canon(); } + struct ContentEntry { GraphicStateEntry fState; @@ -700,7 +703,7 @@ private: //////////////////////////////////////////////////////////////////////////////// -SkPDFDevice::SkPDFDevice(SkISize pageSize, SkScalar rasterDpi, SkPDFCanon* canon, bool flip) +SkPDFDevice::SkPDFDevice(SkISize pageSize, SkScalar rasterDpi, SkPDFDocument* doc, bool flip) : INHERITED(SkSurfaceProps(0, kUnknown_SkPixelGeometry)) , fPageSize(pageSize) , fContentSize(pageSize) @@ -711,7 +714,7 @@ SkPDFDevice::SkPDFDevice(SkISize pageSize, SkScalar rasterDpi, SkPDFCanon* canon , fClipStack(nullptr) , fFontGlyphUsage(new SkPDFGlyphSetMap) , fRasterDpi(rasterDpi) - , fCanon(canon) { + , fDocument(doc) { SkASSERT(pageSize.width() > 0); SkASSERT(pageSize.height() > 0); fLegacyBitmap.setInfo( @@ -1057,7 +1060,7 @@ void SkPDFDevice::drawBitmap(const SkDraw& d, SkMatrix transform = matrix; transform.postConcat(*d.fMatrix); - const SkImage* image = fCanon->bitmapToImage(bitmap); + const SkImage* image = fDocument->canon()->bitmapToImage(bitmap); if (!image) { return; } @@ -1081,7 +1084,7 @@ void SkPDFDevice::drawSprite(const SkDraw& d, SkMatrix matrix; matrix.setTranslate(SkIntToScalar(x), SkIntToScalar(y)); - const SkImage* image = fCanon->bitmapToImage(bitmap); + const SkImage* image = fDocument->canon()->bitmapToImage(bitmap); if (!image) { return; } @@ -1196,7 +1199,7 @@ static void draw_transparent_text(SkPDFDevice* device, void SkPDFDevice::drawText(const SkDraw& d, const void* text, size_t len, SkScalar x, SkScalar y, const SkPaint& srcPaint) { - if (!SkPDFFont::CanEmbedTypeface(srcPaint.getTypeface(), fCanon)) { + if (!SkPDFFont::CanEmbedTypeface(srcPaint.getTypeface(), fDocument->canon())) { // https://bug.skia.org/3866 SkPath path; srcPaint.getTextPath(text, len, x, y, &path); @@ -1257,7 +1260,7 @@ void SkPDFDevice::drawText(const SkDraw& d, const void* text, size_t len, void SkPDFDevice::drawPosText(const SkDraw& d, const void* text, size_t len, const SkScalar pos[], int scalarsPerPos, const SkPoint& offset, const SkPaint& srcPaint) { - if (!SkPDFFont::CanEmbedTypeface(srcPaint.getTypeface(), fCanon)) { + if (!SkPDFFont::CanEmbedTypeface(srcPaint.getTypeface(), fDocument->canon())) { const SkPoint* positions = reinterpret_cast<const SkPoint*>(pos); SkAutoTMalloc<SkPoint> positionsBuffer; if (2 != scalarsPerPos) { @@ -1680,7 +1683,7 @@ void SkPDFDevice::drawFormXObjectWithMask(int xObjectIndex, } auto sMaskGS = SkPDFGraphicState::GetSMaskGraphicState( - mask, invertClip, SkPDFGraphicState::kAlpha_SMaskMode, fCanon); + mask, invertClip, SkPDFGraphicState::kAlpha_SMaskMode, fDocument->canon()); SkMatrix identity; identity.reset(); @@ -1697,7 +1700,7 @@ void SkPDFDevice::drawFormXObjectWithMask(int xObjectIndex, // Call makeNoSmaskGraphicState() instead of // SkPDFGraphicState::MakeNoSmaskGraphicState so that the canon // can deduplicate. - sMaskGS = fCanon->makeNoSmaskGraphicState(); + sMaskGS = fDocument->canon()->makeNoSmaskGraphicState(); SkPDFUtils::ApplyGraphicState(addGraphicStateResource(sMaskGS.get()), &content.entry()->fContent); } @@ -2004,7 +2007,7 @@ void SkPDFDevice::populateGraphicStateEntryFromPaint( SkScalar rasterScale = SkIntToScalar(fRasterDpi) / DPI_FOR_RASTER_SCALE_ONE; pdfShader.reset(SkPDFShader::GetPDFShader( - fCanon, fRasterDpi, *shader, transform, bounds, rasterScale)); + fDocument, fRasterDpi, *shader, transform, bounds, rasterScale)); if (pdfShader.get()) { // pdfShader has been canonicalized so we can directly compare @@ -2035,12 +2038,12 @@ void SkPDFDevice::populateGraphicStateEntryFromPaint( sk_sp<SkPDFGraphicState> newGraphicState; if (color == paint.getColor()) { newGraphicState.reset( - SkPDFGraphicState::GetGraphicStateForPaint(fCanon, paint)); + SkPDFGraphicState::GetGraphicStateForPaint(fDocument->canon(), paint)); } else { SkPaint newPaint = paint; newPaint.setColor(color); newGraphicState.reset( - SkPDFGraphicState::GetGraphicStateForPaint(fCanon, newPaint)); + SkPDFGraphicState::GetGraphicStateForPaint(fDocument->canon(), newPaint)); } int resourceIndex = addGraphicStateResource(newGraphicState.get()); entry->fGraphicStateIndex = resourceIndex; @@ -2097,7 +2100,7 @@ void SkPDFDevice::updateFont(const SkPaint& paint, uint16_t glyphID, int SkPDFDevice::getFontResourceIndex(SkTypeface* typeface, uint16_t glyphID) { sk_sp<SkPDFFont> newFont( - SkPDFFont::GetFontResource(fCanon, typeface, glyphID)); + SkPDFFont::GetFontResource(fDocument->canon(), typeface, glyphID)); int resourceIndex = fFontResources.find(newFont.get()); if (resourceIndex < 0) { resourceIndex = fFontResources.count(); @@ -2261,14 +2264,20 @@ void SkPDFDevice::internalDrawImage(const SkMatrix& origMatrix, // TODO(halcanary): de-dupe this by caching filtered images. // (maybe in the resource cache?) } - sk_sp<SkPDFObject> pdfimage(SkSafeRef(fCanon->findPDFBitmap(image))); + sk_sp<SkPDFObject> pdfimage(SkSafeRef(fDocument->canon()->findPDFBitmap(image))); if (!pdfimage) { pdfimage.reset(SkPDFCreateBitmapObject( - image, fCanon->getPixelSerializer())); + image, fDocument->canon()->getPixelSerializer())); if (!pdfimage) { return; } - fCanon->addPDFBitmap(image->uniqueID(), pdfimage.get()); + #if SK_PDF_SERIALIZE_IMAGES_EARLY // TODO(halcanary): enable. + sk_sp<SkData> encodedImage(image->refEncodedData()); + if (!encodedImage) { + fDocument->serialize(pdfimage); + } + #endif + fDocument->canon()->addPDFBitmap(image->uniqueID(), pdfimage.get()); } SkPDFUtils::DrawFormXObject(this->addXObjectResource(pdfimage.get()), &content.entry()->fContent); diff --git a/src/pdf/SkPDFDevice.h b/src/pdf/SkPDFDevice.h index b214839f5a..138ec19b59 100644 --- a/src/pdf/SkPDFDevice.h +++ b/src/pdf/SkPDFDevice.h @@ -25,6 +25,7 @@ class SkPDFArray; class SkPDFCanon; class SkPDFDevice; +class SkPDFDocument; class SkPDFDict; class SkPDFFont; class SkPDFFormXObject; @@ -59,20 +60,23 @@ public: * while rendering, and it would be slower to be processed * or sent online or to printer. A good choice is * SK_ScalarDefaultRasterDPI(72.0f). - * @param SkPDFCanon. Should be non-null, and shared by all - * devices in a document. + * @param SkPDFDocument. A non-null pointer back to the + * document. The document is repsonsible for + * de-duplicating across pages (via the SkPDFCanon) and + * for early serializing of large immutable objects, such + * as images (via SkPDFDocument::serialize()). */ static SkPDFDevice* Create(SkISize pageSize, SkScalar rasterDpi, - SkPDFCanon* canon) { - return new SkPDFDevice(pageSize, rasterDpi, canon, true); + SkPDFDocument* doc) { + return new SkPDFDevice(pageSize, rasterDpi, doc, true); } /** Create a PDF drawing context without fipping the y-axis. */ static SkPDFDevice* CreateUnflipped(SkISize pageSize, SkScalar rasterDpi, - SkPDFCanon* canon) { - return new SkPDFDevice(pageSize, rasterDpi, canon, false); + SkPDFDocument* doc) { + return new SkPDFDevice(pageSize, rasterDpi, doc, false); } virtual ~SkPDFDevice(); @@ -184,7 +188,7 @@ public: return *(fFontGlyphUsage.get()); } - SkPDFCanon* getCanon() const { return fCanon; } + SkPDFCanon* getCanon() const; protected: const SkBitmap& onAccessBitmap() override { @@ -261,12 +265,12 @@ private: SkBitmap fLegacyBitmap; - SkPDFCanon* fCanon; // Owned by SkDocument_PDF + SkPDFDocument* fDocument; //////////////////////////////////////////////////////////////////////////// SkPDFDevice(SkISize pageSize, SkScalar rasterDpi, - SkPDFCanon* canon, + SkPDFDocument* doc, bool flip); ContentEntry* getLastContentEntry(); diff --git a/src/pdf/SkPDFDocument.cpp b/src/pdf/SkPDFDocument.cpp index 33f944c025..66635a98fb 100644 --- a/src/pdf/SkPDFDocument.cpp +++ b/src/pdf/SkPDFDocument.cpp @@ -276,7 +276,7 @@ SkCanvas* SkPDFDocument::onBeginPage(SkScalar width, SkScalar height, SkISize pageSize = SkISize::Make( SkScalarRoundToInt(width), SkScalarRoundToInt(height)); sk_sp<SkPDFDevice> device( - SkPDFDevice::Create(pageSize, fRasterDpi, &fCanon)); + SkPDFDevice::Create(pageSize, fRasterDpi, this)); fCanvas = sk_make_sp<SkPDFCanvas>(device); fPageDevices.push_back(std::move(device)); fCanvas->clipRect(trimBox); diff --git a/src/pdf/SkPDFDocument.h b/src/pdf/SkPDFDocument.h index de1d8830bc..0528d76e1a 100644 --- a/src/pdf/SkPDFDocument.h +++ b/src/pdf/SkPDFDocument.h @@ -11,6 +11,8 @@ #include "SkPDFMetadata.h" #include "SkPDFTypes.h" +class SkPDFDevice; + sk_sp<SkDocument> SkPDFMakeDocument( SkWStream* stream, void (*doneProc)(SkWStream*, bool), diff --git a/src/pdf/SkPDFShader.cpp b/src/pdf/SkPDFShader.cpp index f5e5b1e439..a9f2754226 100644 --- a/src/pdf/SkPDFShader.cpp +++ b/src/pdf/SkPDFShader.cpp @@ -12,6 +12,7 @@ #include "SkData.h" #include "SkPDFCanon.h" #include "SkPDFDevice.h" +#include "SkPDFDocument.h" #include "SkPDFFormXObject.h" #include "SkPDFGraphicState.h" #include "SkPDFResourceDict.h" @@ -485,10 +486,11 @@ SkPDFImageShader::~SkPDFImageShader() {} //////////////////////////////////////////////////////////////////////////////// static SkPDFObject* get_pdf_shader_by_state( - SkPDFCanon* canon, + SkPDFDocument* doc, SkScalar dpi, SkAutoTDelete<SkPDFShader::State>* autoState) { const SkPDFShader::State& state = **autoState; + SkPDFCanon* canon = doc->canon(); if (state.fType == SkShader::kNone_GradientType && state.fImage.isNull()) { // TODO(vandebo) This drops SKComposeShader on the floor. We could // handle compose shader by pulling things up to a layer, drawing with @@ -498,11 +500,11 @@ static SkPDFObject* get_pdf_shader_by_state( } else if (state.fType == SkShader::kNone_GradientType) { SkPDFObject* shader = canon->findImageShader(state); return shader ? SkRef(shader) - : SkPDFImageShader::Create(canon, dpi, autoState); + : SkPDFImageShader::Create(doc, dpi, autoState); } else if (state.GradientHasAlpha()) { SkPDFObject* shader = canon->findAlphaShader(state); return shader ? SkRef(shader) - : SkPDFAlphaFunctionShader::Create(canon, dpi, autoState); + : SkPDFAlphaFunctionShader::Create(doc, dpi, autoState); } else { SkPDFObject* shader = canon->findFunctionShader(state); return shader ? SkRef(shader) @@ -511,14 +513,14 @@ static SkPDFObject* get_pdf_shader_by_state( } // static -SkPDFObject* SkPDFShader::GetPDFShader(SkPDFCanon* canon, +SkPDFObject* SkPDFShader::GetPDFShader(SkPDFDocument* doc, SkScalar dpi, const SkShader& shader, const SkMatrix& matrix, const SkIRect& surfaceBBox, SkScalar rasterScale) { SkAutoTDelete<SkPDFShader::State> state(new State(shader, matrix, surfaceBBox, rasterScale)); - return get_pdf_shader_by_state(canon, dpi, &state); + return get_pdf_shader_by_state(doc, dpi, &state); } static sk_sp<SkPDFDict> get_gradient_resource_dict( @@ -579,14 +581,14 @@ static SkStream* create_pattern_fill_content(int gsIndex, SkRect& bounds) { * luminosity mode. The shader pattern extends to the bbox. */ static sk_sp<SkPDFObject> create_smask_graphic_state( - SkPDFCanon* canon, SkScalar dpi, const SkPDFShader::State& state) { + SkPDFDocument* doc, SkScalar dpi, const SkPDFShader::State& state) { SkRect bbox; bbox.set(state.fBBox); SkAutoTDelete<SkPDFShader::State> alphaToLuminosityState( state.CreateAlphaToLuminosityState()); sk_sp<SkPDFObject> luminosityShader( - get_pdf_shader_by_state(canon, dpi, &alphaToLuminosityState)); + get_pdf_shader_by_state(doc, dpi, &alphaToLuminosityState)); SkAutoTDelete<SkStream> alphaStream(create_pattern_fill_content(-1, bbox)); @@ -598,11 +600,11 @@ static sk_sp<SkPDFObject> create_smask_graphic_state( return SkPDFGraphicState::GetSMaskGraphicState( alphaMask.get(), false, - SkPDFGraphicState::kLuminosity_SMaskMode, canon); + SkPDFGraphicState::kLuminosity_SMaskMode, doc->canon()); } SkPDFAlphaFunctionShader* SkPDFAlphaFunctionShader::Create( - SkPDFCanon* canon, + SkPDFDocument* doc, SkScalar dpi, SkAutoTDelete<SkPDFShader::State>* autoState) { const SkPDFShader::State& state = **autoState; @@ -612,14 +614,14 @@ SkPDFAlphaFunctionShader* SkPDFAlphaFunctionShader::Create( SkAutoTDelete<SkPDFShader::State> opaqueState(state.CreateOpaqueState()); sk_sp<SkPDFObject> colorShader( - get_pdf_shader_by_state(canon, dpi, &opaqueState)); + get_pdf_shader_by_state(doc, dpi, &opaqueState)); if (!colorShader) { return nullptr; } // Create resource dict with alpha graphics state as G0 and // pattern shader as P0, then write content stream. - auto alphaGs = create_smask_graphic_state(canon, dpi, state); + auto alphaGs = create_smask_graphic_state(doc, dpi, state); SkPDFAlphaFunctionShader* alphaFunctionShader = new SkPDFAlphaFunctionShader(autoState->release()); @@ -633,7 +635,7 @@ SkPDFAlphaFunctionShader* SkPDFAlphaFunctionShader::Create( populate_tiling_pattern_dict(alphaFunctionShader, bbox, resourceDict.get(), SkMatrix::I()); - canon->addAlphaShader(alphaFunctionShader); + doc->canon()->addAlphaShader(alphaFunctionShader); return alphaFunctionShader; } @@ -820,7 +822,7 @@ SkPDFFunctionShader* SkPDFFunctionShader::Create( } SkPDFImageShader* SkPDFImageShader::Create( - SkPDFCanon* canon, + SkPDFDocument* doc, SkScalar dpi, SkAutoTDelete<SkPDFShader::State>* autoState) { const SkPDFShader::State& state = **autoState; @@ -860,7 +862,7 @@ SkPDFImageShader* SkPDFImageShader::Create( SkISize size = SkISize::Make(SkScalarRoundToInt(deviceBounds.width()), SkScalarRoundToInt(deviceBounds.height())); sk_sp<SkPDFDevice> patternDevice( - SkPDFDevice::CreateUnflipped(size, dpi, canon)); + SkPDFDevice::CreateUnflipped(size, dpi, doc)); SkCanvas canvas(patternDevice.get()); SkRect patternBBox; @@ -1030,7 +1032,7 @@ SkPDFImageShader* SkPDFImageShader::Create( imageShader->fShaderState->fImage.unlockPixels(); - canon->addImageShader(imageShader); + doc->canon()->addImageShader(imageShader); return imageShader; } diff --git a/src/pdf/SkPDFShader.h b/src/pdf/SkPDFShader.h index 029966a829..a646aef75c 100644 --- a/src/pdf/SkPDFShader.h +++ b/src/pdf/SkPDFShader.h @@ -14,6 +14,7 @@ #include "SkPDFTypes.h" class SkPDFCanon; +class SkPDFDocument; class SkMatrix; class SkShader; struct SkIRect; @@ -42,7 +43,7 @@ public: * @param rasterScale Additional scale to be applied for early * rasterization. */ - static SkPDFObject* GetPDFShader(SkPDFCanon* canon, + static SkPDFObject* GetPDFShader(SkPDFDocument* doc, SkScalar dpi, const SkShader& shader, const SkMatrix& matrix, @@ -72,7 +73,7 @@ private: */ class SkPDFAlphaFunctionShader final : public SkPDFStream { public: - static SkPDFAlphaFunctionShader* Create(SkPDFCanon*, + static SkPDFAlphaFunctionShader* Create(SkPDFDocument*, SkScalar dpi, SkAutoTDelete<SkPDFShader::State>*); virtual ~SkPDFAlphaFunctionShader(); @@ -86,7 +87,7 @@ private: class SkPDFImageShader final : public SkPDFStream { public: - static SkPDFImageShader* Create(SkPDFCanon*, + static SkPDFImageShader* Create(SkPDFDocument*, SkScalar dpi, SkAutoTDelete<SkPDFShader::State>*); virtual ~SkPDFImageShader(); |