Flutter Engine
The Flutter Engine
Classes | Macros | Functions
SkPDFDevice.cpp File Reference
#include "src/pdf/SkPDFDevice.h"
#include "include/core/SkAlphaType.h"
#include "include/core/SkBitmap.h"
#include "include/core/SkBlendMode.h"
#include "include/core/SkCanvas.h"
#include "include/core/SkClipOp.h"
#include "include/core/SkColor.h"
#include "include/core/SkColorFilter.h"
#include "include/core/SkColorSpace.h"
#include "include/core/SkColorType.h"
#include "include/core/SkData.h"
#include "include/core/SkFont.h"
#include "include/core/SkImage.h"
#include "include/core/SkImageInfo.h"
#include "include/core/SkM44.h"
#include "include/core/SkPaint.h"
#include "include/core/SkPath.h"
#include "include/core/SkPathEffect.h"
#include "include/core/SkPathTypes.h"
#include "include/core/SkPathUtils.h"
#include "include/core/SkPixmap.h"
#include "include/core/SkPoint.h"
#include "include/core/SkRect.h"
#include "include/core/SkShader.h"
#include "include/core/SkSize.h"
#include "include/core/SkSpan.h"
#include "include/core/SkStrokeRec.h"
#include "include/core/SkSurface.h"
#include "include/core/SkSurfaceProps.h"
#include "include/core/SkTypeface.h"
#include "include/core/SkTypes.h"
#include "include/docs/SkPDFDocument.h"
#include "include/encode/SkJpegEncoder.h"
#include "include/pathops/SkPathOps.h"
#include "include/private/base/SkDebug.h"
#include "include/private/base/SkTemplates.h"
#include "include/private/base/SkTo.h"
#include "src/base/SkScopeExit.h"
#include "src/base/SkTLazy.h"
#include "src/base/SkUTF.h"
#include "src/core/SkAdvancedTypefaceMetrics.h"
#include "src/core/SkAnnotationKeys.h"
#include "src/core/SkBitmapDevice.h"
#include "src/core/SkBlendModePriv.h"
#include "src/core/SkColorSpacePriv.h"
#include "src/core/SkDevice.h"
#include "src/core/SkDraw.h"
#include "src/core/SkGlyph.h"
#include "src/core/SkMask.h"
#include "src/core/SkMaskFilterBase.h"
#include "src/core/SkPaintPriv.h"
#include "src/core/SkRasterClip.h"
#include "src/core/SkSpecialImage.h"
#include "src/core/SkStrikeSpec.h"
#include "src/pdf/SkBitmapKey.h"
#include "src/pdf/SkClusterator.h"
#include "src/pdf/SkPDFBitmap.h"
#include "src/pdf/SkPDFDocumentPriv.h"
#include "src/pdf/SkPDFFont.h"
#include "src/pdf/SkPDFFormXObject.h"
#include "src/pdf/SkPDFGraphicState.h"
#include "src/pdf/SkPDFResourceDict.h"
#include "src/pdf/SkPDFShader.h"
#include "src/pdf/SkPDFTag.h"
#include "src/pdf/SkPDFTypes.h"
#include "src/pdf/SkPDFUtils.h"
#include "src/shaders/SkColorShader.h"
#include "src/shaders/SkShaderBase.h"
#include "src/text/GlyphRun.h"
#include "src/utils/SkClipStackUtils.h"
#include <algorithm>
#include <cstdint>
#include <cstring>
#include <utility>
#include <vector>

Go to the source code of this file.

Classes

class  ScopedContentEntry
 

Macros

#define SK_PDF_MASK_QUALITY   50
 

Functions

sk_sp< SkImagemask_to_greyscale_image (SkMaskBuilder *mask)
 
sk_sp< SkImagealpha_image_to_greyscale_image (const SkImage *mask)
 
static int add_resource (THashSet< SkPDFIndirectReference > &resources, SkPDFIndirectReference ref)
 
