// 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();
}
Esempio n. 3
0
// 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;
}
Esempio n. 5
0
// 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;
}
Esempio n. 6
0
// static
int SkPDFGraphicState::Find(const SkPaint& paint) {
    CanonicalPaintsMutex().assertHeld();
    GSCanonicalEntry search(&paint);
    return CanonicalPaints().find(search);
}
Esempio n. 7
0
// static
SkTDArray<SkPDFGraphicState::GSCanonicalEntry>& SkPDFGraphicState::CanonicalPaints() {
    CanonicalPaintsMutex().assertHeld();
    static SkTDArray<SkPDFGraphicState::GSCanonicalEntry> gCanonicalPaints;
    return gCanonicalPaints;
}