Flutter Engine
The Flutter Engine
Functions
SkPDFShader.cpp File Reference
#include "src/pdf/SkPDFShader.h"
#include "include/core/SkBitmap.h"
#include "include/core/SkCanvas.h"
#include "include/core/SkImage.h"
#include "include/core/SkImageInfo.h"
#include "include/core/SkPaint.h"
#include "include/core/SkRefCnt.h"
#include "include/core/SkSamplingOptions.h"
#include "include/core/SkScalar.h"
#include "include/core/SkShader.h"
#include "include/core/SkSize.h"
#include "include/core/SkStream.h"
#include "include/core/SkSurface.h"
#include "include/core/SkTileMode.h"
#include "include/private/base/SkTPin.h"
#include "src/core/SkDevice.h"
#include "src/core/SkTHash.h"
#include "src/pdf/SkKeyedImage.h"
#include "src/pdf/SkPDFDevice.h"
#include "src/pdf/SkPDFDocumentPriv.h"
#include "src/pdf/SkPDFGradientShader.h"
#include "src/pdf/SkPDFUtils.h"
#include "src/shaders/SkShaderBase.h"
#include <memory>
#include <utility>

Go to the source code of this file.

Functions

static void draw (SkCanvas *canvas, const SkImage *image, SkColor4f paintColor)
 
static SkBitmap to_bitmap (const SkImage *image)
 
static void draw_matrix (SkCanvas *canvas, const SkImage *image, const SkMatrix &matrix, SkColor4f paintColor)
 
static void draw_bitmap_matrix (SkCanvas *canvas, const SkBitmap &bm, const SkMatrix &matrix, SkColor4f paintColor)
 
static void fill_color_from_bitmap (SkCanvas *canvas, float left, float top, float right, float bottom, const SkBitmap &bitmap, int x, int y, float alpha)
 
static SkMatrix scale_translate (SkScalar sx, SkScalar sy, SkScalar tx, SkScalar ty)
 
static bool is_tiled (SkTileMode m)
 
static SkPDFIndirectReference make_image_shader (SkPDFDocument *doc, SkMatrix finalMatrix, SkTileMode tileModesX, SkTileMode tileModesY, SkRect bBox, const SkImage *image, SkColor4f paintColor)
 
static SkPDFIndirectReference make_fallback_shader (SkPDFDocument *doc, SkShader *shader, const SkMatrix &canvasTransform, const SkIRect &surfaceBBox, SkColor4f paintColor)
 
static SkColor4f adjust_color (SkShader *shader, SkColor4f paintColor)
 
SkPDFIndirectReference SkPDFMakeShader (SkPDFDocument *doc, SkShader *shader, const SkMatrix &canvasTransform, const SkIRect &surfaceBBox, SkColor4f paintColor)
 

Function Documentation

◆ adjust_color()

static SkColor4f adjust_color ( SkShader shader,
SkColor4f  paintColor 
)
static

Definition at line 325 of file SkPDFShader.cpp.

325 {
326 if (SkImage* img = shader->isAImage(nullptr, (SkTileMode*)nullptr)) {
327 if (img->isAlphaOnly()) {
328 return paintColor;
329 }
330 }
331 return SkColor4f{0, 0, 0, paintColor.fA}; // only preserve the alpha.
332}
SkTileMode
Definition: SkTileMode.h:13
SkImage * isAImage(SkMatrix *localMatrix, SkTileMode xy[2]) const
Definition: SkShader.cpp:22

◆ draw()

static void draw ( SkCanvas canvas,
const SkImage image,
SkColor4f  paintColor 
)
static

Definition at line 36 of file SkPDFShader.cpp.

36 {
37 SkPaint paint(paintColor);
38 canvas->drawImage(image, 0, 0, SkSamplingOptions(), &paint);
39}
void drawImage(const SkImage *image, SkScalar left, SkScalar top)
Definition: SkCanvas.h:1528
const Paint & paint
Definition: color_source.cc:38
sk_sp< const SkImage > image
Definition: SkRecords.h:269
SkSamplingOptions(SkFilterMode::kLinear))

