diff options
author | halcanary <halcanary@google.com> | 2016-08-03 11:16:56 -0700 |
---|---|---|
committer | Commit bot <commit-bot@chromium.org> | 2016-08-03 11:16:57 -0700 |
commit | dabd4f0b799318cb6e90b69ae1ec0ed0b6d32f60 (patch) | |
tree | 440e9e2677dbbf17b2b8e2ce10a7131b99641eb7 /src/pdf/SkPDFShader.cpp | |
parent | 62e1a1a4ba9926c9b515eb603173ea4202ac28ae (diff) |
SkPDF: PDFShader code modernized.
Motivation: reduce code complexity.
SkCanon stores SkPDFShader::State next to SkDFObject, not inside.
many places use sk_sp<T> rather than T* to represent ownership.
SkPDFShader::State no longer holds bitmap.
SkPDFShader::State gets move constructor, no longer heap-allocated.
Classes removed:
SkPDFFunctionShader
SkPDFAlphaFunctionShader
SkPDFImageShader
BUG=skia:
GOLD_TRYBOT_URL= https://gold.skia.org/search?issue=2193973002
Review-Url: https://codereview.chromium.org/2193973002
Diffstat (limited to 'src/pdf/SkPDFShader.cpp')
-rw-r--r-- | src/pdf/SkPDFShader.cpp | 319 |
1 files changed, 128 insertions, 191 deletions
diff --git a/src/pdf/SkPDFShader.cpp b/src/pdf/SkPDFShader.cpp index 885b7e6049..f7aef6304a 100644 --- a/src/pdf/SkPDFShader.cpp +++ b/src/pdf/SkPDFShader.cpp @@ -523,112 +523,65 @@ static void drawBitmapMatrix(SkCanvas* canvas, const SkBitmap& bm, const SkMatri canvas->drawBitmap(bm, 0, 0); } -class SkPDFShader::State { -public: - SkShader::GradientType fType; - SkShader::GradientInfo fInfo; - SkAutoFree fColorData; // This provides storage for arrays in fInfo. - SkMatrix fCanvasTransform; - SkMatrix fShaderTransform; - SkIRect fBBox; - - SkBitmap fImage; - SkBitmapKey fBitmapKey; - SkShader::TileMode fImageTileModes[2]; - - State(SkShader* shader, const SkMatrix& canvasTransform, - const SkIRect& bbox, SkScalar rasterScale); - - bool operator==(const State& b) const; - - SkPDFShader::State* CreateAlphaToLuminosityState() const; - SkPDFShader::State* CreateOpaqueState() const; - - bool GradientHasAlpha() const; - -private: - State(const State& other); - State operator=(const State& rhs); - void AllocateGradientInfoStorage(); -}; - -//////////////////////////////////////////////////////////////////////////////// - -SkPDFFunctionShader::SkPDFFunctionShader(SkPDFShader::State* state) - : SkPDFDict("Pattern"), fShaderState(state) { - state->fImage.reset(); -} - -SkPDFFunctionShader::~SkPDFFunctionShader() {} - -bool SkPDFFunctionShader::equals(const SkPDFShader::State& state) const { - return state == *fShaderState; -} - //////////////////////////////////////////////////////////////////////////////// -SkPDFAlphaFunctionShader::SkPDFAlphaFunctionShader(SkPDFShader::State* state) - : fShaderState(state) { - state->fImage.reset(); -} - -bool SkPDFAlphaFunctionShader::equals(const SkPDFShader::State& state) const { - return state == *fShaderState; -} +static sk_sp<SkPDFStream> make_alpha_function_shader(SkPDFDocument* doc, + SkScalar dpi, + const SkPDFShader::State& state); +static sk_sp<SkPDFDict> make_function_shader(SkPDFCanon* canon, + const SkPDFShader::State& state); -SkPDFAlphaFunctionShader::~SkPDFAlphaFunctionShader() {} +static sk_sp<SkPDFStream> make_image_shader(SkPDFDocument* doc, + SkScalar dpi, + const SkPDFShader::State& state, + SkBitmap image); -//////////////////////////////////////////////////////////////////////////////// - -SkPDFImageShader::SkPDFImageShader(SkPDFShader::State* state) - : fShaderState(state) { - state->fImage.reset(); -} - -bool SkPDFImageShader::equals(const SkPDFShader::State& state) const { - return state == *fShaderState; -} - -SkPDFImageShader::~SkPDFImageShader() {} - -//////////////////////////////////////////////////////////////////////////////// - -static SkPDFObject* get_pdf_shader_by_state( +static sk_sp<SkPDFObject> get_pdf_shader_by_state( SkPDFDocument* doc, SkScalar dpi, - std::unique_ptr<SkPDFShader::State>* autoState) { - const SkPDFShader::State& state = **autoState; + SkPDFShader::State state, + SkBitmap image) { SkPDFCanon* canon = doc->canon(); - if (state.fType == SkShader::kNone_GradientType && state.fImage.isNull()) { + if (state.fType == SkShader::kNone_GradientType && image.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 nullptr; } else if (state.fType == SkShader::kNone_GradientType) { - SkPDFObject* shader = canon->findImageShader(state); - return shader ? SkRef(shader) - : SkPDFImageShader::Create(doc, dpi, autoState); + sk_sp<SkPDFObject> shader = canon->findImageShader(state); + if (!shader) { + shader = make_image_shader(doc, dpi, state, std::move(image)); + canon->addImageShader(shader, std::move(state)); + } + return shader; } else if (state.GradientHasAlpha()) { - SkPDFObject* shader = canon->findAlphaShader(state); - return shader ? SkRef(shader) - : SkPDFAlphaFunctionShader::Create(doc, dpi, autoState); + sk_sp<SkPDFObject> shader = canon->findAlphaShader(state); + if (!shader) { + shader = make_alpha_function_shader(doc, dpi, state); + canon->addAlphaShader(shader, std::move(state)); + } + return shader; } else { - SkPDFObject* shader = canon->findFunctionShader(state); - return shader ? SkRef(shader) - : SkPDFFunctionShader::Create(canon, autoState); + sk_sp<SkPDFObject> shader = canon->findFunctionShader(state); + if (!shader) { + shader = make_function_shader(canon, state); + canon->addFunctionShader(shader, std::move(state)); + } + return shader; } } -// static -SkPDFObject* SkPDFShader::GetPDFShader(SkPDFDocument* doc, - SkScalar dpi, - SkShader* shader, - const SkMatrix& matrix, - const SkIRect& surfaceBBox, - SkScalar rasterScale) { - std::unique_ptr<SkPDFShader::State> state(new State(shader, matrix, surfaceBBox, rasterScale)); - return get_pdf_shader_by_state(doc, dpi, &state); +sk_sp<SkPDFObject> SkPDFShader::GetPDFShader(SkPDFDocument* doc, + SkScalar dpi, + SkShader* shader, + const SkMatrix& matrix, + const SkIRect& surfaceBBox, + SkScalar rasterScale) { + SkBitmap image; + State state(shader, matrix, surfaceBBox, rasterScale, &image); + return get_pdf_shader_by_state( + doc, dpi, std::move(state), std::move(image)); } static sk_sp<SkPDFDict> get_gradient_resource_dict( @@ -647,7 +600,7 @@ static sk_sp<SkPDFDict> get_gradient_resource_dict( static void populate_tiling_pattern_dict(SkPDFDict* pattern, SkRect& bbox, - SkPDFDict* resources, + sk_sp<SkPDFDict> resources, const SkMatrix& matrix) { const int kTiling_PatternType = 1; const int kColoredTilingPattern_PaintType = 1; @@ -660,7 +613,7 @@ static void populate_tiling_pattern_dict(SkPDFDict* pattern, pattern->insertObject("BBox", SkPDFUtils::RectToArray(bbox)); pattern->insertScalar("XStep", bbox.width()); pattern->insertScalar("YStep", bbox.height()); - pattern->insertObject("Resources", sk_ref_sp(resources)); + pattern->insertObject("Resources", std::move(resources)); if (!matrix.isIdentity()) { pattern->insertObject("Matrix", SkPDFUtils::MatrixToArray(matrix)); } @@ -671,7 +624,8 @@ static void populate_tiling_pattern_dict(SkPDFDict* pattern, * @param gsIndex A graphics state resource index to apply, or <0 if no * graphics state to apply. */ -static SkStreamAsset* create_pattern_fill_content(int gsIndex, SkRect& bounds) { +static std::unique_ptr<SkStreamAsset> create_pattern_fill_content( + int gsIndex, SkRect& bounds) { SkDynamicMemoryWStream content; if (gsIndex >= 0) { SkPDFUtils::ApplyGraphicState(gsIndex, &content); @@ -681,7 +635,7 @@ static SkStreamAsset* create_pattern_fill_content(int gsIndex, SkRect& bounds) { SkPDFUtils::PaintPath(SkPaint::kFill_Style, SkPath::kEvenOdd_FillType, &content); - return content.detachAsStream(); + return std::unique_ptr<SkStreamAsset>(content.detachAsStream()); } /** @@ -693,10 +647,9 @@ static sk_sp<SkPDFObject> create_smask_graphic_state( SkRect bbox; bbox.set(state.fBBox); - std::unique_ptr<SkPDFShader::State> alphaToLuminosityState( - state.CreateAlphaToLuminosityState()); sk_sp<SkPDFObject> luminosityShader( - get_pdf_shader_by_state(doc, dpi, &alphaToLuminosityState)); + get_pdf_shader_by_state(doc, dpi, state.MakeAlphaToLuminosityState(), + SkBitmap())); std::unique_ptr<SkStreamAsset> alphaStream(create_pattern_fill_content(-1, bbox)); @@ -709,22 +662,20 @@ static sk_sp<SkPDFObject> create_smask_graphic_state( SkMatrix::I(), "DeviceRGB"); return SkPDFGraphicState::GetSMaskGraphicState( - alphaMask.get(), false, + std::move(alphaMask), false, SkPDFGraphicState::kLuminosity_SMaskMode, doc->canon()); } -SkPDFAlphaFunctionShader* SkPDFAlphaFunctionShader::Create( - SkPDFDocument* doc, - SkScalar dpi, - std::unique_ptr<SkPDFShader::State>* autoState) { - const SkPDFShader::State& state = **autoState; +static sk_sp<SkPDFStream> make_alpha_function_shader(SkPDFDocument* doc, + SkScalar dpi, + const SkPDFShader::State& state) { SkRect bbox; bbox.set(state.fBBox); - std::unique_ptr<SkPDFShader::State> opaqueState(state.CreateOpaqueState()); + SkPDFShader::State opaqueState(state.MakeOpaqueState()); sk_sp<SkPDFObject> colorShader( - get_pdf_shader_by_state(doc, dpi, &opaqueState)); + get_pdf_shader_by_state(doc, dpi, std::move(opaqueState), SkBitmap())); if (!colorShader) { return nullptr; } @@ -733,20 +684,15 @@ SkPDFAlphaFunctionShader* SkPDFAlphaFunctionShader::Create( // pattern shader as P0, then write content stream. auto alphaGs = create_smask_graphic_state(doc, dpi, state); - SkPDFAlphaFunctionShader* alphaFunctionShader = - new SkPDFAlphaFunctionShader(autoState->release()); - auto resourceDict = get_gradient_resource_dict(colorShader.get(), alphaGs.get()); std::unique_ptr<SkStreamAsset> colorStream( create_pattern_fill_content(0, bbox)); - alphaFunctionShader->setData(std::move(colorStream)); + auto alphaFunctionShader = sk_make_sp<SkPDFStream>(std::move(colorStream)); - populate_tiling_pattern_dict( - alphaFunctionShader->dict(), bbox, resourceDict.get(), - SkMatrix::I()); - doc->canon()->addAlphaShader(alphaFunctionShader); + populate_tiling_pattern_dict(alphaFunctionShader->dict(), bbox, + std::move(resourceDict), SkMatrix::I()); return alphaFunctionShader; } @@ -802,11 +748,11 @@ sk_sp<SkPDFArray> SkPDFShader::MakeRangeObject() { static sk_sp<SkPDFStream> make_ps_function( std::unique_ptr<SkStreamAsset> psCode, - SkPDFArray* domain, + sk_sp<SkPDFArray> domain, sk_sp<SkPDFObject> range) { auto result = sk_make_sp<SkPDFStream>(std::move(psCode)); result->dict()->insertInt("FunctionType", 4); - result->dict()->insertObject("Domain", sk_ref_sp(domain)); + result->dict()->insertObject("Domain", std::move(domain)); result->dict()->insertObject("Range", std::move(range)); return result; } @@ -826,10 +772,8 @@ static void FixUpRadius(const SkPoint& p1, SkScalar& r1, const SkPoint& p2, SkSc } } -SkPDFFunctionShader* SkPDFFunctionShader::Create( - SkPDFCanon* canon, std::unique_ptr<SkPDFShader::State>* autoState) { - const SkPDFShader::State& state = **autoState; - +static sk_sp<SkPDFDict> make_function_shader(SkPDFCanon* canon, + const SkPDFShader::State& state) { void (*codeFunction)(const SkShader::GradientInfo& info, const SkMatrix& perspectiveRemover, SkDynamicMemoryWStream* function) = nullptr; @@ -839,10 +783,10 @@ SkPDFFunctionShader* SkPDFFunctionShader::Create( finalMatrix.preConcat(state.fShaderTransform); bool doStitchFunctions = (state.fType == SkShader::kLinear_GradientType || - state.fType == SkShader::kRadial_GradientType || - state.fType == SkShader::kConical_GradientType) && - info->fTileMode == SkShader::kClamp_TileMode && - !finalMatrix.hasPerspective(); + state.fType == SkShader::kRadial_GradientType || + state.fType == SkShader::kConical_GradientType) && + info->fTileMode == SkShader::kClamp_TileMode && + !finalMatrix.hasPerspective(); auto domain = sk_make_sp<SkPDFArray>(); @@ -984,39 +928,37 @@ SkPDFFunctionShader* SkPDFFunctionShader::Create( codeFunction(*info, perspectiveInverseOnly, &functionCode); } - pdfShader->insertObject("Domain", sk_ref_sp(domain.get())); + pdfShader->insertObject("Domain", domain); // Call canon->makeRangeObject() instead of // SkPDFShader::MakeRangeObject() so that the canon can // deduplicate. std::unique_ptr<SkStreamAsset> functionStream( functionCode.detachAsStream()); - auto function = make_ps_function(std::move(functionStream), domain.get(), - canon->makeRangeObject()); + sk_sp<SkPDFStream> function = make_ps_function(std::move(functionStream), + std::move(domain), + canon->makeRangeObject()); pdfShader->insertObjRef("Function", std::move(function)); } pdfShader->insertInt("ShadingType", shadingType); pdfShader->insertName("ColorSpace", "DeviceRGB"); - sk_sp<SkPDFFunctionShader> pdfFunctionShader( - new SkPDFFunctionShader(autoState->release())); + auto pdfFunctionShader = sk_make_sp<SkPDFDict>("Pattern"); pdfFunctionShader->insertInt("PatternType", 2); pdfFunctionShader->insertObject("Matrix", SkPDFUtils::MatrixToArray(finalMatrix)); pdfFunctionShader->insertObject("Shading", std::move(pdfShader)); - canon->addFunctionShader(pdfFunctionShader.get()); - return pdfFunctionShader.release(); + return pdfFunctionShader; } -SkPDFImageShader* SkPDFImageShader::Create( - SkPDFDocument* doc, - SkScalar dpi, - std::unique_ptr<SkPDFShader::State>* autoState) { - const SkPDFShader::State& state = **autoState; - - state.fImage.lockPixels(); +static sk_sp<SkPDFStream> make_image_shader(SkPDFDocument* doc, + SkScalar dpi, + const SkPDFShader::State& state, + SkBitmap image) { + SkASSERT(state.fBitmapKey == SkBitmapKey(image)); + SkAutoLockPixels SkAutoLockPixels(image); // 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 @@ -1032,9 +974,8 @@ SkPDFImageShader* SkPDFImageShader::Create( return nullptr; } - const SkBitmap* image = &state.fImage; SkRect bitmapBounds; - image->getBounds(&bitmapBounds); + image.getBounds(&bitmapBounds); // For tiling modes, the bounds should be extended to include the bitmap, // otherwise the bitmap gets clipped out and the shader is empty and awful. @@ -1055,7 +996,7 @@ SkPDFImageShader* SkPDFImageShader::Create( SkCanvas canvas(patternDevice.get()); SkRect patternBBox; - image->getBounds(&patternBBox); + image.getBounds(&patternBBox); // Translate the canvas so that the bitmap origin is at (0, 0). canvas.translate(-deviceBounds.left(), -deviceBounds.top()); @@ -1066,24 +1007,24 @@ SkPDFImageShader* SkPDFImageShader::Create( // If the bitmap is out of bounds (i.e. clamp mode where we only see the // stretched sides), canvas will clip this out and the extraneous data // won't be saved to the PDF. - canvas.drawBitmap(*image, 0, 0); + canvas.drawBitmap(image, 0, 0); - SkScalar width = SkIntToScalar(image->width()); - SkScalar height = SkIntToScalar(image->height()); + SkScalar width = SkIntToScalar(image.width()); + SkScalar height = SkIntToScalar(image.height()); // Tiling is implied. First we handle mirroring. if (tileModes[0] == SkShader::kMirror_TileMode) { SkMatrix xMirror; xMirror.setScale(-1, 1); xMirror.postTranslate(2 * width, 0); - drawBitmapMatrix(&canvas, *image, xMirror); + drawBitmapMatrix(&canvas, image, xMirror); patternBBox.fRight += width; } if (tileModes[1] == SkShader::kMirror_TileMode) { SkMatrix yMirror; yMirror.setScale(SK_Scalar1, -SK_Scalar1); yMirror.postTranslate(0, 2 * height); - drawBitmapMatrix(&canvas, *image, yMirror); + drawBitmapMatrix(&canvas, image, yMirror); patternBBox.fBottom += height; } if (tileModes[0] == SkShader::kMirror_TileMode && @@ -1091,7 +1032,7 @@ SkPDFImageShader* SkPDFImageShader::Create( SkMatrix mirror; mirror.setScale(-1, -1); mirror.postTranslate(2 * width, 2 * height); - drawBitmapMatrix(&canvas, *image, mirror); + drawBitmapMatrix(&canvas, image, mirror); } // Then handle Clamping, which requires expanding the pattern canvas to @@ -1105,39 +1046,39 @@ SkPDFImageShader* SkPDFImageShader::Create( SkRect rect; rect = SkRect::MakeLTRB(deviceBounds.left(), deviceBounds.top(), 0, 0); if (!rect.isEmpty()) { - paint.setColor(image->getColor(0, 0)); + paint.setColor(image.getColor(0, 0)); canvas.drawRect(rect, paint); } rect = SkRect::MakeLTRB(width, deviceBounds.top(), deviceBounds.right(), 0); if (!rect.isEmpty()) { - paint.setColor(image->getColor(image->width() - 1, 0)); + paint.setColor(image.getColor(image.width() - 1, 0)); canvas.drawRect(rect, paint); } rect = SkRect::MakeLTRB(width, height, deviceBounds.right(), deviceBounds.bottom()); if (!rect.isEmpty()) { - paint.setColor(image->getColor(image->width() - 1, - image->height() - 1)); + paint.setColor(image.getColor(image.width() - 1, + image.height() - 1)); canvas.drawRect(rect, paint); } rect = SkRect::MakeLTRB(deviceBounds.left(), height, 0, deviceBounds.bottom()); if (!rect.isEmpty()) { - paint.setColor(image->getColor(0, image->height() - 1)); + paint.setColor(image.getColor(0, image.height() - 1)); canvas.drawRect(rect, paint); } } // Then expand the left, right, top, then bottom. if (tileModes[0] == SkShader::kClamp_TileMode) { - SkIRect subset = SkIRect::MakeXYWH(0, 0, 1, image->height()); + SkIRect subset = SkIRect::MakeXYWH(0, 0, 1, image.height()); if (deviceBounds.left() < 0) { SkBitmap left; - SkAssertResult(image->extractSubset(&left, subset)); + SkAssertResult(image.extractSubset(&left, subset)); SkMatrix leftMatrix; leftMatrix.setScale(-deviceBounds.left(), 1); @@ -1154,8 +1095,8 @@ SkPDFImageShader* SkPDFImageShader::Create( if (deviceBounds.right() > width) { SkBitmap right; - subset.offset(image->width() - 1, 0); - SkAssertResult(image->extractSubset(&right, subset)); + subset.offset(image.width() - 1, 0); + SkAssertResult(image.extractSubset(&right, subset)); SkMatrix rightMatrix; rightMatrix.setScale(deviceBounds.right() - width, 1); @@ -1172,10 +1113,10 @@ SkPDFImageShader* SkPDFImageShader::Create( } if (tileModes[1] == SkShader::kClamp_TileMode) { - SkIRect subset = SkIRect::MakeXYWH(0, 0, image->width(), 1); + SkIRect subset = SkIRect::MakeXYWH(0, 0, image.width(), 1); if (deviceBounds.top() < 0) { SkBitmap top; - SkAssertResult(image->extractSubset(&top, subset)); + SkAssertResult(image.extractSubset(&top, subset)); SkMatrix topMatrix; topMatrix.setScale(SK_Scalar1, -deviceBounds.top()); @@ -1192,8 +1133,8 @@ SkPDFImageShader* SkPDFImageShader::Create( if (deviceBounds.bottom() > height) { SkBitmap bottom; - subset.offset(0, image->height() - 1); - SkAssertResult(image->extractSubset(&bottom, subset)); + subset.offset(0, image.height() - 1); + SkAssertResult(image.extractSubset(&bottom, subset)); SkMatrix bottomMatrix; bottomMatrix.setScale(SK_Scalar1, deviceBounds.bottom() - height); @@ -1209,17 +1150,9 @@ SkPDFImageShader* SkPDFImageShader::Create( } } - // Put the canvas into the pattern stream (fContent). - SkPDFImageShader* imageShader = new SkPDFImageShader(autoState->release()); - imageShader->setData(patternDevice->content()); - - auto resourceDict = patternDevice->makeResourceDict(); + auto imageShader = sk_make_sp<SkPDFStream>(patternDevice->content()); populate_tiling_pattern_dict(imageShader->dict(), patternBBox, - resourceDict.get(), finalMatrix); - - imageShader->fShaderState->fImage.unlockPixels(); - - doc->canon()->addImageShader(imageShader); + patternDevice->makeResourceDict(), finalMatrix); return imageShader; } @@ -1277,9 +1210,11 @@ bool SkPDFShader::State::operator==(const SkPDFShader::State& b) const { } SkPDFShader::State::State(SkShader* shader, const SkMatrix& canvasTransform, - const SkIRect& bbox, SkScalar rasterScale) + const SkIRect& bbox, SkScalar rasterScale, + SkBitmap* imageDst) : fCanvasTransform(canvasTransform), fBBox(bbox) { + SkASSERT(imageDst); fInfo.fColorCount = 0; fInfo.fColors = nullptr; fInfo.fColorOffsets = nullptr; @@ -1289,18 +1224,19 @@ SkPDFShader::State::State(SkShader* shader, const SkMatrix& canvasTransform, fType = shader->asAGradient(&fInfo); if (fType == SkShader::kNone_GradientType) { - if (!shader->isABitmap(&fImage, nullptr, fImageTileModes)) { + if (!shader->isABitmap(imageDst, nullptr, fImageTileModes)) { // Generic fallback for unsupported shaders: // * allocate a bbox-sized bitmap // * shade the whole area // * use the result as a bitmap shader - // bbox is in device space. While that's exactly what we want for sizing our bitmap, - // we need to map it into shader space for adjustments (to match - // SkPDFImageShader::Create's behavior). + // bbox is in device space. While that's exactly what we + // want for sizing our bitmap, we need to map it into + // shader space for adjustments (to match + // MakeImageShader's behavior). SkRect shaderRect = SkRect::Make(bbox); if (!inverse_transform_bbox(canvasTransform, &shaderRect)) { - fImage.reset(); + imageDst->reset(); return; } @@ -1316,13 +1252,13 @@ SkPDFShader::State::State(SkShader* shader, const SkMatrix& canvasTransform, SkSize scale = SkSize::Make(SkIntToScalar(size.width()) / shaderRect.width(), SkIntToScalar(size.height()) / shaderRect.height()); - fImage.allocN32Pixels(size.width(), size.height()); - fImage.eraseColor(SK_ColorTRANSPARENT); + imageDst->allocN32Pixels(size.width(), size.height()); + imageDst->eraseColor(SK_ColorTRANSPARENT); SkPaint p; p.setShader(sk_ref_sp(shader)); - SkCanvas canvas(fImage); + SkCanvas canvas(*imageDst); canvas.scale(scale.width(), scale.height()); canvas.translate(-shaderRect.x(), -shaderRect.y()); canvas.drawPaint(p); @@ -1330,9 +1266,9 @@ SkPDFShader::State::State(SkShader* shader, const SkMatrix& canvasTransform, fShaderTransform.setTranslate(shaderRect.x(), shaderRect.y()); fShaderTransform.preScale(1 / scale.width(), 1 / scale.height()); } - fBitmapKey = SkBitmapKey(fImage); + fBitmapKey = SkBitmapKey(*imageDst); } else { - AllocateGradientInfoStorage(); + this->allocateGradientInfoStorage(); shader->asAGradient(&fInfo); } } @@ -1350,7 +1286,7 @@ SkPDFShader::State::State(const SkPDFShader::State& other) if (fType != SkShader::kNone_GradientType) { fInfo = other.fInfo; - AllocateGradientInfoStorage(); + this->allocateGradientInfoStorage(); for (int i = 0; i < fInfo.fColorCount; i++) { fInfo.fColors[i] = other.fInfo.fColors[i]; fInfo.fColorOffsets[i] = other.fInfo.fColorOffsets[i]; @@ -1362,14 +1298,15 @@ SkPDFShader::State::State(const SkPDFShader::State& other) * Create a copy of this gradient state with alpha assigned to RGB luminousity. * Only valid for gradient states. */ -SkPDFShader::State* SkPDFShader::State::CreateAlphaToLuminosityState() const { +SkPDFShader::State SkPDFShader::State::MakeAlphaToLuminosityState() const { + SkASSERT(fBitmapKey == SkBitmapKey()); SkASSERT(fType != SkShader::kNone_GradientType); - SkPDFShader::State* newState = new SkPDFShader::State(*this); + SkPDFShader::State newState(*this); for (int i = 0; i < fInfo.fColorCount; i++) { SkAlpha alpha = SkColorGetA(fInfo.fColors[i]); - newState->fInfo.fColors[i] = SkColorSetARGB(255, alpha, alpha, alpha); + newState.fInfo.fColors[i] = SkColorSetARGB(255, alpha, alpha, alpha); } return newState; @@ -1379,12 +1316,13 @@ SkPDFShader::State* SkPDFShader::State::CreateAlphaToLuminosityState() const { * Create a copy of this gradient state with alpha set to fully opaque * Only valid for gradient states. */ -SkPDFShader::State* SkPDFShader::State::CreateOpaqueState() const { +SkPDFShader::State SkPDFShader::State::MakeOpaqueState() const { + SkASSERT(fBitmapKey == SkBitmapKey()); SkASSERT(fType != SkShader::kNone_GradientType); - SkPDFShader::State* newState = new SkPDFShader::State(*this); + SkPDFShader::State newState(*this); for (int i = 0; i < fInfo.fColorCount; i++) { - newState->fInfo.fColors[i] = SkColorSetA(fInfo.fColors[i], + newState.fInfo.fColors[i] = SkColorSetA(fInfo.fColors[i], SK_AlphaOPAQUE); } @@ -1408,10 +1346,9 @@ bool SkPDFShader::State::GradientHasAlpha() const { return false; } -void SkPDFShader::State::AllocateGradientInfoStorage() { - fColorData.set(sk_malloc_throw( - fInfo.fColorCount * (sizeof(SkColor) + sizeof(SkScalar)))); - fInfo.fColors = reinterpret_cast<SkColor*>(fColorData.get()); - fInfo.fColorOffsets = - reinterpret_cast<SkScalar*>(fInfo.fColors + fInfo.fColorCount); +void SkPDFShader::State::allocateGradientInfoStorage() { + fColors.reset(new SkColor[fInfo.fColorCount]); + fStops.reset(new SkScalar[fInfo.fColorCount]); + fInfo.fColors = fColors.get(); + fInfo.fColorOffsets = fStops.get(); } |