static void draw_points (SkCanvas::PointMode mode, size_t count, const SkPoint *points, const SkPaint &paint, const SkIRect &bounds, SkDevice *device)
 
static void transform_shader (SkPaint *paint, const SkMatrix &ctm)
 
static SkTCopyOnFirstWrite< SkPaintclean_paint (const SkPaint &srcPaint)
 
static void set_style (SkTCopyOnFirstWrite< SkPaint > *paint, SkPaint::Style style)
 
static bool calculate_inverse_path (const SkRect &bounds, const SkPath &invPath, SkPath *outPath)
 
static SkUnichar map_glyph (const std::vector< SkUnichar > &glyphToUnicode, SkGlyphID glyph)
 
static SkRect get_glyph_bounds_device_space (const SkGlyph *glyph, SkScalar xScale, SkScalar yScale, SkPoint xy, const SkMatrix &ctm)
 
static bool contains (const SkRect &r, SkPoint p)
 
static bool needs_new_font (SkPDFFont *font, const SkGlyph *glyph, SkAdvancedTypefaceMetrics::FontType fontType)
 
static std::vector< SkPDFIndirectReferencesort (const THashSet< SkPDFIndirectReference > &src)
 
static bool treat_as_regular_pdf_blend_mode (SkBlendMode blendMode)
 
static void populate_graphic_state_entry_from_paint (SkPDFDocument *doc, const SkMatrix &matrix, const SkClipStack *clipStack, SkIRect deviceBounds, const SkPaint &paint, const SkMatrix &initialTransform, SkScalar textScale, SkPDFGraphicStackState::Entry *entry, THashSet< SkPDFIndirectReference > *shaderResources, THashSet< SkPDFIndirectReference > *graphicStateResources)
 
static SkSize rect_to_size (const SkRect &r)
 
static sk_sp< SkImagecolor_filter (const SkImage *image, SkColorFilter *colorFilter)
 
static bool is_integer (SkScalar x)
 
static bool is_integral (const SkRect &r)
 

Macro Definition Documentation

◆ SK_PDF_MASK_QUALITY

#define SK_PDF_MASK_QUALITY   50

Definition at line 95 of file SkPDFDevice.cpp.

Function Documentation

◆ add_resource()

static int add_resource ( THashSet< SkPDFIndirectReference > &  resources,
SkPDFIndirectReference  ref 
)
static

Definition at line 181 of file SkPDFDevice.cpp.

181 {
182 resources.add(ref);
183 return ref.fValue;
184}
void add(T item)
Definition: SkTHash.h:592

◆ alpha_image_to_greyscale_image()

sk_sp< SkImage > alpha_image_to_greyscale_image ( const SkImage mask)

Definition at line 168 of file SkPDFDevice.cpp.

168 {
169 int w = mask->width(), h = mask->height();
170 SkBitmap greyBitmap;
172 // TODO: support gpu images in pdf
173 if (!mask->readPixels(nullptr, SkImageInfo::MakeA8(w, h),
174 greyBitmap.getPixels(), greyBitmap.rowBytes(), 0, 0)) {
175 return nullptr;
176 }
177 greyBitmap.setImmutable();
178 return greyBitmap.asImage();
179}
@ kOpaque_SkAlphaType
pixel is opaque
Definition: SkAlphaType.h:28
@ kGray_8_SkColorType
pixel with grayscale level in 8-bit byte
Definition: SkColorType.h:35
void allocPixels(const SkImageInfo &info, size_t rowBytes)
Definition: SkBitmap.cpp:258
sk_sp< SkImage > asImage() const
Definition: SkBitmap.cpp:645
void setImmutable()
Definition: SkBitmap.cpp:400
size_t rowBytes() const
Definition: SkBitmap.h:238
void * getPixels() const
Definition: SkBitmap.h:283
bool readPixels(GrDirectContext *context, const SkImageInfo &dstInfo, void *dstPixels, size_t dstRowBytes, int srcX, int srcY, CachingHint cachingHint=kAllow_CachingHint) const
Definition: SkImage.cpp:42
int width() const
Definition: SkImage.h:285
int height() const
Definition: SkImage.h:291
SkScalar w
SkScalar h
static SkImageInfo Make(int width, int height, SkColorType ct, SkAlphaType at)
static SkImageInfo MakeA8(int width, int height)