◆ draw_bitmap_matrix()

static void draw_bitmap_matrix ( SkCanvas canvas,
const SkBitmap bm,
const SkMatrix matrix,
SkColor4f  paintColor 
)
static

Definition at line 57 of file SkPDFShader.cpp.

58 {
59 SkAutoCanvasRestore acr(canvas, true);
60 canvas->concat(matrix);
61 SkPaint paint(paintColor);
62 canvas->drawImage(bm.asImage(), 0, 0, SkSamplingOptions(), &paint);
63}
sk_sp< SkImage > asImage() const
Definition: SkBitmap.cpp:645
void concat(const SkMatrix &matrix)
Definition: SkCanvas.cpp:1318
unsigned useCenter Optional< SkMatrix > matrix
Definition: SkRecords.h:258

◆ draw_matrix()

static void draw_matrix ( SkCanvas canvas,
const SkImage image,
const SkMatrix matrix,
SkColor4f  paintColor 
)
static

Definition at line 50 of file SkPDFShader.cpp.

51 {
52 SkAutoCanvasRestore acr(canvas, true);
53 canvas->concat(matrix);
54 draw(canvas, image, paintColor);
55}
static void draw(SkCanvas *canvas, const SkImage *image, SkColor4f paintColor)
Definition: SkPDFShader.cpp:36

◆ fill_color_from_bitmap()

static void fill_color_from_bitmap ( SkCanvas canvas,
float  left,
float  top,
float  right,
float  bottom,
const SkBitmap bitmap,
int  x,
int  y,
float  alpha 
)
static

Definition at line 65 of file SkPDFShader.cpp.

67 {
68 SkRect rect{left, top, right, bottom};
69 if (!rect.isEmpty()) {
70 SkColor4f color = SkColor4f::FromColor(bitmap.getColor(x, y));
71 SkPaint paint(SkColor4f{color.fR, color.fG, color.fB, alpha * color.fA});
72 canvas->drawRect(rect, paint);
73 }
74}
static bool left(const SkPoint &p0, const SkPoint &p1)
static bool right(const SkPoint &p0, const SkPoint &p1)
void drawRect(const SkRect &rect, const SkPaint &paint)
Definition: SkCanvas.cpp:1673
DlColor color
double y
double x
sk_sp< SkBlender > blender SkRect rect
Definition: SkRecords.h:350
Definition: bitmap.py:1

◆ is_tiled()

static bool is_tiled ( SkTileMode  m)
static

◆ make_fallback_shader()

static SkPDFIndirectReference make_fallback_shader ( SkPDFDocument doc,
SkShader shader,
const SkMatrix canvasTransform,
const SkIRect surfaceBBox,
SkColor4f  paintColor 
)
static

Definition at line 273 of file SkPDFShader.cpp.

