| Index: src/pdf/SkPDFShader.cpp
|
| diff --git a/src/pdf/SkPDFShader.cpp b/src/pdf/SkPDFShader.cpp
|
| index 1b9d9eb5b8df7c60188347191cc3c7a561543358..aad62f53caa068ba246951bbe9bec7deaa147b79 100644
|
| --- a/src/pdf/SkPDFShader.cpp
|
| +++ b/src/pdf/SkPDFShader.cpp
|
| @@ -505,16 +505,21 @@ private:
|
| void AllocateGradientInfoStorage();
|
| };
|
|
|
| +static void remove_from_canon(SkPDFShader* shader) {
|
| + SkAutoMutexAcquire lock(SkPDFCanon::GetShaderMutex());
|
| + SkPDFCanon::GetCanon().removeShader(shader);
|
| +}
|
| +
|
| class SkPDFFunctionShader : public SkPDFDict, public SkPDFShader {
|
| SK_DECLARE_INST_COUNT(SkPDFFunctionShader)
|
| public:
|
| - explicit SkPDFFunctionShader(SkPDFShader::State* state);
|
| + static SkPDFObject* Create(SkAutoTDelete<SkPDFShader::State>*);
|
| +
|
| virtual ~SkPDFFunctionShader() {
|
| - SkPDFShader::RemoveFromCanonIfValid(this);
|
| + remove_from_canon(this);
|
| fResources.unrefAll();
|
| }
|
|
|
| - bool isValid() SK_OVERRIDE { return fResources.count() > 0; }
|
| SkPDFObject* toPDFObject() SK_OVERRIDE { return this; }
|
|
|
| void getResources(const SkTSet<SkPDFObject*>& knownResourceObjects,
|
| @@ -525,11 +530,9 @@ public:
|
| }
|
|
|
| private:
|
| - static SkPDFObject* RangeObject();
|
| -
|
| SkTDArray<SkPDFObject*> fResources;
|
| -
|
| - SkPDFStream* makePSFunction(const SkString& psCode, SkPDFArray* domain);
|
| + explicit SkPDFFunctionShader(SkPDFShader::State* state)
|
| + : SkPDFDict("Pattern"), SkPDFShader(state) {}
|
| typedef SkPDFDict INHERITED;
|
| };
|
|
|
| @@ -540,18 +543,17 @@ private:
|
| */
|
| class SkPDFAlphaFunctionShader : public SkPDFStream, public SkPDFShader {
|
| public:
|
| - explicit SkPDFAlphaFunctionShader(SkPDFShader::State* state);
|
| - virtual ~SkPDFAlphaFunctionShader() {
|
| - SkPDFShader::RemoveFromCanonIfValid(this);
|
| - }
|
| + static SkPDFObject* Create(SkAutoTDelete<SkPDFShader::State>*);
|
| +
|
| + virtual ~SkPDFAlphaFunctionShader() { remove_from_canon(this); }
|
|
|
| - bool isValid() SK_OVERRIDE {
|
| - return fColorShader.get() != NULL;
|
| - }
|
| SkPDFObject* toPDFObject() SK_OVERRIDE { return this; }
|
|
|
| private:
|
| - SkPDFGraphicState* CreateSMaskGraphicState();
|
| + explicit SkPDFAlphaFunctionShader(SkPDFShader::State* state);
|
| +
|
| + static SkPDFGraphicState* CreateSMaskGraphicState(
|
| + const SkPDFShader::State&);
|
|
|
| void getResources(const SkTSet<SkPDFObject*>& knownResourceObjects,
|
| SkTSet<SkPDFObject*>* newResourceObjects) SK_OVERRIDE {
|
| @@ -566,13 +568,13 @@ private:
|
|
|
| class SkPDFImageShader : public SkPDFStream, public SkPDFShader {
|
| public:
|
| - explicit SkPDFImageShader(SkPDFShader::State* state);
|
| + static SkPDFObject* Create(SkAutoTDelete<SkPDFShader::State>*);
|
| +
|
| virtual ~SkPDFImageShader() {
|
| - SkPDFShader::RemoveFromCanonIfValid(this);
|
| + remove_from_canon(this);
|
| fResources.unrefAll();
|
| }
|
|
|
| - bool isValid() SK_OVERRIDE { return size() > 0; }
|
| SkPDFObject* toPDFObject() SK_OVERRIDE { return this; }
|
|
|
| void getResources(const SkTSet<SkPDFObject*>& knownResourceObjects,
|
| @@ -584,37 +586,22 @@ public:
|
|
|
| private:
|
| SkTSet<SkPDFObject*> fResources;
|
| + explicit SkPDFImageShader(SkPDFShader::State* state) : SkPDFShader(state) {}
|
| };
|
|
|
| SkPDFShader::SkPDFShader(SkPDFShader::State* s) : fShaderState(s) {}
|
|
|
| SkPDFShader::~SkPDFShader() {}
|
|
|
| -void SkPDFShader::RemoveFromCanonIfValid(SkPDFShader* shader) {
|
| - if (shader->isValid()) {
|
| - SkAutoMutexAcquire lock(SkPDFCanon::GetShaderMutex());
|
| - SkPDFCanon::GetCanon().removeShader(shader);
|
| - }
|
| -}
|
| -
|
| bool SkPDFShader::equals(const SkPDFShader::State& state) const {
|
| return state == *fShaderState.get();
|
| }
|
|
|
| -SkPDFObject* SkPDFShader::AddToCanonIfValid(SkPDFShader* shader) {
|
| - if (!shader->isValid()) {
|
| - SkDELETE(shader);
|
| - return NULL;
|
| - }
|
| - SkPDFCanon::GetCanon().addShader(shader);
|
| - return shader->toPDFObject();
|
| -}
|
| -
|
| // static
|
| -SkPDFObject* SkPDFShader::GetPDFShaderByState(State* inState) {
|
| - SkAutoTDelete<State> state(inState);
|
| - if (state->fType == SkShader::kNone_GradientType &&
|
| - state->fImage.isNull()) {
|
| +SkPDFObject* SkPDFShader::GetPDFShaderByState(
|
| + SkAutoTDelete<SkPDFShader::State>* autoState) {
|
| + const State& state = **autoState;
|
| + if (state.fType == SkShader::kNone_GradientType && state.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
|
| @@ -622,22 +609,18 @@ SkPDFObject* SkPDFShader::GetPDFShaderByState(State* inState) {
|
| return NULL;
|
| }
|
|
|
| - SkPDFShader* pdfShader = SkPDFCanon::GetCanon().findShader(*state);
|
| + SkPDFShader* pdfShader = SkPDFCanon::GetCanon().findShader(state);
|
| if (pdfShader) {
|
| - SkASSERT(pdfShader->isValid());
|
| return SkRef(pdfShader->toPDFObject());
|
| }
|
|
|
| // The PDFShader takes ownership of the shaderSate.
|
| - if (state->fType == SkShader::kNone_GradientType) {
|
| - return SkPDFShader::AddToCanonIfValid(
|
| - SkNEW_ARGS(SkPDFImageShader, (state.detach())));
|
| - } else if (state->GradientHasAlpha()) {
|
| - return SkPDFShader::AddToCanonIfValid(
|
| - SkNEW_ARGS(SkPDFAlphaFunctionShader, (state.detach())));
|
| + if (state.fType == SkShader::kNone_GradientType) {
|
| + return SkPDFImageShader::Create(autoState);
|
| + } else if (state.GradientHasAlpha()) {
|
| + return SkPDFAlphaFunctionShader::Create(autoState);
|
| } else {
|
| - return SkPDFShader::AddToCanonIfValid(
|
| - SkNEW_ARGS(SkPDFFunctionShader, (state.detach())));
|
| + return SkPDFFunctionShader::Create(autoState);
|
| }
|
| }
|
|
|
| @@ -647,28 +630,9 @@ SkPDFObject* SkPDFShader::GetPDFShader(const SkShader& shader,
|
| const SkIRect& surfaceBBox,
|
| SkScalar rasterScale) {
|
| SkAutoMutexAcquire lock(SkPDFCanon::GetShaderMutex());
|
| - return GetPDFShaderByState(
|
| + SkAutoTDelete<SkPDFShader::State> state(
|
| SkNEW_ARGS(State, (shader, matrix, surfaceBBox, rasterScale)));
|
| -}
|
| -
|
| -
|
| -// static
|
| -SkPDFObject* SkPDFFunctionShader::RangeObject() {
|
| - SkPDFCanon::GetShaderMutex().assertHeld();
|
| - static SkPDFArray* range = NULL;
|
| - // This method is only used with CanonicalShadersMutex, so it's safe to
|
| - // populate domain.
|
| - if (range == NULL) {
|
| - range = new SkPDFArray;
|
| - range->reserve(6);
|
| - range->appendInt(0);
|
| - range->appendInt(1);
|
| - range->appendInt(0);
|
| - range->appendInt(1);
|
| - range->appendInt(0);
|
| - range->appendInt(1);
|
| - }
|
| - return range;
|
| + return GetPDFShaderByState(&state);
|
| }
|
|
|
| static SkPDFResourceDict* get_gradient_resource_dict(
|
| @@ -730,12 +694,15 @@ static SkStream* create_pattern_fill_content(int gsIndex, SkRect& bounds) {
|
| * Creates a ExtGState with the SMask set to the luminosityShader in
|
| * luminosity mode. The shader pattern extends to the bbox.
|
| */
|
| -SkPDFGraphicState* SkPDFAlphaFunctionShader::CreateSMaskGraphicState() {
|
| +SkPDFGraphicState* SkPDFAlphaFunctionShader::CreateSMaskGraphicState(
|
| + const SkPDFShader::State& state) {
|
| SkRect bbox;
|
| - bbox.set(fShaderState->fBBox);
|
| + bbox.set(state.fBBox);
|
|
|
| - SkAutoTUnref<SkPDFObject> luminosityShader(SkPDFShader::GetPDFShaderByState(
|
| - fShaderState->CreateAlphaToLuminosityState()));
|
| + SkAutoTDelete<SkPDFShader::State> alphaToLuminosityState(
|
| + state.CreateAlphaToLuminosityState());
|
| + SkAutoTUnref<SkPDFObject> luminosityShader(
|
| + SkPDFShader::GetPDFShaderByState(&alphaToLuminosityState));
|
|
|
| SkAutoTDelete<SkStream> alphaStream(create_pattern_fill_content(-1, bbox));
|
|
|
| @@ -750,28 +717,46 @@ SkPDFGraphicState* SkPDFAlphaFunctionShader::CreateSMaskGraphicState() {
|
| SkPDFGraphicState::kLuminosity_SMaskMode);
|
| }
|
|
|
| -SkPDFAlphaFunctionShader::SkPDFAlphaFunctionShader(SkPDFShader::State* state)
|
| - : SkPDFShader(state) {
|
| +SkPDFObject* SkPDFAlphaFunctionShader::Create(
|
| + SkAutoTDelete<SkPDFShader::State>* autoState) {
|
| + const SkPDFShader::State& state = **autoState;
|
| SkRect bbox;
|
| - bbox.set(fShaderState->fBBox);
|
| + bbox.set(state.fBBox);
|
|
|
| - fColorShader.reset(
|
| - SkPDFShader::GetPDFShaderByState(state->CreateOpaqueState()));
|
| + SkAutoTDelete<SkPDFShader::State> opaqueState(state.CreateOpaqueState());
|
| +
|
| + SkPDFObject* colorShader = SkPDFShader::GetPDFShaderByState(&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(CreateSMaskGraphicState());
|
| - fResourceDict.reset(
|
| - get_gradient_resource_dict(fColorShader.get(), alphaGs.get()));
|
| + SkAutoTUnref<SkPDFGraphicState> alphaGs(
|
| + SkPDFAlphaFunctionShader::CreateSMaskGraphicState(state));
|
| +
|
| + SkPDFAlphaFunctionShader* alphaFunctionShader =
|
| + SkNEW_ARGS(SkPDFAlphaFunctionShader, (autoState->detach()));
|
| +
|
| + alphaFunctionShader->fColorShader.reset(colorShader);
|
| +
|
| + alphaFunctionShader->fResourceDict.reset(get_gradient_resource_dict(
|
| + alphaFunctionShader->fColorShader.get(), alphaGs.get()));
|
|
|
| SkAutoTDelete<SkStream> colorStream(
|
| create_pattern_fill_content(0, bbox));
|
| - setData(colorStream.get());
|
| + alphaFunctionShader->setData(colorStream.get());
|
|
|
| - populate_tiling_pattern_dict(this, bbox, fResourceDict.get(),
|
| + populate_tiling_pattern_dict(alphaFunctionShader, bbox,
|
| + alphaFunctionShader->fResourceDict.get(),
|
| SkMatrix::I());
|
| + SkPDFCanon::GetCanon().addShader(alphaFunctionShader);
|
| + return alphaFunctionShader;
|
| }
|
|
|
| +SkPDFAlphaFunctionShader::SkPDFAlphaFunctionShader(SkPDFShader::State* state)
|
| + : SkPDFShader(state) {}
|
| +
|
| // Finds affine and persp such that in = affine * persp.
|
| // but it returns the inverse of perspective matrix.
|
| static bool split_perspective(const SkMatrix in, SkMatrix* affine,
|
| @@ -810,18 +795,50 @@ static bool split_perspective(const SkMatrix in, SkMatrix* affine,
|
| return true;
|
| }
|
|
|
| -SkPDFFunctionShader::SkPDFFunctionShader(SkPDFShader::State* state)
|
| - : SkPDFDict("Pattern"), SkPDFShader(state) {
|
| +namespace {
|
| +SkPDFObject* create_range_object() {
|
| + SkPDFArray* range = SkNEW(SkPDFArray);
|
| + range->reserve(6);
|
| + range->appendInt(0);
|
| + range->appendInt(1);
|
| + range->appendInt(0);
|
| + range->appendInt(1);
|
| + range->appendInt(0);
|
| + range->appendInt(1);
|
| + return range;
|
| +}
|
| +
|
| +template <typename T> void unref(T* ptr) { ptr->unref();}
|
| +} // namespace
|
| +
|
| +SK_DECLARE_STATIC_LAZY_PTR(SkPDFObject, rangeObject,
|
| + create_range_object, unref<SkPDFObject>);
|
| +
|
| +static SkPDFStream* make_ps_function(const SkString& psCode,
|
| + SkPDFArray* domain) {
|
| + SkAutoDataUnref funcData(
|
| + SkData::NewWithCopy(psCode.c_str(), psCode.size()));
|
| + SkPDFStream* result = SkNEW_ARGS(SkPDFStream, (funcData.get()));
|
| + result->insertInt("FunctionType", 4);
|
| + result->insert("Domain", domain);
|
| + result->insert("Range", rangeObject.get());
|
| + return result;
|
| +}
|
| +
|
| +SkPDFObject* SkPDFFunctionShader::Create(
|
| + SkAutoTDelete<SkPDFShader::State>* autoState) {
|
| + const SkPDFShader::State& state = **autoState;
|
| +
|
| SkString (*codeFunction)(const SkShader::GradientInfo& info,
|
| const SkMatrix& perspectiveRemover) = NULL;
|
| SkPoint transformPoints[2];
|
|
|
| // Depending on the type of the gradient, we want to transform the
|
| // coordinate space in different ways.
|
| - const SkShader::GradientInfo* info = &fShaderState->fInfo;
|
| + const SkShader::GradientInfo* info = &state.fInfo;
|
| transformPoints[0] = info->fPoint[0];
|
| transformPoints[1] = info->fPoint[1];
|
| - switch (fShaderState->fType) {
|
| + switch (state.fType) {
|
| case SkShader::kLinear_GradientType:
|
| codeFunction = &linearCode;
|
| break;
|
| @@ -831,10 +848,9 @@ SkPDFFunctionShader::SkPDFFunctionShader(SkPDFShader::State* state)
|
| codeFunction = &radialCode;
|
| break;
|
| case SkShader::kRadial2_GradientType: {
|
| - // Bail out if the radii are the same. Empty fResources signals
|
| - // an error and isValid will return false.
|
| + // Bail out if the radii are the same.
|
| if (info->fRadius[0] == info->fRadius[1]) {
|
| - return;
|
| + return NULL;
|
| }
|
| transformPoints[1] = transformPoints[0];
|
| SkScalar dr = info->fRadius[1] - info->fRadius[0];
|
| @@ -856,7 +872,7 @@ SkPDFFunctionShader::SkPDFFunctionShader(SkPDFShader::State* state)
|
| case SkShader::kColor_GradientType:
|
| case SkShader::kNone_GradientType:
|
| default:
|
| - return;
|
| + return NULL;
|
| }
|
|
|
| // Move any scaling (assuming a unit gradient) or translation
|
| @@ -866,8 +882,8 @@ SkPDFFunctionShader::SkPDFFunctionShader(SkPDFShader::State* state)
|
| SkMatrix mapperMatrix;
|
| unitToPointsMatrix(transformPoints, &mapperMatrix);
|
|
|
| - SkMatrix finalMatrix = fShaderState->fCanvasTransform;
|
| - finalMatrix.preConcat(fShaderState->fShaderTransform);
|
| + SkMatrix finalMatrix = state.fCanvasTransform;
|
| + finalMatrix.preConcat(state.fShaderTransform);
|
| finalMatrix.preConcat(mapperMatrix);
|
|
|
| // Preserves as much as posible in the final matrix, and only removes
|
| @@ -879,14 +895,14 @@ SkPDFFunctionShader::SkPDFFunctionShader(SkPDFShader::State* state)
|
| if (finalMatrix.hasPerspective()) {
|
| if (!split_perspective(finalMatrix,
|
| &finalMatrix, &perspectiveInverseOnly)) {
|
| - return;
|
| + return NULL;
|
| }
|
| }
|
|
|
| SkRect bbox;
|
| - bbox.set(fShaderState->fBBox);
|
| + bbox.set(state.fBBox);
|
| if (!inverseTransformBBox(finalMatrix, &bbox)) {
|
| - return;
|
| + return NULL;
|
| }
|
|
|
| SkAutoTUnref<SkPDFArray> domain(new SkPDFArray);
|
| @@ -898,14 +914,14 @@ SkPDFFunctionShader::SkPDFFunctionShader(SkPDFShader::State* state)
|
|
|
| SkString functionCode;
|
| // The two point radial gradient further references
|
| - // fShaderState->fInfo
|
| + // state.fInfo
|
| // in translating from x, y coordinates to the t parameter. So, we have
|
| // to transform the points and radii according to the calculated matrix.
|
| - if (fShaderState->fType == SkShader::kRadial2_GradientType) {
|
| + if (state.fType == SkShader::kRadial2_GradientType) {
|
| SkShader::GradientInfo twoPointRadialInfo = *info;
|
| SkMatrix inverseMapperMatrix;
|
| if (!mapperMatrix.invert(&inverseMapperMatrix)) {
|
| - return;
|
| + return NULL;
|
| }
|
| inverseMapperMatrix.mapPoints(twoPointRadialInfo.fPoint, 2);
|
| twoPointRadialInfo.fRadius[0] =
|
| @@ -922,18 +938,31 @@ SkPDFFunctionShader::SkPDFFunctionShader(SkPDFShader::State* state)
|
| pdfShader->insertName("ColorSpace", "DeviceRGB");
|
| pdfShader->insert("Domain", domain.get());
|
|
|
| - SkPDFStream* function = makePSFunction(functionCode, domain.get());
|
| + SkPDFStream* function = make_ps_function(functionCode, domain.get());
|
| pdfShader->insert("Function", new SkPDFObjRef(function))->unref();
|
| - fResources.push(function); // Pass ownership to resource list.
|
|
|
| - insertInt("PatternType", 2);
|
| - insert("Matrix", SkPDFUtils::MatrixToArray(finalMatrix))->unref();
|
| - insert("Shading", pdfShader.get());
|
| + SkAutoTUnref<SkPDFArray> matrixArray(
|
| + SkPDFUtils::MatrixToArray(finalMatrix));
|
| +
|
| + SkPDFFunctionShader* pdfFunctionShader =
|
| + SkNEW_ARGS(SkPDFFunctionShader, (autoState->detach()));
|
| +
|
| + pdfFunctionShader->fResources.push(function);
|
| + // Pass ownership to resource list.
|
| +
|
| + pdfFunctionShader->insertInt("PatternType", 2);
|
| + pdfFunctionShader->insert("Matrix", matrixArray.get());
|
| + pdfFunctionShader->insert("Shading", pdfShader.get());
|
| +
|
| + SkPDFCanon::GetCanon().addShader(pdfFunctionShader);
|
| + return pdfFunctionShader;
|
| }
|
|
|
| -SkPDFImageShader::SkPDFImageShader(SkPDFShader::State* state)
|
| - : SkPDFShader(state) {
|
| - fShaderState->fImage.lockPixels();
|
| +SkPDFObject* SkPDFImageShader::Create(
|
| + SkAutoTDelete<SkPDFShader::State>* autoState) {
|
| + const SkPDFShader::State& state = **autoState;
|
| +
|
| + state.fImage.lockPixels();
|
|
|
| // The image shader pattern cell will be drawn into a separate device
|
| // in pattern cell space (no scaling on the bitmap, though there may be
|
| @@ -941,15 +970,15 @@ SkPDFImageShader::SkPDFImageShader(SkPDFShader::State* state)
|
|
|
| // Map clip bounds to shader space to ensure the device is large enough
|
| // to handle fake clamping.
|
| - SkMatrix finalMatrix = fShaderState->fCanvasTransform;
|
| - finalMatrix.preConcat(fShaderState->fShaderTransform);
|
| + SkMatrix finalMatrix = state.fCanvasTransform;
|
| + finalMatrix.preConcat(state.fShaderTransform);
|
| SkRect deviceBounds;
|
| - deviceBounds.set(fShaderState->fBBox);
|
| + deviceBounds.set(state.fBBox);
|
| if (!inverseTransformBBox(finalMatrix, &deviceBounds)) {
|
| - return;
|
| + return NULL;
|
| }
|
|
|
| - const SkBitmap* image = &fShaderState->fImage;
|
| + const SkBitmap* image = &state.fImage;
|
| SkRect bitmapBounds;
|
| image->getBounds(&bitmapBounds);
|
|
|
| @@ -958,8 +987,8 @@ SkPDFImageShader::SkPDFImageShader(SkPDFShader::State* state)
|
| // For clamp modes, we're only interested in the clip region, whether
|
| // or not the main bitmap is in it.
|
| SkShader::TileMode tileModes[2];
|
| - tileModes[0] = fShaderState->fImageTileModes[0];
|
| - tileModes[1] = fShaderState->fImageTileModes[1];
|
| + tileModes[0] = state.fImageTileModes[0];
|
| + tileModes[1] = state.fImageTileModes[1];
|
| if (tileModes[0] != SkShader::kClamp_TileMode ||
|
| tileModes[1] != SkShader::kClamp_TileMode) {
|
| deviceBounds.join(bitmapBounds);
|
| @@ -1132,23 +1161,22 @@ SkPDFImageShader::SkPDFImageShader(SkPDFShader::State* state)
|
|
|
| // Put the canvas into the pattern stream (fContent).
|
| SkAutoTDelete<SkStream> content(pattern.content());
|
| - setData(content.get());
|
| +
|
| + SkPDFImageShader* imageShader =
|
| + SkNEW_ARGS(SkPDFImageShader, (autoState->detach()));
|
| + imageShader->setData(content.get());
|
| +
|
| SkPDFResourceDict* resourceDict = pattern.getResourceDict();
|
| - resourceDict->getReferencedResources(fResources, &fResources, false);
|
| + resourceDict->getReferencedResources(imageShader->fResources,
|
| + &imageShader->fResources, false);
|
|
|
| - populate_tiling_pattern_dict(this, patternBBox,
|
| + populate_tiling_pattern_dict(imageShader, patternBBox,
|
| pattern.getResourceDict(), finalMatrix);
|
|
|
| - fShaderState->fImage.unlockPixels();
|
| -}
|
| + imageShader->fShaderState->fImage.unlockPixels();
|
|
|
| -SkPDFStream* SkPDFFunctionShader::makePSFunction(const SkString& psCode, SkPDFArray* domain) {
|
| - SkAutoDataUnref funcData(SkData::NewWithCopy(psCode.c_str(), psCode.size()));
|
| - SkPDFStream* result = new SkPDFStream(funcData.get());
|
| - result->insertInt("FunctionType", 4);
|
| - result->insert("Domain", domain);
|
| - result->insert("Range", RangeObject());
|
| - return result;
|
| + SkPDFCanon::GetCanon().addShader(imageShader);
|
| + return imageShader;
|
| }
|
|
|
| bool SkPDFShader::State::operator==(const SkPDFShader::State& b) const {
|
|
|