◆ calculate_inverse_path()

static bool calculate_inverse_path ( const SkRect bounds,
const SkPath invPath,
SkPath outPath 
)
static

Definition at line 250 of file SkPDFDevice.cpp.

251 {
252 SkASSERT(invPath.isInverseFillType());
253 return Op(SkPath::Rect(bounds), invPath, kIntersect_SkPathOp, outPath);
254}
#define SkASSERT(cond)
Definition: SkAssert.h:116
@ kIntersect_SkPathOp
intersect the two paths
Definition: SkPathOps.h:24
bool isInverseFillType() const
Definition: SkPath.h:244
static SkPath Rect(const SkRect &, SkPathDirection=SkPathDirection::kCW, unsigned startIndex=0)
Definition: SkPath.cpp:3586
Optional< SkRect > bounds
Definition: SkRecords.h:189

◆ clean_paint()

static SkTCopyOnFirstWrite< SkPaint > clean_paint ( const SkPaint srcPaint)
static

Definition at line 223 of file SkPDFDevice.cpp.

223 {
225 // If the paint will definitely draw opaquely, replace kSrc with
226 // kSrcOver. http://crbug.com/473572
227 if (!paint->isSrcOver() &&
229 {
230 paint.writable()->setBlendMode(SkBlendMode::kSrcOver);
231 }
232 if (paint->getColorFilter()) {
233 // We assume here that PDFs all draw in sRGB.
235 }
236 SkASSERT(!paint->getColorFilter());
237 return paint;
238}
SkBlendFastPath CheckFastPath(const SkPaint &paint, bool dstIsOpaque)
@ kSrcOver
r = s + (1-sa)*d
SkColorSpace * sk_srgb_singleton()
static void RemoveColorFilter(SkPaint *, SkColorSpace *dstCS)
const Paint & paint
Definition: color_source.cc:38

◆ color_filter()

static sk_sp< SkImage > color_filter ( const SkImage image,
SkColorFilter colorFilter 
)
static

Definition at line 1492 of file SkPDFDevice.cpp.

1493 {
1496 SkCanvas* canvas = surface->getCanvas();
1497 canvas->clear(SK_ColorTRANSPARENT);
1498 SkPaint paint;
1499 paint.setColorFilter(sk_ref_sp(colorFilter));
1500 canvas->drawImage(image, 0, 0, SkSamplingOptions(), &paint);
1501 return surface->makeImageSnapshot();
1502}
constexpr SkColor SK_ColorTRANSPARENT
Definition: SkColor.h:99
sk_sp< T > sk_ref_sp(T *obj)
Definition: SkRefCnt.h:381
void clear(SkColor color)
Definition: SkCanvas.h:1199
void drawImage(const SkImage *image, SkScalar left, SkScalar top)
Definition: SkCanvas.h:1528
SkISize dimensions() const
Definition: SkImage.h:297
VkSurfaceKHR surface
Definition: main.cc:49
sk_sp< const SkImage > image
Definition: SkRecords.h:269
SK_API sk_sp< SkSurface > Raster(const SkImageInfo &imageInfo, size_t rowBytes, const SkSurfaceProps *surfaceProps)
SkSamplingOptions(SkFilterMode::kLinear))
static SkImageInfo MakeN32Premul(int width, int height)

◆ contains()

static bool contains ( const SkRect r,
SkPoint  p 
)
static

Definition at line 795 of file SkPDFDevice.cpp.