277 {
278 // surfaceBBox is in device space. While that's exactly what we
279 // want for sizing our bitmap, we need to map it into
280 // shader space for adjustments (to match
281 // MakeImageShader's behavior).
282 SkRect shaderRect = SkRect::Make(surfaceBBox);
283 if (!SkPDFUtils::InverseTransformBBox(canvasTransform, &shaderRect)) {
284 return SkPDFIndirectReference();
285 }
286 // Clamp the bitmap size to about 1M pixels
287 static const int kMaxBitmapArea = 1024 * 1024;
288 SkScalar bitmapArea = (float)surfaceBBox.width() * (float)surfaceBBox.height();
289 SkScalar rasterScale = 1.0f;
290 if (bitmapArea > (float)kMaxBitmapArea) {
291 rasterScale *= SkScalarSqrt((float)kMaxBitmapArea / bitmapArea);
292 }
293
294 SkISize size = {
295 SkTPin(SkScalarCeilToInt(rasterScale * surfaceBBox.width()), 1, kMaxBitmapArea),
296 SkTPin(SkScalarCeilToInt(rasterScale * surfaceBBox.height()), 1, kMaxBitmapArea)};
297 SkSize scale = {SkIntToScalar(size.width()) / shaderRect.width(),
298 SkIntToScalar(size.height()) / shaderRect.height()};
299
302 SkCanvas* canvas = surface->getCanvas();
303 canvas->clear(SK_ColorTRANSPARENT);
304
305 SkPaint p(paintColor);
306 p.setShader(sk_ref_sp(shader));
307
308 canvas->scale(scale.width(), scale.height());
309 canvas->translate(-shaderRect.x(), -shaderRect.y());
310 canvas->drawPaint(p);
311
312 auto shaderTransform = SkMatrix::Translate(shaderRect.x(), shaderRect.y());
313 shaderTransform.preScale(1 / scale.width(), 1 / scale.height());
314
315 sk_sp<SkImage> image = surface->makeImageSnapshot();
317 return make_image_shader(doc,
318 SkMatrix::Concat(canvasTransform, shaderTransform),
320 SkRect::Make(surfaceBBox),
321 image.get(),
322 paintColor);
323}
#define SkASSERT(cond)
Definition: SkAssert.h:116
constexpr SkColor SK_ColorTRANSPARENT
Definition: SkColor.h:99
static SkPDFIndirectReference make_image_shader(SkPDFDocument *doc, SkMatrix finalMatrix, SkTileMode tileModesX, SkTileMode tileModesY, SkRect bBox, const SkImage *image, SkColor4f paintColor)
Definition: SkPDFShader.cpp:84
sk_sp< T > sk_ref_sp(T *obj)
Definition: SkRefCnt.h:381
#define SkScalarCeilToInt(x)
Definition: SkScalar.h:36
#define SkIntToScalar(x)
Definition: SkScalar.h:57
#define SkScalarSqrt(x)
Definition: SkScalar.h:42
static constexpr const T & SkTPin(const T &x, const T &lo, const T &hi)
Definition: SkTPin.h:19
void translate(SkScalar dx, SkScalar dy)
Definition: SkCanvas.cpp:1278
void drawPaint(const SkPaint &paint)
Definition: SkCanvas.cpp:1668
void clear(SkColor color)
Definition: SkCanvas.h:1199
void scale(SkScalar sx, SkScalar sy)
Definition: SkCanvas.cpp:1289
static SkMatrix Translate(SkScalar dx, SkScalar dy)
Definition: SkMatrix.h:91
static SkMatrix Concat(const SkMatrix &a, const SkMatrix &b)
Definition: SkMatrix.h:1775
T * get() const
Definition: SkRefCnt.h:303
VkSurfaceKHR surface
Definition: main.cc:49
float SkScalar
Definition: extension.cpp:12
bool InverseTransformBBox(const SkMatrix &matrix, SkRect *bbox)
Definition: SkPDFUtils.cpp:318
SK_API sk_sp< SkSurface > Raster(const SkImageInfo &imageInfo, size_t rowBytes, const SkSurfaceProps *surfaceProps)
it will be possible to load the file into Perfetto s trace viewer disable asset Prevents usage of any non test fonts unless they were explicitly Loaded via prefetched default font Indicates whether the embedding started a prefetch of the default font manager before creating the engine run In non interactive keep the shell running after the Dart script has completed enable serial On low power devices with low core running concurrent GC tasks on threads can cause them to contend with the UI thread which could potentially lead to jank This option turns off all concurrent GC activities domain network JSON encoded network policy per domain This overrides the DisallowInsecureConnections switch Embedder can specify whether to allow or disallow insecure connections at a domain level old gen heap size
Definition: switches.h:259
const Scalar scale
constexpr int32_t height() const
Definition: SkRect.h:165
constexpr int32_t width() const
Definition: SkRect.h:158
Definition: SkSize.h:16
static SkImageInfo MakeN32Premul(int width, int height)
static SkRect Make(const SkISize &size)
Definition: SkRect.h:669
constexpr float x() const
Definition: SkRect.h:720
constexpr float y() const
Definition: SkRect.h:727
constexpr float height() const
Definition: SkRect.h:769
constexpr float width() const
Definition: SkRect.h:762
Definition: SkSize.h:52

◆ make_image_shader()

