PDF: Now threadsafe!
The PDF canvas is now just as threadsafe as any other Skia canvas.
DM updated to thread PDF tests.
SkDocument_PDF now owns SkPDFCanon, and pointers to that canon are
passed around to all classes that need access to the canon.
BUG=skia:2683
Review URL: https://codereview.chromium.org/944643002
diff --git a/dm/DMSrcSink.h b/dm/DMSrcSink.h
index abf3ef8..8cd92a6 100644
--- a/dm/DMSrcSink.h
+++ b/dm/DMSrcSink.h
@@ -42,8 +42,8 @@
virtual const char* fileExtension() const = 0;
};
-enum { kAnyThread_Enclave, kGPU_Enclave, kPDFSink_Enclave };
-static const int kNumEnclaves = kPDFSink_Enclave + 1;
+enum { kAnyThread_Enclave, kGPU_Enclave };
+static const int kNumEnclaves = kGPU_Enclave + 1;
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
@@ -115,7 +115,7 @@
PDFSink();
Error draw(const Src&, SkBitmap*, SkWStream*, SkString*) const SK_OVERRIDE;
- int enclave() const SK_OVERRIDE { return kPDFSink_Enclave; }
+ int enclave() const SK_OVERRIDE { return kAnyThread_Enclave; }
const char* fileExtension() const SK_OVERRIDE { return "pdf"; }
};
diff --git a/src/doc/SkDocument_PDF.cpp b/src/doc/SkDocument_PDF.cpp
index e73b888..468111c 100644
--- a/src/doc/SkDocument_PDF.cpp
+++ b/src/doc/SkDocument_PDF.cpp
@@ -13,7 +13,7 @@
class SkDocument_PDF : public SkDocument {
public:
SkDocument_PDF(SkWStream* stream,
- void (*doneProc)(SkWStream*,bool),
+ void (*doneProc)(SkWStream*, bool),
SkScalar rasterDpi)
: SkDocument(stream, doneProc)
, fDoc(SkNEW(SkPDFDocument))
diff --git a/src/pdf/SkPDFBitmap.cpp b/src/pdf/SkPDFBitmap.cpp
index b65709c..f8742a6 100644
--- a/src/pdf/SkPDFBitmap.cpp
+++ b/src/pdf/SkPDFBitmap.cpp
@@ -247,13 +247,12 @@
pdfDict.emitObject(stream, catalog);
}
-SkPDFBitmap::SkPDFBitmap(const SkBitmap& bm, SkPDFObject* smask)
- : fBitmap(bm), fSMask(smask) {}
+SkPDFBitmap::SkPDFBitmap(SkPDFCanon* canon,
+ const SkBitmap& bm,
+ SkPDFObject* smask)
+ : fCanon(canon), fBitmap(bm), fSMask(smask) {}
-SkPDFBitmap::~SkPDFBitmap() {
- SkAutoMutexAcquire autoMutexAcquire(SkPDFCanon::GetBitmapMutex());
- SkPDFCanon::GetCanon().removeBitmap(this);
-}
+SkPDFBitmap::~SkPDFBitmap() { fCanon->removeBitmap(this); }
////////////////////////////////////////////////////////////////////////////////
static bool is_transparent(const SkBitmap& bm) {
@@ -275,9 +274,10 @@
return true;
}
-// TODO(halcanary): SkPDFBitmap::Create should take a SkPDFCanon* parameter.
-SkPDFBitmap* SkPDFBitmap::Create(const SkBitmap& bitmap,
+SkPDFBitmap* SkPDFBitmap::Create(SkPDFCanon* canon,
+ const SkBitmap& bitmap,
const SkIRect& subset) {
+ SkASSERT(canon);
if (kN32_SkColorType != bitmap.colorType()) {
// TODO(halcanary): support other colortypes.
return NULL;
@@ -299,9 +299,7 @@
bm = copy;
}
- SkAutoMutexAcquire autoMutexAcquire(SkPDFCanon::GetBitmapMutex());
- SkPDFCanon& canon = SkPDFCanon::GetCanon();
- SkPDFBitmap* pdfBitmap = canon.findBitmap(bm);
+ SkPDFBitmap* pdfBitmap = canon->findBitmap(bm);
if (pdfBitmap) {
return SkRef(pdfBitmap);
}
@@ -314,7 +312,7 @@
// are refed by the SkPDFBitmap).
smask = SkNEW_ARGS(PDFAlphaBitmap, (bm));
}
- pdfBitmap = SkNEW_ARGS(SkPDFBitmap, (bm, smask));
- canon.addBitmap(pdfBitmap);
+ pdfBitmap = SkNEW_ARGS(SkPDFBitmap, (canon, bm, smask));
+ canon->addBitmap(pdfBitmap);
return pdfBitmap;
}
diff --git a/src/pdf/SkPDFBitmap.h b/src/pdf/SkPDFBitmap.h
index 922db8f..eae6877 100644
--- a/src/pdf/SkPDFBitmap.h
+++ b/src/pdf/SkPDFBitmap.h
@@ -10,6 +10,8 @@
#include "SkPDFTypes.h"
#include "SkBitmap.h"
+class SkPDFCanon;
+
/**
* SkPDFBitmap wraps a SkBitmap and serializes it as an image Xobject.
* It is designed to use a minimal amout of memory, aside from refing
@@ -24,7 +26,9 @@
// Returns NULL on unsupported bitmap;
// TODO(halcanary): support other bitmap colortypes and replace
// SkPDFImage.
- static SkPDFBitmap* Create(const SkBitmap&, const SkIRect& subset);
+ static SkPDFBitmap* Create(SkPDFCanon*,
+ const SkBitmap&,
+ const SkIRect& subset);
~SkPDFBitmap();
void emitObject(SkWStream*, SkPDFCatalog*) SK_OVERRIDE;
void addResources(SkTSet<SkPDFObject*>* resourceSet,
@@ -36,9 +40,10 @@
}
private:
+ SkPDFCanon* const fCanon;
const SkBitmap fBitmap;
const SkAutoTUnref<SkPDFObject> fSMask;
- SkPDFBitmap(const SkBitmap&, SkPDFObject*);
+ SkPDFBitmap(SkPDFCanon*, const SkBitmap&, SkPDFObject*);
void emitDict(SkWStream*, SkPDFCatalog*, size_t, bool) const;
};
diff --git a/src/pdf/SkPDFCanon.cpp b/src/pdf/SkPDFCanon.cpp
index 268a53a..8bbe835 100644
--- a/src/pdf/SkPDFCanon.cpp
+++ b/src/pdf/SkPDFCanon.cpp
@@ -5,7 +5,6 @@
* found in the LICENSE file.
*/
-#include "SkLazyPtr.h"
#include "SkPDFBitmap.h"
#include "SkPDFCanon.h"
#include "SkPDFFont.h"
@@ -14,32 +13,12 @@
////////////////////////////////////////////////////////////////////////////////
-SK_DECLARE_STATIC_MUTEX(gSkPDFCanonFontMutex);
-SK_DECLARE_STATIC_MUTEX(gSkPDFCanonShaderMutex);
-SK_DECLARE_STATIC_MUTEX(gSkPDFCanonPaintMutex);
-SK_DECLARE_STATIC_MUTEX(gSkPDFCanonBitmapMutex);
-
-SkBaseMutex& SkPDFCanon::GetFontMutex() { return gSkPDFCanonFontMutex; }
-SkBaseMutex& SkPDFCanon::GetShaderMutex() { return gSkPDFCanonShaderMutex; }
-SkBaseMutex& SkPDFCanon::GetPaintMutex() { return gSkPDFCanonPaintMutex; }
-SkBaseMutex& SkPDFCanon::GetBitmapMutex() { return gSkPDFCanonBitmapMutex; }
-
SkPDFCanon::SkPDFCanon() {}
SkPDFCanon::~SkPDFCanon() {}
-SK_DECLARE_STATIC_LAZY_PTR(SkPDFCanon, singleton);
-
-SkPDFCanon& SkPDFCanon::GetCanon() { return *singleton.get(); }
-
////////////////////////////////////////////////////////////////////////////////
-static void assert_mutex_held(const SkPDFCanon* canon, SkBaseMutex& mutex) {
- if (canon == singleton.get()) {
- mutex.assertHeld();
- }
-}
-
template <class T> T* assert_ptr(T* p) { SkASSERT(p); return p; }
template <typename T>
@@ -68,7 +47,6 @@
SkPDFFont* SkPDFCanon::findFont(uint32_t fontID,
uint16_t glyphID,
SkPDFFont** relatedFontPtr) const {
- assert_mutex_held(this, gSkPDFCanonFontMutex);
SkASSERT(relatedFontPtr);
SkPDFFont* relatedFont = NULL;
@@ -87,7 +65,6 @@
}
void SkPDFCanon::addFont(SkPDFFont* font, uint32_t fontID, uint16_t fGlyphID) {
- assert_mutex_held(this, gSkPDFCanonFontMutex);
SkPDFCanon::FontRec* rec = fFontRecords.push();
rec->fFont = font;
rec->fFontID = fontID;
@@ -95,7 +72,6 @@
}
void SkPDFCanon::removeFont(SkPDFFont* pdfFont) {
- assert_mutex_held(this, gSkPDFCanonFontMutex);
for (int i = 0; i < fFontRecords.count(); i++) {
if (fFontRecords[i].fFont == pdfFont) {
fFontRecords.removeShuffle(i);
@@ -109,15 +85,12 @@
SkPDFFunctionShader* SkPDFCanon::findFunctionShader(
const SkPDFShader::State& state) const {
- assert_mutex_held(this, gSkPDFCanonShaderMutex);
return find_item(fFunctionShaderRecords, state);
}
void SkPDFCanon::addFunctionShader(SkPDFFunctionShader* pdfShader) {
- assert_mutex_held(this, gSkPDFCanonShaderMutex);
fFunctionShaderRecords.push(assert_ptr(pdfShader));
}
void SkPDFCanon::removeFunctionShader(SkPDFFunctionShader* pdfShader) {
- assert_mutex_held(this, gSkPDFCanonShaderMutex);
SkAssertResult(remove_item(&fFunctionShaderRecords, pdfShader));
}
@@ -125,15 +98,12 @@
SkPDFAlphaFunctionShader* SkPDFCanon::findAlphaShader(
const SkPDFShader::State& state) const {
- assert_mutex_held(this, gSkPDFCanonShaderMutex);
return find_item(fAlphaShaderRecords, state);
}
void SkPDFCanon::addAlphaShader(SkPDFAlphaFunctionShader* pdfShader) {
- assert_mutex_held(this, gSkPDFCanonShaderMutex);
fAlphaShaderRecords.push(assert_ptr(pdfShader));
}
void SkPDFCanon::removeAlphaShader(SkPDFAlphaFunctionShader* pdfShader) {
- assert_mutex_held(this, gSkPDFCanonShaderMutex);
SkAssertResult(remove_item(&fAlphaShaderRecords, pdfShader));
}
@@ -141,50 +111,41 @@
SkPDFImageShader* SkPDFCanon::findImageShader(
const SkPDFShader::State& state) const {
- assert_mutex_held(this, gSkPDFCanonShaderMutex);
return find_item(fImageShaderRecords, state);
}
void SkPDFCanon::addImageShader(SkPDFImageShader* pdfShader) {
- assert_mutex_held(this, gSkPDFCanonShaderMutex);
fImageShaderRecords.push(assert_ptr(pdfShader));
}
void SkPDFCanon::removeImageShader(SkPDFImageShader* pdfShader) {
- assert_mutex_held(this, gSkPDFCanonShaderMutex);
SkAssertResult(remove_item(&fImageShaderRecords, pdfShader));
}
////////////////////////////////////////////////////////////////////////////////
SkPDFGraphicState* SkPDFCanon::findGraphicState(const SkPaint& paint) const {
- assert_mutex_held(this, gSkPDFCanonPaintMutex);
return find_item(fGraphicStateRecords, paint);
}
void SkPDFCanon::addGraphicState(SkPDFGraphicState* state) {
- assert_mutex_held(this, gSkPDFCanonPaintMutex);
fGraphicStateRecords.push(assert_ptr(state));
}
void SkPDFCanon::removeGraphicState(SkPDFGraphicState* pdfGraphicState) {
- assert_mutex_held(this, gSkPDFCanonPaintMutex);
SkAssertResult(remove_item(&fGraphicStateRecords, pdfGraphicState));
}
////////////////////////////////////////////////////////////////////////////////
SkPDFBitmap* SkPDFCanon::findBitmap(const SkBitmap& bm) const {
- assert_mutex_held(this, gSkPDFCanonBitmapMutex);
return find_item(fBitmapRecords, bm);
}
void SkPDFCanon::addBitmap(SkPDFBitmap* pdfBitmap) {
- assert_mutex_held(this, gSkPDFCanonBitmapMutex);
fBitmapRecords.push(assert_ptr(pdfBitmap));
}
void SkPDFCanon::removeBitmap(SkPDFBitmap* pdfBitmap) {
- assert_mutex_held(this, gSkPDFCanonBitmapMutex);
SkAssertResult(remove_item(&fBitmapRecords, pdfBitmap));
}
diff --git a/src/pdf/SkPDFCanon.h b/src/pdf/SkPDFCanon.h
index 7c5cdf7..369106a 100644
--- a/src/pdf/SkPDFCanon.h
+++ b/src/pdf/SkPDFCanon.h
@@ -8,42 +8,33 @@
#define SkPDFCanon_DEFINED
#include "SkPDFShader.h"
-#include "SkThread.h"
#include "SkTDArray.h"
-struct SkIRect;
class SkBitmap;
-class SkMatrix;
class SkPDFFont;
class SkPDFGraphicState;
class SkPDFBitmap;
class SkPaint;
-// This class's fields and methods will eventually become part of
-// SkPDFDocument/SkDocument_PDF. For now, it exists as a singleton to
-// preflight that transition. This replaces three global arrays in
-// SkPDFFont, SkPDFShader, and SkPDFGraphicsContext.
-//
-// IF YOU ARE LOOKING AT THIS API PLEASE DO NOT WRITE THE CHANGE
-// YOU ARE ABOUT TO WRITE WITHOUT TALKING TO HALCANARY@.
-//
-// Note that this class does not create, delete, reference or
-// dereference the SkPDFObject objects that it indexes. It is up to
-// the caller to manage the lifetime of these objects.
+/**
+ * The SkPDFCanon canonicalizes objects across PDF pages(SkPDFDevices).
+ *
+ * The PDF backend works correctly if:
+ * - There is no more than one SkPDFCanon for each thread.
+ * - Every SkPDFDevice is given a pointer to a SkPDFCanon on creation.
+ * - All SkPDFDevices in a document share the same SkPDFCanon.
+ * The SkDocument_PDF class makes this happen by owning a single
+ * SkPDFCanon.
+ *
+ * Note that this class does not create, delete, reference or
+ * dereference the SkPDFObject objects that it indexes. It is up to
+ * the caller to manage the lifetime of these objects.
+ */
class SkPDFCanon : SkNoncopyable {
public:
SkPDFCanon();
~SkPDFCanon();
- static SkPDFCanon& GetCanon();
-
- // This mutexes will be removed once this class is subsumed into
- // SkPDFDocument.
- static SkBaseMutex& GetFontMutex();
- static SkBaseMutex& GetShaderMutex();
- static SkBaseMutex& GetPaintMutex();
- static SkBaseMutex& GetBitmapMutex();
-
// Returns exact match if there is one. If not, it returns NULL.
// If there is no exact match, but there is a related font, we
// still return NULL, but also set *relatedFont.
diff --git a/src/pdf/SkPDFDevice.cpp b/src/pdf/SkPDFDevice.cpp
index 7c0aaa2..90f0a4a 100644
--- a/src/pdf/SkPDFDevice.cpp
+++ b/src/pdf/SkPDFDevice.cpp
@@ -737,7 +737,7 @@
fLastMarginContentEntry = NULL;
fDrawingArea = kContent_DrawingArea;
if (fFontGlyphUsage.get() == NULL) {
- fFontGlyphUsage.reset(new SkPDFGlyphSetMap());
+ fFontGlyphUsage.reset(SkNEW(SkPDFGlyphSetMap));
}
}
@@ -1896,8 +1896,10 @@
fInitialTransform.mapRect(&boundsTemp);
boundsTemp.roundOut(&bounds);
- pdfShader.reset(SkPDFShader::GetPDFShader(*shader, transform, bounds,
- SkIntToScalar(fRasterDpi) / DPI_FOR_RASTER_SCALE_ONE));
+ SkScalar rasterScale =
+ SkIntToScalar(fRasterDpi) / DPI_FOR_RASTER_SCALE_ONE;
+ pdfShader.reset(SkPDFShader::GetPDFShader(
+ fCanon, fRasterDpi, *shader, transform, bounds, rasterScale));
if (pdfShader.get()) {
// pdfShader has been canonicalized so we can directly compare
@@ -1928,12 +1930,12 @@
SkAutoTUnref<SkPDFGraphicState> newGraphicState;
if (color == paint.getColor()) {
newGraphicState.reset(
- SkPDFGraphicState::GetGraphicStateForPaint(paint));
+ SkPDFGraphicState::GetGraphicStateForPaint(fCanon, paint));
} else {
SkPaint newPaint = paint;
newPaint.setColor(color);
newGraphicState.reset(
- SkPDFGraphicState::GetGraphicStateForPaint(newPaint));
+ SkPDFGraphicState::GetGraphicStateForPaint(fCanon, newPaint));
}
int resourceIndex = addGraphicStateResource(newGraphicState.get());
entry->fGraphicStateIndex = resourceIndex;
@@ -1989,8 +1991,8 @@
}
int SkPDFDevice::getFontResourceIndex(SkTypeface* typeface, uint16_t glyphID) {
- SkAutoTUnref<SkPDFFont> newFont(SkPDFFont::GetFontResource(typeface,
- glyphID));
+ SkAutoTUnref<SkPDFFont> newFont(
+ SkPDFFont::GetFontResource(fCanon, typeface, glyphID));
int resourceIndex = fFontResources.find(newFont.get());
if (resourceIndex < 0) {
resourceIndex = fFontResources.count();
@@ -2133,7 +2135,7 @@
}
SkAutoTUnref<SkPDFObject> image(
- SkPDFCreateImageObject(*bitmap, subset));
+ SkPDFCreateImageObject(fCanon, *bitmap, subset));
if (!image) {
return;
}
@@ -2141,4 +2143,3 @@
SkPDFUtils::DrawFormXObject(this->addXObjectResource(image.get()),
&content.entry()->fContent);
}
-
diff --git a/src/pdf/SkPDFFont.cpp b/src/pdf/SkPDFFont.cpp
index 426fbaf..f386b71 100644
--- a/src/pdf/SkPDFFont.cpp
+++ b/src/pdf/SkPDFFont.cpp
@@ -747,12 +747,7 @@
* from each page and combine it and ask for a resource with that subset.
*/
-SkPDFFont::~SkPDFFont() {
- {
- SkAutoMutexAcquire lock(SkPDFCanon::GetFontMutex());
- SkPDFCanon::GetCanon().removeFont(this);
- }
-}
+SkPDFFont::~SkPDFFont() { fCanon->removeFont(this); }
SkTypeface* SkPDFFont::typeface() {
return fTypeface.get();
@@ -804,16 +799,16 @@
}
// static
-SkPDFFont* SkPDFFont::GetFontResource(SkTypeface* typeface, uint16_t glyphID) {
+SkPDFFont* SkPDFFont::GetFontResource(SkPDFCanon* canon,
+ SkTypeface* typeface,
+ uint16_t glyphID) {
+ SkASSERT(canon);
SkAutoResolveDefaultTypeface autoResolve(typeface);
typeface = autoResolve.get();
const uint32_t fontID = typeface->uniqueID();
- SkAutoMutexAcquire lock(SkPDFCanon::GetFontMutex());
SkPDFFont* relatedFont;
- SkPDFFont* pdfFont =
- SkPDFCanon::GetCanon().findFont(fontID, glyphID, &relatedFont);
- if (pdfFont) {
+ if (SkPDFFont* pdfFont = canon->findFont(fontID, glyphID, &relatedFont)) {
return SkRef(pdfFont);
}
@@ -857,25 +852,27 @@
#endif
}
- SkPDFFont* font = Create(fontMetrics.get(), typeface, glyphID,
- relatedFontDescriptor);
- SkPDFCanon::GetCanon().addFont(font, fontID, font->fFirstGlyphID);
- return font; // Return the reference new SkPDFFont() created.
+ SkPDFFont* font = SkPDFFont::Create(canon, fontMetrics.get(), typeface,
+ glyphID, relatedFontDescriptor);
+ canon->addFont(font, fontID, font->fFirstGlyphID);
+ return font;
}
SkPDFFont* SkPDFFont::getFontSubset(const SkPDFGlyphSet*) {
return NULL; // Default: no support.
}
-SkPDFFont::SkPDFFont(const SkAdvancedTypefaceMetrics* info,
+SkPDFFont::SkPDFFont(SkPDFCanon* canon,
+ const SkAdvancedTypefaceMetrics* info,
SkTypeface* typeface,
SkPDFDict* relatedFontDescriptor)
- : SkPDFDict("Font"),
- fTypeface(ref_or_default(typeface)),
- fFirstGlyphID(1),
- fLastGlyphID(info ? info->fLastGlyphID : 0),
- fFontInfo(SkSafeRef(info)),
- fDescriptor(SkSafeRef(relatedFontDescriptor)) {
+ : SkPDFDict("Font")
+ , fCanon(canon)
+ , fTypeface(ref_or_default(typeface))
+ , fFirstGlyphID(1)
+ , fLastGlyphID(info ? info->fLastGlyphID : 0)
+ , fFontInfo(SkSafeRef(info))
+ , fDescriptor(SkSafeRef(relatedFontDescriptor)) {
if (info == NULL ||
info->fFlags & SkAdvancedTypefaceMetrics::kMultiMaster_FontFlag) {
fFontType = SkAdvancedTypefaceMetrics::kOther_Font;
@@ -885,8 +882,10 @@
}
// static
-SkPDFFont* SkPDFFont::Create(const SkAdvancedTypefaceMetrics* info,
- SkTypeface* typeface, uint16_t glyphID,
+SkPDFFont* SkPDFFont::Create(SkPDFCanon* canon,
+ const SkAdvancedTypefaceMetrics* info,
+ SkTypeface* typeface,
+ uint16_t glyphID,
SkPDFDict* relatedFontDescriptor) {
SkAdvancedTypefaceMetrics::FontType type =
info ? info->fType : SkAdvancedTypefaceMetrics::kOther_Font;
@@ -894,26 +893,22 @@
if (info &&
(info->fFlags & SkAdvancedTypefaceMetrics::kMultiMaster_FontFlag)) {
NOT_IMPLEMENTED(true, true);
- return new SkPDFType3Font(info,
- typeface,
- glyphID);
+ return new SkPDFType3Font(canon, info, typeface, glyphID);
}
if (type == SkAdvancedTypefaceMetrics::kType1CID_Font ||
type == SkAdvancedTypefaceMetrics::kTrueType_Font) {
SkASSERT(relatedFontDescriptor == NULL);
- return new SkPDFType0Font(info, typeface);
+ return new SkPDFType0Font(canon, info, typeface);
}
if (type == SkAdvancedTypefaceMetrics::kType1_Font) {
- return new SkPDFType1Font(info,
- typeface,
- glyphID,
+ return new SkPDFType1Font(canon, info, typeface, glyphID,
relatedFontDescriptor);
}
SkASSERT(type == SkAdvancedTypefaceMetrics::kCFF_Font ||
type == SkAdvancedTypefaceMetrics::kOther_Font);
- return new SkPDFType3Font(info, typeface, glyphID);
+ return new SkPDFType3Font(canon, info, typeface, glyphID);
}
const SkAdvancedTypefaceMetrics* SkPDFFont::fontInfo() {
@@ -1001,9 +996,10 @@
// class SkPDFType0Font
///////////////////////////////////////////////////////////////////////////////
-SkPDFType0Font::SkPDFType0Font(const SkAdvancedTypefaceMetrics* info,
+SkPDFType0Font::SkPDFType0Font(SkPDFCanon* canon,
+ const SkAdvancedTypefaceMetrics* info,
SkTypeface* typeface)
- : SkPDFFont(info, typeface, NULL) {
+ : SkPDFFont(canon, info, typeface, NULL) {
SkDEBUGCODE(fPopulated = false);
if (!canSubset()) {
populate(NULL);
@@ -1016,7 +1012,8 @@
if (!canSubset()) {
return NULL;
}
- SkPDFType0Font* newSubset = new SkPDFType0Font(fontInfo(), typeface());
+ SkPDFType0Font* newSubset =
+ new SkPDFType0Font(fCanon, fontInfo(), typeface());
newSubset->populate(subset);
return newSubset;
}
@@ -1034,7 +1031,7 @@
insertName("Encoding", "Identity-H");
SkAutoTUnref<SkPDFCIDFont> newCIDFont(
- new SkPDFCIDFont(fontInfo(), typeface(), subset));
+ new SkPDFCIDFont(fCanon, fontInfo(), typeface(), subset));
SkAutoTUnref<SkPDFArray> descendantFonts(new SkPDFArray());
descendantFonts->append(new SkPDFObjRef(newCIDFont.get()))->unref();
insert("DescendantFonts", descendantFonts.get());
@@ -1049,9 +1046,11 @@
// class SkPDFCIDFont
///////////////////////////////////////////////////////////////////////////////
-SkPDFCIDFont::SkPDFCIDFont(const SkAdvancedTypefaceMetrics* info,
- SkTypeface* typeface, const SkPDFGlyphSet* subset)
- : SkPDFFont(info, typeface, NULL) {
+SkPDFCIDFont::SkPDFCIDFont(SkPDFCanon* canon,
+ const SkAdvancedTypefaceMetrics* info,
+ SkTypeface* typeface,
+ const SkPDFGlyphSet* subset)
+ : SkPDFFont(canon, info, typeface, NULL) {
populate(subset);
}
@@ -1202,11 +1201,12 @@
// class SkPDFType1Font
///////////////////////////////////////////////////////////////////////////////
-SkPDFType1Font::SkPDFType1Font(const SkAdvancedTypefaceMetrics* info,
+SkPDFType1Font::SkPDFType1Font(SkPDFCanon* canon,
+ const SkAdvancedTypefaceMetrics* info,
SkTypeface* typeface,
uint16_t glyphID,
SkPDFDict* relatedFontDescriptor)
- : SkPDFFont(info, typeface, relatedFontDescriptor) {
+ : SkPDFFont(canon, info, typeface, relatedFontDescriptor) {
populate(glyphID);
}
@@ -1329,10 +1329,11 @@
// class SkPDFType3Font
///////////////////////////////////////////////////////////////////////////////
-SkPDFType3Font::SkPDFType3Font(const SkAdvancedTypefaceMetrics* info,
+SkPDFType3Font::SkPDFType3Font(SkPDFCanon* canon,
+ const SkAdvancedTypefaceMetrics* info,
SkTypeface* typeface,
uint16_t glyphID)
- : SkPDFFont(info, typeface, NULL) {
+ : SkPDFFont(canon, info, typeface, NULL) {
populate(glyphID);
}
diff --git a/src/pdf/SkPDFFont.h b/src/pdf/SkPDFFont.h
index 81ffd90..105ae8d 100644
--- a/src/pdf/SkPDFFont.h
+++ b/src/pdf/SkPDFFont.h
@@ -18,6 +18,7 @@
#include "SkTypeface.h"
class SkPaint;
+class SkPDFCanon;
class SkPDFCatalog;
class SkPDFFont;
@@ -126,7 +127,9 @@
* @param typeface The typeface to find.
* @param glyphID Specify which section of a large font is of interest.
*/
- static SkPDFFont* GetFontResource(SkTypeface* typeface, uint16_t glyphID);
+ static SkPDFFont* GetFontResource(SkPDFCanon* canon,
+ SkTypeface* typeface,
+ uint16_t glyphID);
/** Subset the font based on usage set. Returns a SkPDFFont instance with
* subset.
@@ -148,8 +151,12 @@
uint16_t searchGlyphID);
protected:
+ SkPDFCanon* const fCanon;
+
// Common constructor to handle common members.
- SkPDFFont(const SkAdvancedTypefaceMetrics* fontInfo, SkTypeface* typeface,
+ SkPDFFont(SkPDFCanon* canon,
+ const SkAdvancedTypefaceMetrics* fontInfo,
+ SkTypeface* typeface,
SkPDFDict* relatedFontDescriptor);
// Accessors for subclass.
@@ -176,8 +183,10 @@
void populateToUnicodeTable(const SkPDFGlyphSet* subset);
// Create instances of derived types based on fontInfo.
- static SkPDFFont* Create(const SkAdvancedTypefaceMetrics* fontInfo,
- SkTypeface* typeface, uint16_t glyphID,
+ static SkPDFFont* Create(SkPDFCanon* canon,
+ const SkAdvancedTypefaceMetrics* fontInfo,
+ SkTypeface* typeface,
+ uint16_t glyphID,
SkPDFDict* relatedFontDescriptor);
static bool Find(uint32_t fontID, uint16_t glyphID, int* index);
diff --git a/src/pdf/SkPDFFontImpl.h b/src/pdf/SkPDFFontImpl.h
index eaec8f9..2556822 100644
--- a/src/pdf/SkPDFFontImpl.h
+++ b/src/pdf/SkPDFFontImpl.h
@@ -28,7 +28,9 @@
typedef SkPDFDict INHERITED;
#endif
- SkPDFType0Font(const SkAdvancedTypefaceMetrics* info, SkTypeface* typeface);
+ SkPDFType0Font(SkPDFCanon* canon,
+ const SkAdvancedTypefaceMetrics* info,
+ SkTypeface* typeface);
bool populate(const SkPDFGlyphSet* subset);
};
@@ -41,7 +43,9 @@
private:
friend class SkPDFType0Font; // to access the constructor
- SkPDFCIDFont(const SkAdvancedTypefaceMetrics* info, SkTypeface* typeface,
+ SkPDFCIDFont(SkPDFCanon* canon,
+ const SkAdvancedTypefaceMetrics* info,
+ SkTypeface* typeface,
const SkPDFGlyphSet* subset);
bool populate(const SkPDFGlyphSet* subset);
@@ -57,8 +61,11 @@
private:
friend class SkPDFFont; // to access the constructor
- SkPDFType1Font(const SkAdvancedTypefaceMetrics* info, SkTypeface* typeface,
- uint16_t glyphID, SkPDFDict* relatedFontDescriptor);
+ SkPDFType1Font(SkPDFCanon* canon,
+ const SkAdvancedTypefaceMetrics* info,
+ SkTypeface* typeface,
+ uint16_t glyphID,
+ SkPDFDict* relatedFontDescriptor);
bool populate(int16_t glyphID);
bool addFontDescriptor(int16_t defaultWidth);
@@ -74,8 +81,10 @@
private:
friend class SkPDFFont; // to access the constructor
- SkPDFType3Font(const SkAdvancedTypefaceMetrics* info,
- SkTypeface* typeface, uint16_t glyphID);
+ SkPDFType3Font(SkPDFCanon* canon,
+ const SkAdvancedTypefaceMetrics* info,
+ SkTypeface* typeface,
+ uint16_t glyphID);
bool populate(uint16_t glyphID);
};
diff --git a/src/pdf/SkPDFGraphicState.cpp b/src/pdf/SkPDFGraphicState.cpp
index 46aa1d1..4ec0821 100644
--- a/src/pdf/SkPDFGraphicState.cpp
+++ b/src/pdf/SkPDFGraphicState.cpp
@@ -113,9 +113,8 @@
}
SkPDFGraphicState::~SkPDFGraphicState() {
- SkAutoMutexAcquire lock(SkPDFCanon::GetPaintMutex());
- if (!fSMask) {
- SkPDFCanon::GetCanon().removeGraphicState(this);
+ if (fCanon) {
+ fCanon->removeGraphicState(this);
}
}
@@ -126,15 +125,14 @@
// static
SkPDFGraphicState* SkPDFGraphicState::GetGraphicStateForPaint(
- const SkPaint& paint) {
- SkAutoMutexAcquire lock(SkPDFCanon::GetPaintMutex());
- SkPDFGraphicState* pdfGraphicState =
- SkPDFCanon::GetCanon().findGraphicState(paint);
+ SkPDFCanon* canon, const SkPaint& paint) {
+ SkASSERT(canon);
+ SkPDFGraphicState* pdfGraphicState = canon->findGraphicState(paint);
if (pdfGraphicState) {
return SkRef(pdfGraphicState);
}
- pdfGraphicState = new SkPDFGraphicState(paint);
- SkPDFCanon::GetCanon().addGraphicState(pdfGraphicState);
+ pdfGraphicState = new SkPDFGraphicState(canon, paint);
+ canon->addGraphicState(pdfGraphicState);
return pdfGraphicState;
}
@@ -181,7 +179,6 @@
SkPDFGraphicState* result = new SkPDFGraphicState;
result->fPopulated = true;
- result->fSMask = true;
result->insertName("Type", "ExtGState");
result->insert("SMask", sMaskDict.get());
@@ -195,7 +192,6 @@
SkPDFGraphicState* SkPDFGraphicState::CreateNoSMaskGraphicState() {
SkPDFGraphicState* noSMaskGS = SkNEW(SkPDFGraphicState);
noSMaskGS->fPopulated = true;
- noSMaskGS->fSMask = true;
noSMaskGS->insertName("Type", "ExtGState");
noSMaskGS->insertName("SMask", "None");
return noSMaskGS;
@@ -211,15 +207,10 @@
}
SkPDFGraphicState::SkPDFGraphicState()
- : fPopulated(false),
- fSMask(false) {
-}
+ : fCanon(NULL), fPopulated(false) {}
-SkPDFGraphicState::SkPDFGraphicState(const SkPaint& paint)
- : fPaint(paint),
- fPopulated(false),
- fSMask(false) {
-}
+SkPDFGraphicState::SkPDFGraphicState(SkPDFCanon* canon, const SkPaint& paint)
+ : fCanon(canon), fPaint(paint), fPopulated(false) {}
// populateDict and operator== have to stay in sync with each other.
void SkPDFGraphicState::populateDict() {
diff --git a/src/pdf/SkPDFGraphicState.h b/src/pdf/SkPDFGraphicState.h
index a759d56..b26e4a0 100644
--- a/src/pdf/SkPDFGraphicState.h
+++ b/src/pdf/SkPDFGraphicState.h
@@ -47,7 +47,8 @@
* other references.
* @param paint The SkPaint to emulate.
*/
- static SkPDFGraphicState* GetGraphicStateForPaint(const SkPaint& paint);
+ 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
@@ -74,12 +75,12 @@
static SkPDFGraphicState* CreateNoSMaskGraphicState();
private:
+ SkPDFCanon* const fCanon;
const SkPaint fPaint;
bool fPopulated;
- bool fSMask;
SkPDFGraphicState();
- explicit SkPDFGraphicState(const SkPaint& paint);
+ SkPDFGraphicState(SkPDFCanon* canon, const SkPaint& paint);
void populateDict();
diff --git a/src/pdf/SkPDFImage.cpp b/src/pdf/SkPDFImage.cpp
index 788b647..666a008 100644
--- a/src/pdf/SkPDFImage.cpp
+++ b/src/pdf/SkPDFImage.cpp
@@ -687,10 +687,10 @@
} // namespace
#endif
-SkPDFObject* SkPDFCreateImageObject(
- const SkBitmap& bitmap,
- const SkIRect& subset) {
- if (SkPDFObject* pdfBitmap = SkPDFBitmap::Create(bitmap, subset)) {
+SkPDFObject* SkPDFCreateImageObject(SkPDFCanon* canon,
+ const SkBitmap& bitmap,
+ const SkIRect& subset) {
+ if (SkPDFObject* pdfBitmap = SkPDFBitmap::Create(canon, bitmap, subset)) {
return pdfBitmap;
}
#if 0 // reenable when we can figure out the JPEG colorspace
diff --git a/src/pdf/SkPDFImage.h b/src/pdf/SkPDFImage.h
index 8e36542..64be971 100644
--- a/src/pdf/SkPDFImage.h
+++ b/src/pdf/SkPDFImage.h
@@ -24,7 +24,9 @@
/**
* Return the mose efficient availible encoding of the given bitmap.
*/
-SkPDFObject* SkPDFCreateImageObject(const SkBitmap&, const SkIRect& subset);
+SkPDFObject* SkPDFCreateImageObject(SkPDFCanon* canon,
+ const SkBitmap&,
+ const SkIRect& subset);
/** \class SkPDFImage
diff --git a/src/pdf/SkPDFShader.cpp b/src/pdf/SkPDFShader.cpp
index 979ef3f..21d767d 100644
--- a/src/pdf/SkPDFShader.cpp
+++ b/src/pdf/SkPDFShader.cpp
@@ -507,13 +507,12 @@
////////////////////////////////////////////////////////////////////////////////
-SkPDFFunctionShader::SkPDFFunctionShader(SkPDFShader::State* state)
- : SkPDFDict("Pattern"), fShaderState(state) {}
+SkPDFFunctionShader::SkPDFFunctionShader(SkPDFCanon* canon,
+ SkPDFShader::State* state)
+ : SkPDFDict("Pattern"), fCanon(canon), fShaderState(state) {}
SkPDFFunctionShader::~SkPDFFunctionShader() {
- SkAutoMutexAcquire lock(SkPDFCanon::GetShaderMutex());
- SkPDFCanon::GetCanon().removeFunctionShader(this);
- lock.release();
+ fCanon->removeFunctionShader(this);
fResources.unrefAll();
}
@@ -523,37 +522,37 @@
////////////////////////////////////////////////////////////////////////////////
-SkPDFAlphaFunctionShader::SkPDFAlphaFunctionShader(SkPDFShader::State* state)
- : fShaderState(state) {}
+SkPDFAlphaFunctionShader::SkPDFAlphaFunctionShader(SkPDFCanon* canon,
+ SkPDFShader::State* state)
+ : fCanon(canon), fShaderState(state) {}
bool SkPDFAlphaFunctionShader::equals(const SkPDFShader::State& state) const {
return state == *fShaderState;
}
SkPDFAlphaFunctionShader::~SkPDFAlphaFunctionShader() {
- SkAutoMutexAcquire lock(SkPDFCanon::GetShaderMutex());
- SkPDFCanon::GetCanon().removeAlphaShader(this);
+ fCanon->removeAlphaShader(this);
}
////////////////////////////////////////////////////////////////////////////////
-SkPDFImageShader::SkPDFImageShader(SkPDFShader::State* state)
- : fShaderState(state) {}
+SkPDFImageShader::SkPDFImageShader(SkPDFCanon* canon, SkPDFShader::State* state)
+ : fCanon(canon), fShaderState(state) {}
bool SkPDFImageShader::equals(const SkPDFShader::State& state) const {
return state == *fShaderState;
}
SkPDFImageShader::~SkPDFImageShader() {
- SkAutoMutexAcquire lock(SkPDFCanon::GetShaderMutex());
- SkPDFCanon::GetCanon().removeImageShader(this);
- lock.release();
+ fCanon->removeImageShader(this);
fResources.unrefAll();
}
////////////////////////////////////////////////////////////////////////////////
static SkPDFObject* get_pdf_shader_by_state(
+ SkPDFCanon* canon,
+ SkScalar dpi,
SkAutoTDelete<SkPDFShader::State>* autoState) {
const SkPDFShader::State& state = **autoState;
if (state.fType == SkShader::kNone_GradientType && state.fImage.isNull()) {
@@ -563,28 +562,31 @@
// second shader, then applying the layer to the original drawing.
return NULL;
} else if (state.fType == SkShader::kNone_GradientType) {
- SkPDFObject* shader = SkPDFCanon::GetCanon().findImageShader(state);
- return shader ? SkRef(shader) : SkPDFImageShader::Create(autoState);
- } else if (state.GradientHasAlpha()) {
- SkPDFObject* shader = SkPDFCanon::GetCanon().findAlphaShader(state);
+ SkPDFObject* shader = canon->findImageShader(state);
return shader ? SkRef(shader)
- : SkPDFAlphaFunctionShader::Create(autoState);
+ : SkPDFImageShader::Create(canon, dpi, autoState);
+ } else if (state.GradientHasAlpha()) {
+ SkPDFObject* shader = canon->findAlphaShader(state);
+ return shader ? SkRef(shader)
+ : SkPDFAlphaFunctionShader::Create(canon, dpi, autoState);
} else {
- SkPDFObject* shader = SkPDFCanon::GetCanon().findFunctionShader(state);
- return shader ? SkRef(shader) : SkPDFFunctionShader::Create(autoState);
+ SkPDFObject* shader = canon->findFunctionShader(state);
+ return shader ? SkRef(shader)
+ : SkPDFFunctionShader::Create(canon, autoState);
}
}
// static
-SkPDFObject* SkPDFShader::GetPDFShader(const SkShader& shader,
+SkPDFObject* SkPDFShader::GetPDFShader(SkPDFCanon* canon,
+ SkScalar dpi,
+ const SkShader& shader,
const SkMatrix& matrix,
const SkIRect& surfaceBBox,
SkScalar rasterScale) {
// There is only one mutex becasue we don't know which one we'll need.
- SkAutoMutexAcquire lock(SkPDFCanon::GetShaderMutex());
SkAutoTDelete<SkPDFShader::State> state(
SkNEW_ARGS(State, (shader, matrix, surfaceBBox, rasterScale)));
- return get_pdf_shader_by_state(&state);
+ return get_pdf_shader_by_state(canon, dpi, &state);
}
static SkPDFResourceDict* get_gradient_resource_dict(
@@ -647,14 +649,14 @@
* luminosity mode. The shader pattern extends to the bbox.
*/
static SkPDFGraphicState* create_smask_graphic_state(
- const SkPDFShader::State& state) {
+ SkPDFCanon* canon, SkScalar dpi, const SkPDFShader::State& state) {
SkRect bbox;
bbox.set(state.fBBox);
SkAutoTDelete<SkPDFShader::State> alphaToLuminosityState(
state.CreateAlphaToLuminosityState());
SkAutoTUnref<SkPDFObject> luminosityShader(
- get_pdf_shader_by_state(&alphaToLuminosityState));
+ get_pdf_shader_by_state(canon, dpi, &alphaToLuminosityState));
SkAutoTDelete<SkStream> alphaStream(create_pattern_fill_content(-1, bbox));
@@ -670,6 +672,8 @@
}
SkPDFAlphaFunctionShader* SkPDFAlphaFunctionShader::Create(
+ SkPDFCanon* canon,
+ SkScalar dpi,
SkAutoTDelete<SkPDFShader::State>* autoState) {
const SkPDFShader::State& state = **autoState;
SkRect bbox;
@@ -677,17 +681,19 @@
SkAutoTDelete<SkPDFShader::State> opaqueState(state.CreateOpaqueState());
- SkPDFObject* colorShader = get_pdf_shader_by_state(&opaqueState);
+ SkPDFObject* colorShader =
+ get_pdf_shader_by_state(canon, dpi, &opaqueState);
if (!colorShader) {
return NULL;
}
// Create resource dict with alpha graphics state as G0 and
// pattern shader as P0, then write content stream.
- SkAutoTUnref<SkPDFGraphicState> alphaGs(create_smask_graphic_state(state));
+ SkAutoTUnref<SkPDFGraphicState> alphaGs(
+ create_smask_graphic_state(canon, dpi, state));
SkPDFAlphaFunctionShader* alphaFunctionShader =
- SkNEW_ARGS(SkPDFAlphaFunctionShader, (autoState->detach()));
+ SkNEW_ARGS(SkPDFAlphaFunctionShader, (canon, autoState->detach()));
alphaFunctionShader->fColorShader.reset(colorShader);
@@ -701,7 +707,7 @@
populate_tiling_pattern_dict(alphaFunctionShader, bbox,
alphaFunctionShader->fResourceDict.get(),
SkMatrix::I());
- SkPDFCanon::GetCanon().addAlphaShader(alphaFunctionShader);
+ canon->addAlphaShader(alphaFunctionShader);
return alphaFunctionShader;
}
@@ -774,7 +780,7 @@
}
SkPDFFunctionShader* SkPDFFunctionShader::Create(
- SkAutoTDelete<SkPDFShader::State>* autoState) {
+ SkPDFCanon* canon, SkAutoTDelete<SkPDFShader::State>* autoState) {
const SkPDFShader::State& state = **autoState;
SkString (*codeFunction)(const SkShader::GradientInfo& info,
@@ -893,7 +899,7 @@
SkPDFUtils::MatrixToArray(finalMatrix));
SkPDFFunctionShader* pdfFunctionShader =
- SkNEW_ARGS(SkPDFFunctionShader, (autoState->detach()));
+ SkNEW_ARGS(SkPDFFunctionShader, (canon, autoState->detach()));
pdfFunctionShader->fResources.push(function);
// Pass ownership to resource list.
@@ -902,11 +908,13 @@
pdfFunctionShader->insert("Matrix", matrixArray.get());
pdfFunctionShader->insert("Shading", pdfShader.get());
- SkPDFCanon::GetCanon().addFunctionShader(pdfFunctionShader);
+ canon->addFunctionShader(pdfFunctionShader);
return pdfFunctionShader;
}
SkPDFImageShader* SkPDFImageShader::Create(
+ SkPDFCanon* canon,
+ SkScalar dpi,
SkAutoTDelete<SkPDFShader::State>* autoState) {
const SkPDFShader::State& state = **autoState;
@@ -945,7 +953,7 @@
SkISize size = SkISize::Make(SkScalarRoundToInt(deviceBounds.width()),
SkScalarRoundToInt(deviceBounds.height()));
SkAutoTUnref<SkPDFDevice> patternDevice(
- SkPDFDevice::CreateUnflipped(size, 72.0f, NULL));
+ SkPDFDevice::CreateUnflipped(size, dpi, canon));
SkCanvas canvas(patternDevice.get());
SkRect patternBBox;
@@ -1107,17 +1115,15 @@
SkAutoTDelete<SkStream> content(patternDevice->content());
SkPDFImageShader* imageShader =
- SkNEW_ARGS(SkPDFImageShader, (autoState->detach()));
+ SkNEW_ARGS(SkPDFImageShader, (canon, autoState->detach()));
imageShader->setData(content.get());
- populate_tiling_pattern_dict(imageShader,
- patternBBox,
- patternDevice->getResourceDict(),
- finalMatrix);
+ populate_tiling_pattern_dict(imageShader, patternBBox,
+ patternDevice->getResourceDict(), finalMatrix);
imageShader->fShaderState->fImage.unlockPixels();
- SkPDFCanon::GetCanon().addImageShader(imageShader);
+ canon->addImageShader(imageShader);
return imageShader;
}
diff --git a/src/pdf/SkPDFShader.h b/src/pdf/SkPDFShader.h
index 3fb962a..5be47a3 100644
--- a/src/pdf/SkPDFShader.h
+++ b/src/pdf/SkPDFShader.h
@@ -14,6 +14,7 @@
#include "SkPDFStream.h"
#include "SkPDFTypes.h"
+class SkPDFCanon;
class SkMatrix;
class SkShader;
struct SkIRect;
@@ -42,7 +43,9 @@
* @param rasterScale Additional scale to be applied for early
* rasterization.
*/
- static SkPDFObject* GetPDFShader(const SkShader& shader,
+ static SkPDFObject* GetPDFShader(SkPDFCanon* canon,
+ SkScalar dpi,
+ const SkShader& shader,
const SkMatrix& matrix,
const SkIRect& surfaceBBox,
SkScalar rasterScale);
@@ -52,14 +55,16 @@
SK_DECLARE_INST_COUNT(SkPDFFunctionShader);
public:
- static SkPDFFunctionShader* Create(SkAutoTDelete<SkPDFShader::State>*);
+ static SkPDFFunctionShader* Create(SkPDFCanon*,
+ SkAutoTDelete<SkPDFShader::State>*);
virtual ~SkPDFFunctionShader();
bool equals(const SkPDFShader::State&) const;
private:
+ SkPDFCanon* fCanon;
SkAutoTDelete<const SkPDFShader::State> fShaderState;
SkTDArray<SkPDFObject*> fResources;
- explicit SkPDFFunctionShader(SkPDFShader::State* state);
+ SkPDFFunctionShader(SkPDFCanon*, SkPDFShader::State*);
typedef SkPDFDict INHERITED;
};
@@ -70,27 +75,33 @@
*/
class SkPDFAlphaFunctionShader : public SkPDFStream {
public:
- static SkPDFAlphaFunctionShader* Create(SkAutoTDelete<SkPDFShader::State>*);
+ static SkPDFAlphaFunctionShader* Create(SkPDFCanon*,
+ SkScalar dpi,
+ SkAutoTDelete<SkPDFShader::State>*);
virtual ~SkPDFAlphaFunctionShader();
bool equals(const SkPDFShader::State&) const;
private:
+ SkPDFCanon* fCanon;
SkAutoTDelete<const SkPDFShader::State> fShaderState;
SkAutoTUnref<SkPDFObject> fColorShader;
SkAutoTUnref<SkPDFResourceDict> fResourceDict;
- explicit SkPDFAlphaFunctionShader(SkPDFShader::State* state);
+ SkPDFAlphaFunctionShader(SkPDFCanon*, SkPDFShader::State*);
};
class SkPDFImageShader : public SkPDFStream {
public:
- static SkPDFImageShader* Create(SkAutoTDelete<SkPDFShader::State>*);
+ static SkPDFImageShader* Create(SkPDFCanon*,
+ SkScalar dpi,
+ SkAutoTDelete<SkPDFShader::State>*);
virtual ~SkPDFImageShader();
bool equals(const SkPDFShader::State&) const;
private:
+ SkPDFCanon* fCanon;
SkAutoTDelete<const SkPDFShader::State> fShaderState;
SkTSet<SkPDFObject*> fResources;
- explicit SkPDFImageShader(SkPDFShader::State* state);
+ SkPDFImageShader(SkPDFCanon*, SkPDFShader::State*);
};
#endif