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
This commit is contained in:
parent
d08ea5fdae
commit
792c80f5a7
@ -42,8 +42,8 @@ struct Sink {
|
||||
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 @@ public:
|
||||
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"; }
|
||||
};
|
||||
|
||||
|
@ -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))
|
||||
|
@ -247,13 +247,12 @@ void SkPDFBitmap::emitDict(SkWStream* stream,
|
||||
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 @@ static bool is_transparent(const SkBitmap& bm) {
|
||||
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 @@ SkPDFBitmap* SkPDFBitmap::Create(const SkBitmap& bitmap,
|
||||
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 @@ SkPDFBitmap* SkPDFBitmap::Create(const SkBitmap& bitmap,
|
||||
// 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;
|
||||
}
|
||||
|
@ -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 @@ public:
|
||||
// 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 @@ public:
|
||||
}
|
||||
|
||||
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;
|
||||
};
|
||||
|
||||
|
@ -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 @@ T* find_item(const SkTDArray<T*>& ptrArray, const U& object) {
|
||||
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 @@ SkPDFFont* SkPDFCanon::findFont(uint32_t fontID,
|
||||
}
|
||||
|
||||
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::addFont(SkPDFFont* font, uint32_t fontID, uint16_t fGlyphID) {
|
||||
}
|
||||
|
||||
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 @@ void SkPDFCanon::removeFont(SkPDFFont* pdfFont) {
|
||||
|
||||
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 @@ void SkPDFCanon::removeFunctionShader(SkPDFFunctionShader* pdfShader) {
|
||||
|
||||
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 @@ void SkPDFCanon::removeAlphaShader(SkPDFAlphaFunctionShader* pdfShader) {
|
||||
|
||||
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));
|
||||
}
|
||||
|
@ -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.
|
||||
|
@ -737,7 +737,7 @@ void SkPDFDevice::init() {
|
||||
fLastMarginContentEntry = NULL;
|
||||
fDrawingArea = kContent_DrawingArea;
|
||||
if (fFontGlyphUsage.get() == NULL) {
|
||||
fFontGlyphUsage.reset(new SkPDFGlyphSetMap());
|
||||
fFontGlyphUsage.reset(SkNEW(SkPDFGlyphSetMap));
|
||||
}
|
||||
}
|
||||
|
||||
@ -1896,8 +1896,10 @@ void SkPDFDevice::populateGraphicStateEntryFromPaint(
|
||||
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 @@ void SkPDFDevice::populateGraphicStateEntryFromPaint(
|
||||
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 @@ void SkPDFDevice::updateFont(const SkPaint& paint, uint16_t glyphID,
|
||||
}
|
||||
|
||||
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 @@ void SkPDFDevice::internalDrawBitmap(const SkMatrix& origMatrix,
|
||||
}
|
||||
|
||||
SkAutoTUnref<SkPDFObject> image(
|
||||
SkPDFCreateImageObject(*bitmap, subset));
|
||||
SkPDFCreateImageObject(fCanon, *bitmap, subset));
|
||||
if (!image) {
|
||||
return;
|
||||
}
|
||||
@ -2141,4 +2143,3 @@ void SkPDFDevice::internalDrawBitmap(const SkMatrix& origMatrix,
|
||||
SkPDFUtils::DrawFormXObject(this->addXObjectResource(image.get()),
|
||||
&content.entry()->fContent);
|
||||
}
|
||||
|
||||
|
@ -747,12 +747,7 @@ SkPDFGlyphSet* SkPDFGlyphSetMap::getGlyphSetForFont(SkPDFFont* font) {
|
||||
* 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 @@ int SkPDFFont::glyphsToPDFFontEncoding(uint16_t* glyphIDs, int numGlyphs) {
|
||||
}
|
||||
|
||||
// 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 @@ SkPDFFont* SkPDFFont::GetFontResource(SkTypeface* typeface, uint16_t glyphID) {
|
||||
#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 @@ SkPDFFont::SkPDFFont(const SkAdvancedTypefaceMetrics* info,
|
||||
}
|
||||
|
||||
// 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 @@ SkPDFFont* SkPDFFont::Create(const SkAdvancedTypefaceMetrics* info,
|
||||
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 @@ void SkPDFFont::populateToUnicodeTable(const SkPDFGlyphSet* subset) {
|
||||
// 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 @@ SkPDFFont* SkPDFType0Font::getFontSubset(const SkPDFGlyphSet* subset) {
|
||||
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 @@ bool SkPDFType0Font::populate(const SkPDFGlyphSet* subset) {
|
||||
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 @@ bool SkPDFType0Font::populate(const SkPDFGlyphSet* subset) {
|
||||
// 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 @@ bool SkPDFCIDFont::populate(const SkPDFGlyphSet* subset) {
|
||||
// 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 @@ void SkPDFType1Font::addWidthInfoFromRange(
|
||||
// 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);
|
||||
}
|
||||
|
||||
|
@ -18,6 +18,7 @@
|
||||
#include "SkTypeface.h"
|
||||
|
||||
class SkPaint;
|
||||
class SkPDFCanon;
|
||||
class SkPDFCatalog;
|
||||
class SkPDFFont;
|
||||
|
||||
@ -126,7 +127,9 @@ public:
|
||||
* @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 @@ public:
|
||||
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 @@ protected:
|
||||
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);
|
||||
|
@ -28,7 +28,9 @@ private:
|
||||
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 @@ public:
|
||||
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 @@ public:
|
||||
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 @@ public:
|
||||
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);
|
||||
};
|
||||
|
@ -113,9 +113,8 @@ bool SkPDFGraphicState::equals(const SkPaint& paint) const {
|
||||
}
|
||||
|
||||
SkPDFGraphicState::~SkPDFGraphicState() {
|
||||
SkAutoMutexAcquire lock(SkPDFCanon::GetPaintMutex());
|
||||
if (!fSMask) {
|
||||
SkPDFCanon::GetCanon().removeGraphicState(this);
|
||||
if (fCanon) {
|
||||
fCanon->removeGraphicState(this);
|
||||
}
|
||||
}
|
||||
|
||||
@ -126,15 +125,14 @@ void SkPDFGraphicState::emitObject(SkWStream* stream, SkPDFCatalog* catalog) {
|
||||
|
||||
// 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* SkPDFGraphicState::GetSMaskGraphicState(
|
||||
|
||||
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::GetSMaskGraphicState(
|
||||
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::GetNoSMaskGraphicState() {
|
||||
}
|
||||
|
||||
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() {
|
||||
|
@ -47,7 +47,8 @@ public:
|
||||
* 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 @@ public:
|
||||
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();
|
||||
|
||||
|
@ -687,10 +687,10 @@ static bool is_jfif_jpeg(SkData* data) {
|
||||
} // 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
|
||||
|
@ -24,7 +24,9 @@ struct SkIRect;
|
||||
/**
|
||||
* 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
|
||||
|
||||
|
@ -507,13 +507,12 @@ private:
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
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 @@ bool SkPDFFunctionShader::equals(const SkPDFShader::State& state) const {
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
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 @@ static SkPDFObject* get_pdf_shader_by_state(
|
||||
// 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 @@ static SkStream* create_pattern_fill_content(int gsIndex, SkRect& bounds) {
|
||||
* 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 @@ static SkPDFGraphicState* create_smask_graphic_state(
|
||||
}
|
||||
|
||||
SkPDFAlphaFunctionShader* SkPDFAlphaFunctionShader::Create(
|
||||
SkPDFCanon* canon,
|
||||
SkScalar dpi,
|
||||
SkAutoTDelete<SkPDFShader::State>* autoState) {
|
||||
const SkPDFShader::State& state = **autoState;
|
||||
SkRect bbox;
|
||||
@ -677,17 +681,19 @@ SkPDFAlphaFunctionShader* SkPDFAlphaFunctionShader::Create(
|
||||
|
||||
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 @@ SkPDFAlphaFunctionShader* SkPDFAlphaFunctionShader::Create(
|
||||
populate_tiling_pattern_dict(alphaFunctionShader, bbox,
|
||||
alphaFunctionShader->fResourceDict.get(),
|
||||
SkMatrix::I());
|
||||
SkPDFCanon::GetCanon().addAlphaShader(alphaFunctionShader);
|
||||
canon->addAlphaShader(alphaFunctionShader);
|
||||
return alphaFunctionShader;
|
||||
}
|
||||
|
||||
@ -774,7 +780,7 @@ static SkPDFStream* make_ps_function(const SkString& psCode,
|
||||
}
|
||||
|
||||
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 @@ SkPDFFunctionShader* SkPDFFunctionShader::Create(
|
||||
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 @@ SkPDFFunctionShader* SkPDFFunctionShader::Create(
|
||||
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 @@ SkPDFImageShader* SkPDFImageShader::Create(
|
||||
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 @@ SkPDFImageShader* SkPDFImageShader::Create(
|
||||
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;
|
||||
}
|
||||
|
||||
|
@ -14,6 +14,7 @@
|
||||
#include "SkPDFStream.h"
|
||||
#include "SkPDFTypes.h"
|
||||
|
||||
class SkPDFCanon;
|
||||
class SkMatrix;
|
||||
class SkShader;
|
||||
struct SkIRect;
|
||||
@ -42,7 +43,9 @@ public:
|
||||
* @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 @@ class SkPDFFunctionShader : public SkPDFDict {
|
||||
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 @@ private:
|
||||
*/
|
||||
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
|
||||
|
Loading…
Reference in New Issue
Block a user