static SkPDFIndirectReference make_image_shader ( SkPDFDocument doc,
SkMatrix  finalMatrix,
SkTileMode  tileModesX,
SkTileMode  tileModesY,
SkRect  bBox,
const SkImage image,
SkColor4f  paintColor 
)
static

Definition at line 84 of file SkPDFShader.cpp.

90 {
91 // The image shader pattern cell will be drawn into a separate device
92 // in pattern cell space (no scaling on the bitmap, though there may be
93 // translations so that all content is in the device, coordinates > 0).
94
95 // Map clip bounds to shader space to ensure the device is large enough
96 // to handle fake clamping.
97
98 SkRect deviceBounds = bBox;
99 if (!SkPDFUtils::InverseTransformBBox(finalMatrix, &deviceBounds)) {
100 return SkPDFIndirectReference();
101 }
102
104
105 // For tiling modes, the bounds should be extended to include the bitmap,
106 // otherwise the bitmap gets clipped out and the shader is empty and awful.
107 // For clamp modes, we're only interested in the clip region, whether
108 // or not the main bitmap is in it.
109 if (is_tiled(tileModesX) || is_tiled(tileModesY)) {
110 deviceBounds.join(bitmapBounds);
111 }
112
113 SkISize patternDeviceSize = {SkScalarCeilToInt(deviceBounds.width()),
114 SkScalarCeilToInt(deviceBounds.height())};
115 auto patternDevice = sk_make_sp<SkPDFDevice>(patternDeviceSize, doc);
116 SkCanvas canvas(patternDevice);
117
119 SkScalar width = patternBBox.width();
120 SkScalar height = patternBBox.height();
121
122 // Translate the canvas so that the bitmap origin is at (0, 0).
123 canvas.translate(-deviceBounds.left(), -deviceBounds.top());
124 patternBBox.offset(-deviceBounds.left(), -deviceBounds.top());
125 // Undo the translation in the final matrix
126 finalMatrix.preTranslate(deviceBounds.left(), deviceBounds.top());
127
128 // If the bitmap is out of bounds (i.e. clamp mode where we only see the
129 // stretched sides), canvas will clip this out and the extraneous data
130 // won't be saved to the PDF.
131 draw(&canvas, image, paintColor);
132
133 // Tiling is implied. First we handle mirroring.
134 if (tileModesX == SkTileMode::kMirror) {
135 draw_matrix(&canvas, image, scale_translate(-1, 1, 2 * width, 0), paintColor);
136 patternBBox.fRight += width;
137 }
138 if (tileModesY == SkTileMode::kMirror) {
139 draw_matrix(&canvas, image, scale_translate(1, -1, 0, 2 * height), paintColor);
140 patternBBox.fBottom += height;
141 }
142 if (tileModesX == SkTileMode::kMirror && tileModesY == SkTileMode::kMirror) {
143 draw_matrix(&canvas, image, scale_translate(-1, -1, 2 * width, 2 * height), paintColor);
144 }
145
146 // Then handle Clamping, which requires expanding the pattern canvas to
147 // cover the entire surfaceBBox.
148
150 if (tileModesX == SkTileMode::kClamp || tileModesY == SkTileMode::kClamp) {
151 // For now, the easiest way to access the colors in the corners and sides is
152 // to just make a bitmap from the image.
154 }
155
156 // If both x and y are in clamp mode, we start by filling in the corners.
157 // (Which are just a rectangles of the corner colors.)
158 if (tileModesX == SkTileMode::kClamp && tileModesY == SkTileMode::kClamp) {
159 SkASSERT(!bitmap.drawsNothing());
160
161 fill_color_from_bitmap(&canvas, deviceBounds.left(), deviceBounds.top(), 0, 0,
162 bitmap, 0, 0, paintColor.fA);
163
164 fill_color_from_bitmap(&canvas, width, deviceBounds.top(), deviceBounds.right(), 0,
165 bitmap, bitmap.width() - 1, 0, paintColor.fA);
166
167 fill_color_from_bitmap(&canvas, width, height, deviceBounds.right(), deviceBounds.bottom(),
168 bitmap, bitmap.width() - 1, bitmap.height() - 1, paintColor.fA);
169
170 fill_color_from_bitmap(&canvas, deviceBounds.left(), height, 0, deviceBounds.bottom(),
171 bitmap, 0, bitmap.height() - 1, paintColor.fA);
172 }
173
174 // Then expand the left, right, top, then bottom.
175 if (tileModesX == SkTileMode::kClamp) {
176 SkASSERT(!bitmap.drawsNothing());
177 SkIRect subset = SkIRect::MakeXYWH(0, 0, 1, bitmap.height());
178 if (deviceBounds.left() < 0) {
180 SkAssertResult(bitmap.extractSubset(&left, subset));
181
182 SkMatrix leftMatrix = scale_translate(-deviceBounds.left(), 1, deviceBounds.left(), 0);
183 draw_bitmap_matrix(&canvas, left, leftMatrix, paintColor);
184
185 if (tileModesY == SkTileMode::kMirror) {
186 leftMatrix.postScale(SK_Scalar1, -SK_Scalar1);
187 leftMatrix.postTranslate(0, 2 * height);
188 draw_bitmap_matrix(&canvas, left, leftMatrix, paintColor);
189 }
190 patternBBox.fLeft = 0;
191 }
192
193 if (deviceBounds.right() > width) {
195 subset.offset(bitmap.width() - 1, 0);
196 SkAssertResult(bitmap.extractSubset(&right, subset));
197
198 SkMatrix rightMatrix = scale_translate(deviceBounds.right() - width, 1, width, 0);
199 draw_bitmap_matrix(&canvas, right, rightMatrix, paintColor);
200
201 if (tileModesY == SkTileMode::kMirror) {
202 rightMatrix.postScale(SK_Scalar1, -SK_Scalar1);
203 rightMatrix.postTranslate(0, 2 * height);
204 draw_bitmap_matrix(&canvas, right, rightMatrix, paintColor);
205 }
206 patternBBox.fRight = deviceBounds.width();
207 }
208 }
209 if (tileModesX == SkTileMode::kDecal) {
210 if (deviceBounds.left() < 0) {
211 patternBBox.fLeft = 0;
212 }
213 if (deviceBounds.right() > width) {
214 patternBBox.fRight = deviceBounds.width();
215 }
216 }
217
218 if (tileModesY == SkTileMode::kClamp) {
219 SkASSERT(!bitmap.drawsNothing());
220 SkIRect subset = SkIRect::MakeXYWH(0, 0, bitmap.width(), 1);
221 if (deviceBounds.top() < 0) {
222 SkBitmap top;
223 SkAssertResult(bitmap.extractSubset(&top, subset));
224
225 SkMatrix topMatrix = scale_translate(1, -deviceBounds.top(), 0, deviceBounds.top());
226 draw_bitmap_matrix(&canvas, top, topMatrix, paintColor);
227
228 if (tileModesX == SkTileMode::kMirror) {
229 topMatrix.postScale(-1, 1);
230 topMatrix.postTranslate(2 * width, 0);
231 draw_bitmap_matrix(&canvas, top, topMatrix, paintColor);
232 }
233 patternBBox.fTop = 0;
234 }
235
236 if (deviceBounds.bottom() > height) {
237 SkBitmap bottom;
238 subset.offset(0, bitmap.height() - 1);
239 SkAssertResult(bitmap.extractSubset(&bottom, subset));
240
241 SkMatrix bottomMatrix = scale_translate(1, deviceBounds.bottom() - height, 0, height);
242 draw_bitmap_matrix(&canvas, bottom, bottomMatrix, paintColor);
243
244 if (tileModesX == SkTileMode::kMirror) {
245 bottomMatrix.postScale(-1, 1);
246 bottomMatrix.postTranslate(2 * width, 0);
247 draw_bitmap_matrix(&canvas, bottom, bottomMatrix, paintColor);
248 }
249 patternBBox.fBottom = deviceBounds.height();
250 }
251 }
252 if (tileModesY == SkTileMode::kDecal) {
253 if (deviceBounds.top() < 0) {
254 patternBBox.fTop = 0;
255 }
256 if (deviceBounds.bottom() > height) {
257 patternBBox.fBottom = deviceBounds.height();
258 }
259 }
260
261 auto imageShader = patternDevice->content();
262 std::unique_ptr<SkPDFDict> resourceDict = patternDevice->makeResourceDict();
263 std::unique_ptr<SkPDFDict> dict = SkPDFMakeDict();
264 SkPDFUtils::PopulateTilingPatternDict(dict.get(), patternBBox,
265 std::move(resourceDict), finalMatrix);
266 return SkPDFStreamOut(std::move(dict), std::move(imageShader), doc);
267}
SkAssertResult(font.textToGlyphs("Hello", 5, SkTextEncoding::kUTF8, glyphs, std::size(glyphs))==count)
static void draw_matrix(SkCanvas *canvas, const SkImage *image, const SkMatrix &matrix, SkColor4f paintColor)
Definition: SkPDFShader.cpp:50
static void draw_bitmap_matrix(SkCanvas *canvas, const SkBitmap &bm, const SkMatrix &matrix, SkColor4f paintColor)
Definition: SkPDFShader.cpp:57
static bool is_tiled(SkTileMode m)
Definition: SkPDFShader.cpp:82
static void fill_color_from_bitmap(SkCanvas *canvas, float left, float top, float right, float bottom, const SkBitmap &bitmap, int x, int y, float alpha)
Definition: SkPDFShader.cpp:65
static SkBitmap to_bitmap(const SkImage *image)
Definition: SkPDFShader.cpp:41
static SkMatrix scale_translate(SkScalar sx, SkScalar sy, SkScalar tx, SkScalar ty)
Definition: SkPDFShader.cpp:76
SkPDFIndirectReference SkPDFStreamOut(std::unique_ptr< SkPDFDict > dict, std::unique_ptr< SkStreamAsset > content, SkPDFDocument *doc, SkPDFSteamCompressionEnabled compress)
Definition: SkPDFTypes.cpp:591
static std::unique_ptr< SkPDFDict > SkPDFMakeDict(const char *type=nullptr)
Definition: SkPDFTypes.h:185
#define SK_Scalar1
Definition: SkScalar.h:18
SkISize dimensions() const
Definition: SkImage.h:297
SkMatrix & postTranslate(SkScalar dx, SkScalar dy)
Definition: SkMatrix.cpp:281
SkMatrix & postScale(SkScalar sx, SkScalar sy, SkScalar px, SkScalar py)
Definition: SkMatrix.cpp:360
SkMatrix & preTranslate(SkScalar dx, SkScalar dy)
Definition: SkMatrix.cpp:263
void PopulateTilingPatternDict(SkPDFDict *pattern, SkRect &bbox, std::unique_ptr< SkPDFDict > resources, const SkMatrix &matrix)
Definition: SkPDFUtils.cpp:327
int32_t height
int32_t width
Definition: SkRect.h:32
void offset(int32_t dx, int32_t dy)
Definition: SkRect.h:367
static constexpr SkIRect MakeXYWH(int32_t x, int32_t y, int32_t w, int32_t h)
Definition: SkRect.h:104
SkScalar fBottom
larger y-axis bounds
Definition: extension.cpp:17
constexpr float left() const
Definition: SkRect.h:734
constexpr float top() const
Definition: SkRect.h:741
SkScalar fLeft
smaller x-axis bounds
Definition: extension.cpp:14
SkScalar fRight
larger x-axis bounds
Definition: extension.cpp:16
void offset(float dx, float dy)
Definition: SkRect.h:1016
static constexpr SkRect MakeSize(const SkSize &size)
Definition: SkRect.h:633
constexpr float right() const
Definition: SkRect.h:748
void join(const SkRect &r)
Definition: SkRect.cpp:126
constexpr float bottom() const
Definition: SkRect.h:755
SkScalar fTop
smaller y-axis bounds
Definition: extension.cpp:15
static constexpr SkSize Make(SkScalar w, SkScalar h)
Definition: SkSize.h:56