795 {
796 return r.left() <= p.x() && p.x() <= r.right() &&
797 r.top() <= p.y() && p.y() <= r.bottom();
798}
constexpr float left() const
Definition: SkRect.h:734
constexpr float top() const
Definition: SkRect.h:741
constexpr float right() const
Definition: SkRect.h:748
constexpr float bottom() const
Definition: SkRect.h:755

◆ draw_points()

static void draw_points ( SkCanvas::PointMode  mode,
size_t  count,
const SkPoint points,
const SkPaint paint,
const SkIRect bounds,
SkDevice device 
)
static

Definition at line 186 of file SkPDFDevice.cpp.

191 {
193 SkDraw draw;
194 draw.fDst = SkPixmap(SkImageInfo::MakeUnknown(bounds.right(), bounds.bottom()), nullptr, 0);
195 draw.fCTM = &device->localToDevice();
196 draw.fRC = &rc;
197 draw.drawPoints(mode, count, points, paint, device);
198}
int count
Definition: FontMgrTest.cpp:50
static const int points[]
static void draw(SkCanvas *canvas, SkRect &target, int x, int y)
Definition: aaclip.cpp:27
Definition: SkDraw.h:38
VkDevice device
Definition: main.cc:53
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 mode
Definition: switches.h:228
static SkImageInfo MakeUnknown()
Definition: SkImageInfo.h:357

◆ get_glyph_bounds_device_space()

static SkRect get_glyph_bounds_device_space ( const SkGlyph glyph,
SkScalar  xScale,
SkScalar  yScale,
SkPoint  xy,
const SkMatrix ctm 
)
static

Definition at line 786 of file SkPDFDevice.cpp.

788 {
789 SkRect glyphBounds = SkMatrix::Scale(xScale, yScale).mapRect(glyph->rect());
790 glyphBounds.offset(xy);
791 ctm.mapRect(&glyphBounds); // now in dev space.
792 return glyphBounds;
793}
SkRect rect() const
Definition: SkGlyph.h:506
static SkMatrix Scale(SkScalar sx, SkScalar sy)
Definition: SkMatrix.h:75
bool mapRect(SkRect *dst, const SkRect &src, SkApplyPerspectiveClip pc=SkApplyPerspectiveClip::kYes) const
Definition: SkMatrix.cpp:1141
void offset(float dx, float dy)
Definition: SkRect.h:1016

◆ is_integer()

static bool is_integer ( SkScalar  x)
static

Definition at line 1506 of file SkPDFDevice.cpp.

1506 {
1507 return x == SkScalarTruncToScalar(x);
1508}
#define SkScalarTruncToScalar(x)
Definition: SkScalar.h:33
double x

◆ is_integral()

static bool is_integral ( const SkRect r)
static

Definition at line 1510 of file SkPDFDevice.cpp.

1510 {
1511 return is_integer(r.left()) &&
1512 is_integer(r.top()) &&
1513 is_integer(r.right()) &&
1514 is_integer(r.bottom());
1515}
static bool is_integer(SkScalar x)

◆ map_glyph()

static SkUnichar map_glyph ( const std::vector< SkUnichar > &  glyphToUnicode,
SkGlyphID  glyph 
)
static

Definition at line 775 of file SkPDFDevice.cpp.

775 {
776 return glyph < glyphToUnicode.size() ? glyphToUnicode[SkToInt(glyph)] : -1;
777}
constexpr int SkToInt(S x)
Definition: SkTo.h:29

◆ mask_to_greyscale_image()

sk_sp< SkImage > mask_to_greyscale_image ( SkMaskBuilder mask)

Definition at line 142 of file SkPDFDevice.cpp.

