// static
void SkPDFShader::RemoveShader(SkPDFObject* shader) {
    SkAutoMutexAcquire lock(CanonicalShadersMutex());
    ShaderCanonicalEntry entry(shader, NULL);
    int index = CanonicalShaders().find(entry);
    SkASSERT(index >= 0);
    CanonicalShaders().removeShuffle(index);
}
// static
SkPDFObject* SkPDFShader::GetPDFShader(const SkShader& shader,
                                       const SkMatrix& matrix,
                                       const SkIRect& surfaceBBox) {
    SkPDFObject* result;
    SkAutoMutexAcquire lock(CanonicalShadersMutex());
    SkAutoTDelete<State> shaderState(new State(shader, matrix, surfaceBBox));

    ShaderCanonicalEntry entry(NULL, shaderState.get());
    int index = CanonicalShaders().find(entry);
    if (index >= 0) {
        result = CanonicalShaders()[index].fPDFShader;
        result->ref();
        return result;
    }
    // The PDFShader takes ownership of the shaderSate.
    if (shaderState.get()->fType == SkShader::kNone_GradientType) {
        result = new SkPDFImageShader(shaderState.detach());
    } else {
        SkPDFFunctionShader* functionShader =
            new SkPDFFunctionShader(shaderState.detach());
        if (!functionShader->isValid()) {
            delete functionShader;
            return NULL;
        }
        result = functionShader;
    }
    entry.fPDFShader = result;
    CanonicalShaders().push(entry);
    return result;  // return the reference that came from new.
}
Esempio n. 3
0
// static
SkPDFObject* SkPDFShader::GetPDFShaderByState(State* inState) {
    SkPDFObject* result;

    SkAutoTDelete<State> shaderState(inState);
    if (shaderState.get()->fType == SkShader::kNone_GradientType &&
            shaderState.get()->fImage.isNull()) {
        // TODO(vandebo) This drops SKComposeShader on the floor.  We could
        // handle compose shader by pulling things up to a layer, drawing with
        // the first shader, applying the xfer mode and drawing again with the
        // second shader, then applying the layer to the original drawing.
        return NULL;
    }

    ShaderCanonicalEntry entry(NULL, shaderState.get());
    int index = CanonicalShaders().find(entry);
    if (index >= 0) {
        result = CanonicalShaders()[index].fPDFShader;
        result->ref();
        return result;
    }

    bool valid = false;
    // The PDFShader takes ownership of the shaderSate.
    if (shaderState.get()->fType == SkShader::kNone_GradientType) {
        SkPDFImageShader* imageShader =
            new SkPDFImageShader(shaderState.detach());
        valid = imageShader->isValid();
        result = imageShader;
    } else {
        if (shaderState.get()->GradientHasAlpha()) {
            SkPDFAlphaFunctionShader* gradientShader =
                SkNEW_ARGS(SkPDFAlphaFunctionShader, (shaderState.detach()));
            valid = gradientShader->isValid();
            result = gradientShader;
        } else {
            SkPDFFunctionShader* functionShader =
                SkNEW_ARGS(SkPDFFunctionShader, (shaderState.detach()));
            valid = functionShader->isValid();
            result = functionShader;
        }
    }
    if (!valid) {
        delete result;
        return NULL;
    }
    entry.fPDFShader = result;
    CanonicalShaders().push(entry);
    return result;  // return the reference that came from new.
}