◆ scale_translate()

static SkMatrix scale_translate ( SkScalar  sx,
SkScalar  sy,
SkScalar  tx,
SkScalar  ty 
)
static

Definition at line 76 of file SkPDFShader.cpp.

76 {
77 SkMatrix m;
78 m.setScaleTranslate(sx, sy, tx, ty);
79 return m;
80}

◆ SkPDFMakeShader()

SkPDFIndirectReference SkPDFMakeShader ( SkPDFDocument doc,
SkShader shader,
const SkMatrix ctm,
const SkIRect surfaceBBox,
SkColor4f  paintColor 
)

Make a PDF shader for the passed SkShader. If the SkShader is invalid in some way, returns nullptr.

In PDF parlance, this is a pattern, used in place of a color when the pattern color space is selected.

May cache the shader in the document for later re-use. If this function is called again with an equivalent shader, a new reference to the cached pdf shader may be returned.

Parameters
docThe parent document, must be non-null.
shaderThe SkShader to emulate.
ctmThe current transform matrix. (PDF shaders are absolutely positioned, relative to where the page is drawn.)
surfaceBBoxThe bounding box of the drawing surface (with matrix already applied).
paintColorColor+Alpha of the paint. Color is usually ignored, unless it is a alpha shader.

Definition at line 334 of file SkPDFShader.cpp.