142 {
143 sk_sp<SkImage> img;
146 mask->fImage, mask->fRowBytes);
147 const int imgQuality = SK_PDF_MASK_QUALITY;
148 if (imgQuality <= 100 && imgQuality >= 0) {
150 SkJpegEncoder::Options jpegOptions;
151 jpegOptions.fQuality = imgQuality;
152 if (SkJpegEncoder::Encode(&buffer, pm, jpegOptions)) {
153 img = SkImages::DeferredFromEncodedData(buffer.detachAsData());
154 SkASSERT(img);
155 if (img) {
157 }
158 }
159 }
160 if (!img) {
162 pm, [](const void* p, void*) { SkMaskBuilder::FreeImage(const_cast<void*>(p)); }, nullptr);
163 }
164 *mask = SkMaskBuilder(); // destructive;
165 return img;
166}
#define SK_PDF_MASK_QUALITY
Definition: SkPDFDevice.cpp:95
SK_API sk_sp< SkImage > DeferredFromEncodedData(sk_sp< SkData > encoded, std::optional< SkAlphaType > alphaType=std::nullopt)
SK_API sk_sp< SkImage > RasterFromPixmap(const SkPixmap &pixmap, RasterReleaseProc rasterReleaseProc, ReleaseContext releaseContext)
SK_API bool Encode(SkWStream *dst, const SkPixmap &src, const Options &options)
DEF_SWITCHES_START aot vmservice shared library Name of the *so containing AOT compiled Dart assets for launching the service isolate vm snapshot The VM snapshot data that will be memory mapped as read only SnapshotAssetPath must be present isolate snapshot The isolate snapshot data that will be memory mapped as read only SnapshotAssetPath must be present cache dir Path to the cache directory This is different from the persistent_cache_path in embedder which is used for Skia shader cache icu native lib Path to the library file that exports the ICU data vm service The hostname IP address on which the Dart VM Service should be served If not defaults to or::depending on whether ipv6 is specified vm service A custom Dart VM Service port The default is to pick a randomly available open port disable vm Disable the Dart VM Service The Dart VM Service is never available in release mode disable vm service Disable mDNS Dart VM Service publication Bind to the IPv6 localhost address for the Dart VM Service Ignored if vm service host is set endless trace buffer
Definition: switches.h:126
constexpr int32_t height() const
Definition: SkRect.h:165
constexpr int32_t width() const
Definition: SkRect.h:158
static void FreeImage(void *image)
Definition: SkMask.cpp:57
uint8_t *& image()
Definition: SkMask.h:236
const uint32_t fRowBytes
Definition: SkMask.h:43
uint8_t const *const fImage
Definition: SkMask.h:41
const SkIRect fBounds
Definition: SkMask.h:42

◆ needs_new_font()

static bool needs_new_font ( SkPDFFont font,
const SkGlyph glyph,
SkAdvancedTypefaceMetrics::FontType  fontType 
)
static

Definition at line 839 of file SkPDFDevice.cpp.

840 {
841 if (!font || !font->hasGlyph(glyph->getGlyphID())) {
842 return true;
843 }
845 return false;
846 }
847 if (glyph->isEmpty()) {
848 return false;
849 }
850
851 bool bitmapOnly = nullptr == glyph->path();
852 bool convertedToType3 = (font->getType() == SkAdvancedTypefaceMetrics::kOther_Font);
853 return convertedToType3 != bitmapOnly;
854}
bool isEmpty() const
Definition: SkGlyph.h:514
SkGlyphID getGlyphID() const
Definition: SkGlyph.h:429
const SkPath * path() const
Definition: SkGlyph.cpp:284
font
Font Metadata and Metrics.

◆ populate_graphic_state_entry_from_paint()

static void populate_graphic_state_entry_from_paint ( SkPDFDocument doc,
const SkMatrix matrix,
const SkClipStack clipStack,
SkIRect  deviceBounds,
const SkPaint paint,
const SkMatrix initialTransform,
SkScalar  textScale,
SkPDFGraphicStackState::Entry entry,
THashSet< SkPDFIndirectReference > *  shaderResources,
THashSet< SkPDFIndirectReference > *  graphicStateResources 
)
static

Definition at line 1214 of file SkPDFDevice.cpp.

