// static SkPDFGraphicState* SkPDFGraphicState::GetSMaskGraphicState( SkPDFFormXObject* sMask, bool invert) { // The practical chances of using the same mask more than once are unlikely // enough that it's not worth canonicalizing. SkAutoMutexAcquire lock(CanonicalPaintsMutex()); SkRefPtr<SkPDFDict> sMaskDict = new SkPDFDict("Mask"); sMaskDict->unref(); // SkRefPtr and new both took a reference. sMaskDict->insertName("S", "Alpha"); sMaskDict->insert("G", new SkPDFObjRef(sMask))->unref(); SkPDFGraphicState* result = new SkPDFGraphicState; result->fPopulated = true; result->fSMask = true; result->insertName("Type", "ExtGState"); result->insert("SMask", sMaskDict.get()); result->fResources.push(sMask); sMask->ref(); if (invert) { SkPDFObject* invertFunction = GetInvertFunction(); result->fResources.push(invertFunction); invertFunction->ref(); sMaskDict->insert("TR", new SkPDFObjRef(invertFunction))->unref(); } return result; }
SkPDFGraphicState::~SkPDFGraphicState() { SkAutoMutexAcquire lock(CanonicalPaintsMutex()); if (!fSMask) { int index = Find(fPaint); SkASSERT(index >= 0); CanonicalPaints().removeShuffle(index); } fResources.unrefAll(); }
// static SkPDFGraphicState* SkPDFGraphicState::GetGraphicStateForPaint(const SkPaint& paint) { SkAutoMutexAcquire lock(CanonicalPaintsMutex()); int index = Find(paint); if (index >= 0) { CanonicalPaints()[index].fGraphicState->ref(); return CanonicalPaints()[index].fGraphicState; } GSCanonicalEntry newEntry(new SkPDFGraphicState(paint)); CanonicalPaints().push(newEntry); return newEntry.fGraphicState; }
// static SkPDFGraphicState* SkPDFGraphicState::GetNoSMaskGraphicState() { SkAutoMutexAcquire lock(CanonicalPaintsMutex()); static SkPDFGraphicState* noSMaskGS = NULL; if (!noSMaskGS) { noSMaskGS = new SkPDFGraphicState; noSMaskGS->fPopulated = true; noSMaskGS->fSMask = true; noSMaskGS->insertName("Type", "ExtGState"); noSMaskGS->insertName("SMask", "None"); } noSMaskGS->ref(); return noSMaskGS; }
// static SkPDFObject* SkPDFGraphicState::GetInvertFunction() { // This assumes that canonicalPaintsMutex is held. CanonicalPaintsMutex().assertHeld(); static SkPDFStream* invertFunction = NULL; if (!invertFunction) { // 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. SkAutoTUnref<SkPDFArray> domainAndRange(new SkPDFArray); domainAndRange->reserve(2); domainAndRange->appendInt(0); domainAndRange->appendInt(1); static const char psInvert[] = "{1 exch sub}"; SkAutoTUnref<SkMemoryStream> psInvertStream( new SkMemoryStream(&psInvert, strlen(psInvert), true)); invertFunction = new SkPDFStream(psInvertStream.get()); invertFunction->insertInt("FunctionType", 4); invertFunction->insert("Domain", domainAndRange.get()); invertFunction->insert("Range", domainAndRange.get()); } return invertFunction; }
// static int SkPDFGraphicState::Find(const SkPaint& paint) { CanonicalPaintsMutex().assertHeld(); GSCanonicalEntry search(&paint); return CanonicalPaints().find(search); }
// static SkTDArray<SkPDFGraphicState::GSCanonicalEntry>& SkPDFGraphicState::CanonicalPaints() { CanonicalPaintsMutex().assertHeld(); static SkTDArray<SkPDFGraphicState::GSCanonicalEntry> gCanonicalPaints; return gCanonicalPaints; }