338 {
339 SkASSERT(shader);
340 SkASSERT(doc);
341 if (as_SB(shader)->asGradient() != SkShaderBase::GradientType::kNone) {
342 return SkPDFGradientShader::Make(doc, shader, canvasTransform, surfaceBBox);
343 }
344 if (surfaceBBox.isEmpty()) {
345 return SkPDFIndirectReference();
346 }
348
349 paintColor = adjust_color(shader, paintColor);
350 SkMatrix shaderTransform;
351 SkTileMode imageTileModes[2];
352 if (SkImage* skimg = shader->isAImage(&shaderTransform, imageTileModes)) {
353 SkMatrix finalMatrix = SkMatrix::Concat(canvasTransform, shaderTransform);
355 finalMatrix,
356 surfaceBBox,
358 {imageTileModes[0], imageTileModes[1]},
359 paintColor};
360 SkPDFIndirectReference* shaderPtr = doc->fImageShaderMap.find(key);
361 if (shaderPtr) {
362 return *shaderPtr;
363 }
364 SkPDFIndirectReference pdfShader =
366 finalMatrix,
367 imageTileModes[0],
368 imageTileModes[1],
369 SkRect::Make(surfaceBBox),
370 skimg,
371 paintColor);
372 doc->fImageShaderMap.set(std::move(key), pdfShader);
373 return pdfShader;
374 }
375 // Don't bother to de-dup fallback shader.
376 return make_fallback_shader(doc, shader, canvasTransform, surfaceBBox, paintColor);
377}
SkBitmapKey SkBitmapKeyFromImage(const SkImage *image)
static SkPDFIndirectReference make_fallback_shader(SkPDFDocument *doc, SkShader *shader, const SkMatrix &canvasTransform, const SkIRect &surfaceBBox, SkColor4f paintColor)
static SkColor4f adjust_color(SkShader *shader, SkColor4f paintColor)
SkShaderBase * as_SB(SkShader *shader)
Definition: SkShaderBase.h:412
skia_private::THashMap< SkPDFImageShaderKey, SkPDFIndirectReference, SkPDFImageShaderKey::Hash > fImageShaderMap
SkPDFIndirectReference Make(SkPDFDocument *doc, SkShader *shader, const SkMatrix &matrix, const SkIRect &surfaceBBox)
bool isEmpty() const
Definition: SkRect.h:202

◆ to_bitmap()

static SkBitmap to_bitmap ( const SkImage image)
static

Definition at line 41 of file SkPDFShader.cpp.

41 {
44 bitmap.allocN32Pixels(image->width(), image->height());
45 bitmap.eraseColor(0x00000000);
46 }
47 return bitmap;
48}
int width() const
Definition: SkImage.h:285
int height() const
Definition: SkImage.h:291
bool ToBitmap(const SkImage *img, SkBitmap *dst)
Definition: SkPDFUtils.cpp:348