1224 {
1225 NOT_IMPLEMENTED(paint.getPathEffect() != nullptr, false);
1226 NOT_IMPLEMENTED(paint.getMaskFilter() != nullptr, false);
1227 NOT_IMPLEMENTED(paint.getColorFilter() != nullptr, false);
1228
1229 entry->fMatrix = matrix;
1230 entry->fClipStackGenID = clipStack ? clipStack->getTopmostGenID()
1232 SkColor4f color = paint.getColor4f();
1233 entry->fColor = {color.fR, color.fG, color.fB, 1};
1234 entry->fShaderIndex = -1;
1235
1236 // PDF treats a shader as a color, so we only set one or the other.
1237 SkShader* shader = paint.getShader();
1238 if (shader) {
1239 // note: we always present the alpha as 1 for the shader, knowing that it will be
1240 // accounted for when we create our newGraphicsState (below)
1241 if (as_SB(shader)->type() == SkShaderBase::ShaderType::kColor) {
1242 auto colorShader = static_cast<SkColorShader*>(shader);
1243 // We don't have to set a shader just for a color.
1244 color = SkColor4f::FromColor(colorShader->color());
1245 entry->fColor = {color.fR, color.fG, color.fB, 1};
1246 } else {
1247 // PDF positions patterns relative to the initial transform, so
1248 // we need to apply the current transform to the shader parameters.
1250 transform.postConcat(initialTransform);
1251
1252 // PDF doesn't support kClamp_TileMode, so we simulate it by making
1253 // a pattern the size of the current clip.
1254 SkRect clipStackBounds = clipStack ? clipStack->bounds(deviceBounds)
1255 : SkRect::Make(deviceBounds);
1256
1257 // We need to apply the initial transform to bounds in order to get
1258 // bounds in a consistent coordinate system.
1259 initialTransform.mapRect(&clipStackBounds);
1261 clipStackBounds.roundOut(&bounds);
1262
1263 auto c = paint.getColor4f();
1264 SkPDFIndirectReference pdfShader = SkPDFMakeShader(doc, shader, transform, bounds,
1265 {c.fR, c.fG, c.fB, 1.0f});
1266
1267 if (pdfShader) {
1268 // pdfShader has been canonicalized so we can directly compare pointers.
1269 entry->fShaderIndex = add_resource(*shaderResources, pdfShader);
1270 }
1271 }
1272 }
1273
1274 SkPDFIndirectReference newGraphicState;
1275 if (color == paint.getColor4f()) {
1276 newGraphicState = SkPDFGraphicState::GetGraphicStateForPaint(doc, paint);
1277 } else {
1278 SkPaint newPaint = paint;
1279 newPaint.setColor4f(color, nullptr);
1280 newGraphicState = SkPDFGraphicState::GetGraphicStateForPaint(doc, newPaint);
1281 }
1282 entry->fGraphicStateIndex = add_resource(*graphicStateResources, newGraphicState);
1283 entry->fTextScaleX = textScale;
1284}
static constexpr SkColor kColor
Definition: CanvasTest.cpp:265
static int add_resource(THashSet< SkPDFIndirectReference > &resources, SkPDFIndirectReference ref)
SkPDFIndirectReference SkPDFMakeShader(SkPDFDocument *doc, SkShader *shader, const SkMatrix &canvasTransform, const SkIRect &surfaceBBox, SkColor4f paintColor)
#define NOT_IMPLEMENTED(condition, assertion)
Definition: SkPDFUtils.h:51
SkShaderBase * as_SB(SkShader *shader)
Definition: SkShaderBase.h:412
GLenum type
uint32_t getTopmostGenID() const
static const uint32_t kWideOpenGenID
Definition: SkClipStack.h:387
SkRect bounds(const SkIRect &deviceBounds) const
void setColor4f(const SkColor4f &color, SkColorSpace *colorSpace=nullptr)
Definition: SkPaint.h:253
DlColor color
SkPDFIndirectReference GetGraphicStateForPaint(SkPDFDocument *, const SkPaint &)
unsigned useCenter Optional< SkMatrix > matrix
Definition: SkRecords.h:258
static SkColor4f transform(SkColor4f c, SkColorSpace *src, SkColorSpace *dst)
Definition: p3.cpp:47
Definition: SkRect.h:32
static SkRect Make(const SkISize &size)
Definition: SkRect.h:669
void roundOut(SkIRect *dst) const
Definition: SkRect.h:1241

