aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--src/pdf/SkPDFCanon.cpp22
-rw-r--r--src/pdf/SkPDFCanon.h7
-rw-r--r--src/pdf/SkPDFDevice.cpp9
-rw-r--r--src/pdf/SkPDFGraphicState.cpp38
-rw-r--r--src/pdf/SkPDFGraphicState.h25
-rw-r--r--src/pdf/SkPDFShader.cpp30
-rw-r--r--src/pdf/SkPDFShader.h2
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 {