diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/pdf/SkPDFCanon.cpp | 22 | ||||
-rw-r--r-- | src/pdf/SkPDFCanon.h | 7 | ||||
-rw-r--r-- | src/pdf/SkPDFDevice.cpp | 9 | ||||
-rw-r--r-- | src/pdf/SkPDFGraphicState.cpp | 38 | ||||
-rw-r--r-- | src/pdf/SkPDFGraphicState.h | 25 | ||||
-rw-r--r-- | src/pdf/SkPDFShader.cpp | 30 | ||||
-rw-r--r-- | src/pdf/SkPDFShader.h | 2 |
7 files changed, 74 insertions, 59 deletions
diff --git a/src/pdf/SkPDFCanon.cpp b/src/pdf/SkPDFCanon.cpp index 4fdaa0db62..d7aea8ad69 100644 --- a/src/pdf/SkPDFCanon.cpp +++ b/src/pdf/SkPDFCanon.cpp @@ -149,3 +149,25 @@ const SkImage* SkPDFCanon::bitmapToImage(const SkBitmap& bm) { bm.copyTo(&n32bitmap, kN32_SkColorType); return *fBitmapToImageMap.set(key, SkImage::NewFromBitmap(n32bitmap)); } + +sk_sp<SkPDFStream> SkPDFCanon::makeInvertFunction() { + if (fInvertFunction) { + return fInvertFunction; + } + fInvertFunction = SkPDFGraphicState::MakeInvertFunction(); + return fInvertFunction; +} +sk_sp<SkPDFDict> SkPDFCanon::makeNoSmaskGraphicState() { + if (fNoSmaskGraphicState) { + return fNoSmaskGraphicState; + } + fNoSmaskGraphicState = SkPDFGraphicState::MakeNoSmaskGraphicState(); + return fNoSmaskGraphicState; +} +sk_sp<SkPDFArray> SkPDFCanon::makeRangeObject() { + if (fRangeObject) { + return fRangeObject; + } + fRangeObject = SkPDFShader::MakeRangeObject(); + return fRangeObject; +} diff --git a/src/pdf/SkPDFCanon.h b/src/pdf/SkPDFCanon.h index 80b1f83e8a..9ca8a261d6 100644 --- a/src/pdf/SkPDFCanon.h +++ b/src/pdf/SkPDFCanon.h @@ -84,6 +84,10 @@ public: SkPixelSerializer* getPixelSerializer() const { return fPixelSerializer.get(); } void setPixelSerializer(SkPixelSerializer* ps) { fPixelSerializer.reset(ps); } + sk_sp<SkPDFStream> makeInvertFunction(); + sk_sp<SkPDFDict> makeNoSmaskGraphicState(); + sk_sp<SkPDFArray> makeRangeObject(); + private: struct FontRec { SkPDFFont* fFont; @@ -119,5 +123,8 @@ private: SkTHashMap<uint32_t /*ImageUniqueID*/, SkPDFObject*> fPDFBitmapMap; sk_sp<SkPixelSerializer> fPixelSerializer; + sk_sp<SkPDFStream> fInvertFunction; + sk_sp<SkPDFDict> fNoSmaskGraphicState; + sk_sp<SkPDFArray> fRangeObject; }; #endif // SkPDFCanon_DEFINED diff --git a/src/pdf/SkPDFDevice.cpp b/src/pdf/SkPDFDevice.cpp index 744d42d25e..e349ce42fb 100644 --- a/src/pdf/SkPDFDevice.cpp +++ b/src/pdf/SkPDFDevice.cpp @@ -1742,8 +1742,8 @@ void SkPDFDevice::drawFormXObjectWithMask(int xObjectIndex, return; } - sk_sp<SkPDFObject> sMaskGS(SkPDFGraphicState::GetSMaskGraphicState( - mask, invertClip, SkPDFGraphicState::kAlpha_SMaskMode)); + auto sMaskGS = SkPDFGraphicState::GetSMaskGraphicState( + mask, invertClip, SkPDFGraphicState::kAlpha_SMaskMode, fCanon); SkMatrix identity; identity.reset(); @@ -1757,7 +1757,10 @@ void SkPDFDevice::drawFormXObjectWithMask(int xObjectIndex, &content.entry()->fContent); SkPDFUtils::DrawFormXObject(xObjectIndex, &content.entry()->fContent); - sMaskGS.reset(SkPDFGraphicState::GetNoSMaskGraphicState()); + // Call makeNoSmaskGraphicState() instead of + // SkPDFGraphicState::MakeNoSmaskGraphicState so that the canon + // can deduplicate. + sMaskGS = fCanon->makeNoSmaskGraphicState(); SkPDFUtils::ApplyGraphicState(addGraphicStateResource(sMaskGS.get()), &content.entry()->fContent); } diff --git a/src/pdf/SkPDFGraphicState.cpp b/src/pdf/SkPDFGraphicState.cpp index 8fad7497c2..efa49baf45 100644 --- a/src/pdf/SkPDFGraphicState.cpp +++ b/src/pdf/SkPDFGraphicState.cpp @@ -6,12 +6,10 @@ */ #include "SkData.h" -#include "SkOncePtr.h" #include "SkPDFCanon.h" #include "SkPDFFormXObject.h" #include "SkPDFGraphicState.h" #include "SkPDFUtils.h" -#include "SkTypes.h" static const char* as_blend_mode(SkXfermode::Mode mode) { switch (mode) { @@ -126,7 +124,7 @@ SkPDFGraphicState* SkPDFGraphicState::GetGraphicStateForPaint( return pdfGraphicState; } -static SkPDFStream* create_invert_function() { +sk_sp<SkPDFStream> SkPDFGraphicState::MakeInvertFunction() { // Acrobat crashes if we use a type 0 function, kpdf crashes if we use // a type 2 function, so we use a type 4 function. auto domainAndRange = sk_make_sp<SkPDFArray>(); @@ -143,20 +141,14 @@ static SkPDFStream* create_invert_function() { invertFunction->insertInt("FunctionType", 4); invertFunction->insertObject("Domain", domainAndRange); invertFunction->insertObject("Range", std::move(domainAndRange)); - return invertFunction.release(); + return invertFunction; } -SK_DECLARE_STATIC_ONCE_PTR(SkPDFStream, invertFunction); - -static sk_sp<SkPDFStream> make_invert_function() { - return sk_sp<SkPDFStream>( - SkRef(invertFunction.get(create_invert_function))); -} - -// static -SkPDFDict* SkPDFGraphicState::GetSMaskGraphicState(SkPDFFormXObject* sMask, - bool invert, - SkPDFSMaskMode sMaskMode) { +sk_sp<SkPDFDict> SkPDFGraphicState::GetSMaskGraphicState( + SkPDFFormXObject* sMask, + bool invert, + SkPDFSMaskMode sMaskMode, + SkPDFCanon* canon) { // The practical chances of using the same mask more than once are unlikely // enough that it's not worth canonicalizing. auto sMaskDict = sk_make_sp<SkPDFDict>("Mask"); @@ -167,25 +159,21 @@ SkPDFDict* SkPDFGraphicState::GetSMaskGraphicState(SkPDFFormXObject* sMask, } sMaskDict->insertObjRef("G", sk_ref_sp(sMask)); if (invert) { - sMaskDict->insertObjRef("TR", make_invert_function()); + // Instead of calling SkPDFGraphicState::MakeInvertFunction, + // let the canon deduplicate this object. + sMaskDict->insertObjRef("TR", canon->makeInvertFunction()); } auto result = sk_make_sp<SkPDFDict>("ExtGState"); result->insertObject("SMask", std::move(sMaskDict)); - return result.release(); + return result; } -static SkPDFDict* create_no_smask_graphic_state() { - SkPDFDict* noSMaskGS = new SkPDFDict("ExtGState"); +sk_sp<SkPDFDict> SkPDFGraphicState::MakeNoSmaskGraphicState() { + auto noSMaskGS = sk_make_sp<SkPDFDict>("ExtGState"); noSMaskGS->insertName("SMask", "None"); return noSMaskGS; } -SK_DECLARE_STATIC_ONCE_PTR(SkPDFDict, noSMaskGraphicState); - -// static -SkPDFDict* SkPDFGraphicState::GetNoSMaskGraphicState() { - return SkRef(noSMaskGraphicState.get(create_no_smask_graphic_state)); -} void SkPDFGraphicState::emitObject( SkWStream* stream, diff --git a/src/pdf/SkPDFGraphicState.h b/src/pdf/SkPDFGraphicState.h index d816f72120..31848e8cac 100644 --- a/src/pdf/SkPDFGraphicState.h +++ b/src/pdf/SkPDFGraphicState.h @@ -11,7 +11,7 @@ #define SkPDFGraphicState_DEFINED #include "SkPaint.h" -#include "SkPDFTypes.h" +#include "SkPDFStream.h" #include "SkChecksum.h" class SkPDFCanon; @@ -46,28 +46,21 @@ public: static SkPDFGraphicState* GetGraphicStateForPaint(SkPDFCanon* canon, const SkPaint& paint); - /** Make a graphic state that only sets the passed soft mask. The - * reference count of the object is incremented and it is the caller's - * responsibility to unreference it when done. + /** Make a graphic state that only sets the passed soft mask. * @param sMask The form xobject to use as a soft mask. * @param invert Indicates if the alpha of the sMask should be inverted. * @param sMaskMode Whether to use alpha or luminosity for the sMask. * * These are not de-duped. */ - static SkPDFDict* GetSMaskGraphicState(SkPDFFormXObject* sMask, - bool invert, - SkPDFSMaskMode sMaskMode); + static sk_sp<SkPDFDict> GetSMaskGraphicState(SkPDFFormXObject* sMask, + bool invert, + SkPDFSMaskMode sMaskMode, + SkPDFCanon* canon); - /** Get a graphic state that only unsets the soft mask. The reference - * count of the object is incremented and it is the caller's responsibility - * to unreference it when done. This is needed to accommodate the weak - * reference pattern used when the returned object is new and has no - * other references. - * - * The returned object is a singleton. - */ - static SkPDFDict* GetNoSMaskGraphicState(); + /** Make a graphic state that only unsets the soft mask. */ + static sk_sp<SkPDFDict> MakeNoSmaskGraphicState(); + static sk_sp<SkPDFStream> MakeInvertFunction(); bool operator==(const SkPDFGraphicState& rhs) const { return 0 == memcmp(&fStrokeWidth, &rhs.fStrokeWidth, 12); diff --git a/src/pdf/SkPDFShader.cpp b/src/pdf/SkPDFShader.cpp index e30e43d4f8..2ae3217585 100644 --- a/src/pdf/SkPDFShader.cpp +++ b/src/pdf/SkPDFShader.cpp @@ -10,7 +10,6 @@ #include "SkPDFShader.h" #include "SkData.h" -#include "SkOncePtr.h" #include "SkPDFCanon.h" #include "SkPDFDevice.h" #include "SkPDFFormXObject.h" @@ -20,7 +19,6 @@ #include "SkScalar.h" #include "SkStream.h" #include "SkTemplates.h" -#include "SkTypes.h" static bool inverse_transform_bbox(const SkMatrix& matrix, SkRect* bbox) { SkMatrix inverse; @@ -580,7 +578,7 @@ static SkStream* create_pattern_fill_content(int gsIndex, SkRect& bounds) { * Creates a ExtGState with the SMask set to the luminosityShader in * luminosity mode. The shader pattern extends to the bbox. */ -static SkPDFObject* create_smask_graphic_state( +static sk_sp<SkPDFObject> create_smask_graphic_state( SkPDFCanon* canon, SkScalar dpi, const SkPDFShader::State& state) { SkRect bbox; bbox.set(state.fBBox); @@ -600,7 +598,7 @@ static SkPDFObject* create_smask_graphic_state( return SkPDFGraphicState::GetSMaskGraphicState( alphaMask.get(), false, - SkPDFGraphicState::kLuminosity_SMaskMode); + SkPDFGraphicState::kLuminosity_SMaskMode, canon); } SkPDFAlphaFunctionShader* SkPDFAlphaFunctionShader::Create( @@ -621,8 +619,7 @@ SkPDFAlphaFunctionShader* SkPDFAlphaFunctionShader::Create( // Create resource dict with alpha graphics state as G0 and // pattern shader as P0, then write content stream. - sk_sp<SkPDFObject> alphaGs( - create_smask_graphic_state(canon, dpi, state)); + auto alphaGs = create_smask_graphic_state(canon, dpi, state); SkPDFAlphaFunctionShader* alphaFunctionShader = new SkPDFAlphaFunctionShader(autoState->detach()); @@ -678,8 +675,8 @@ static bool split_perspective(const SkMatrix in, SkMatrix* affine, return true; } -static SkPDFObject* create_range_object() { - SkPDFArray* range = new SkPDFArray; +sk_sp<SkPDFArray> SkPDFShader::MakeRangeObject() { + auto range = sk_make_sp<SkPDFArray>(); range->reserve(6); range->appendInt(0); range->appendInt(1); @@ -689,16 +686,16 @@ static SkPDFObject* create_range_object() { range->appendInt(1); return range; } -SK_DECLARE_STATIC_ONCE_PTR(SkPDFObject, rangeObject); -static SkPDFStream* make_ps_function(const SkString& psCode, - SkPDFArray* domain) { +static sk_sp<SkPDFStream> make_ps_function(const SkString& psCode, + SkPDFArray* domain, + sk_sp<SkPDFObject> range) { SkAutoDataUnref funcData( SkData::NewWithCopy(psCode.c_str(), psCode.size())); - SkPDFStream* result = new SkPDFStream(funcData.get()); + auto result = sk_make_sp<SkPDFStream>(funcData.get()); result->insertInt("FunctionType", 4); result->insertObject("Domain", sk_ref_sp(domain)); - result->insertObject("Range", sk_ref_sp(rangeObject.get(create_range_object))); + result->insertObject("Range", std::move(range)); return result; } @@ -804,8 +801,11 @@ SkPDFFunctionShader* SkPDFFunctionShader::Create( pdfShader->insertName("ColorSpace", "DeviceRGB"); pdfShader->insertObject("Domain", sk_ref_sp(domain.get())); - sk_sp<SkPDFStream> function( - make_ps_function(functionCode, domain.get())); + // Call canon->makeRangeObject() instead of + // SkPDFShader::MakeRangeObject() so that the canon can + // deduplicate. + auto function = make_ps_function(functionCode, domain.get(), + canon->makeRangeObject()); pdfShader->insertObjRef("Function", std::move(function)); sk_sp<SkPDFFunctionShader> pdfFunctionShader( diff --git a/src/pdf/SkPDFShader.h b/src/pdf/SkPDFShader.h index 61b6de663d..029966a829 100644 --- a/src/pdf/SkPDFShader.h +++ b/src/pdf/SkPDFShader.h @@ -48,6 +48,8 @@ public: const SkMatrix& matrix, const SkIRect& surfaceBBox, SkScalar rasterScale); + + static sk_sp<SkPDFArray> MakeRangeObject(); }; class SkPDFFunctionShader final : public SkPDFDict { |