◆ rect_to_size()

static SkSize rect_to_size ( const SkRect r)
static

Definition at line 1490 of file SkPDFDevice.cpp.

1490{ return {r.width(), r.height()}; }
constexpr float height() const
Definition: SkRect.h:769
constexpr float width() const
Definition: SkRect.h:762

◆ set_style()

static void set_style ( SkTCopyOnFirstWrite< SkPaint > *  paint,
SkPaint::Style  style 
)
static

Definition at line 240 of file SkPDFDevice.cpp.

240 {
241 if (paint->get()->getStyle() != style) {
242 paint->writable()->setStyle(style);
243 }
244}

◆ sort()

static std::vector< SkPDFIndirectReference > sort ( const THashSet< SkPDFIndirectReference > &  src)
static

Definition at line 1061 of file SkPDFDevice.cpp.

1061 {
1062 std::vector<SkPDFIndirectReference> dst;
1063 dst.reserve(src.count());
1064 for (SkPDFIndirectReference ref : src) {
1065 dst.push_back(ref);
1066 }
1067 std::sort(dst.begin(), dst.end(),
1068 [](SkPDFIndirectReference a, SkPDFIndirectReference b) { return a.fValue < b.fValue; });
1069 return dst;
1070}
static std::vector< SkPDFIndirectReference > sort(const THashSet< SkPDFIndirectReference > &src)
static bool b
struct MyStruct a[10]
dst
Definition: cp.py:12

◆ transform_shader()

static void transform_shader ( SkPaint paint,
const SkMatrix ctm 
)
static

Definition at line 200 of file SkPDFDevice.cpp.

200 {
201 SkASSERT(!ctm.isIdentity());
202#if defined(SK_BUILD_FOR_ANDROID_FRAMEWORK)
203 // A shader's matrix is: CTM x LocalMatrix x WrappingLocalMatrix. We want to
204 // switch to device space, where CTM = I, while keeping the original behavior.
205 //
206 // I * LocalMatrix * NewWrappingMatrix = CTM * LocalMatrix
207 // LocalMatrix * NewWrappingMatrix = CTM * LocalMatrix
208 // InvLocalMatrix * LocalMatrix * NewWrappingMatrix = InvLocalMatrix * CTM * LocalMatrix
209 // NewWrappingMatrix = InvLocalMatrix * CTM * LocalMatrix
210 //
212 SkMatrix lmInv;
213 if (lm.invert(&lmInv)) {
214 SkMatrix m = SkMatrix::Concat(SkMatrix::Concat(lmInv, ctm), lm);
215 paint->setShader(paint->getShader()->makeWithLocalMatrix(m));
216 }
217 return;
218#endif
219 paint->setShader(paint->getShader()->makeWithLocalMatrix(ctm));
220}
static SkMatrix Concat(const SkMatrix &a, const SkMatrix &b)
Definition: SkMatrix.h:1775
bool invert(SkMatrix *inverse) const
Definition: SkMatrix.h:1206
bool isIdentity() const
Definition: SkMatrix.h:223
SkMatrix GetShaderLocalMatrix(const SkShader *shader)
Definition: SkPDFUtils.h:129

◆ treat_as_regular_pdf_blend_mode()

static bool treat_as_regular_pdf_blend_mode ( SkBlendMode  blendMode)
static

Definition at line 1210 of file SkPDFDevice.cpp.

1210 {
1211 return nullptr != SkPDFUtils::BlendModeName(blendMode);
1212}
const char * BlendModeName(SkBlendMode)
Definition: SkPDFUtils.cpp:37