60#ifndef SK_PDF_MASK_QUALITY
63 #define SK_PDF_MASK_QUALITY 50
76class ScopedOutputMarkedContentTags {
84 fOut->writeText(
"/P <</MCID ");
85 fOut->writeDecAsText(fMark.id());
86 fOut->writeText(
" >>BDC\n");
90 explicit operator bool()
const {
return bool(fMark); }
94 ~ScopedOutputMarkedContentTags() {
96 fOut->writeText(
"EMC\n");
116 if (imgQuality <= 100 && imgQuality >= 0) {
170#if defined(SK_BUILD_FOR_ANDROID_FRAMEWORK)
183 paint->setShader(
paint->getShader()->makeWithLocalMatrix(m));
187 paint->setShader(
paint->getShader()->makeWithLocalMatrix(ctm));
195 if (!
paint->isSrcOver() &&
200 if (
paint->getColorFilter()) {
209 if (
paint->
get()->getStyle() != style) {
210 paint->writable()->setStyle(style);
251 , fClipStack(clipStack)
253 if (matrix.hasPerspective()) {
259 fDevice->setUpContentEntry(clipStack, matrix,
paint, textScale, &fDstFormXObject);
265 if (fContentStream) {
270 fDevice->finishContentEntry(fClipStack, fBlendMode, fDstFormXObject, shape);
274 explicit operator bool()
const {
return fContentStream !=
nullptr; }
279 switch (fBlendMode) {
333void SkPDFDevice::reset() {
334 fGraphicStateResources.
reset();
335 fXObjectResources.
reset();
336 fShaderResources.
reset();
337 fFontResources.
reset();
350 if (rect.isEmpty()) {
353 if (
value->size() !=
sizeof(nodeID)) {
return; }
354 memcpy(&nodeID,
value->data(),
sizeof(nodeID));
372 SkRect transformedRect = pageXform.
mapRect(path.getBounds());
373 if (transformedRect.
isEmpty()) {
385 std::unique_ptr<SkPDFLink> link = std::make_unique<SkPDFLink>(
386 linkType,
value, transformedRect, fNodeId);
399 if (this->hasEmptyClip()) {
411 if (this->hasEmptyClip()) {
428 if (
paint->getPathEffect() || this->localToDevice().hasPerspective()) {
435 if (
paint->getStrokeWidth()) {
441 for (
size_t i = 0; i <
count; i++) {
443 r.
inset(-halfStroke, -halfStroke);
462 for (
size_t i = 1; i <
count; i++) {
468 for (
size_t i = 0; i <
count/2; i++) {
476 for (
size_t i = 0; i <
count; i++) {
505void SkPDFDevice::internalDrawPathWithFilter(
const SkClipStack& clipStack,
516 path.transform(ctm, &path);
538 canvas.drawImage(mask, dstMaskBounds.
x(), dstMaskBounds.
y());
548 maskDevice->makeFormXObjectFromDevice(dstMaskBounds,
true),
false,
549 SkPDFGraphicState::kLuminosity_SMaskMode, fDocument),
content.stream());
552 this->clearMaskOnGraphicState(
content.stream());
564 tmp.insertName(
"SMask",
"None");
565 noSMaskGS = fDocument->
emit(tmp);
567 this->setGraphicState(noSMaskGS, contentStream);
570void SkPDFDevice::internalDrawPath(
const SkClipStack& clipStack,
574 bool pathIsMutable) {
575 if (clipStack.
isEmpty(this->bounds())) {
582 if (
paint->getMaskFilter()) {
583 this->internalDrawPathWithFilter(clipStack, ctm, origPath, *
paint);
589 if (
paint->getPathEffect()) {
590 if (clipStack.
isEmpty(this->bounds())) {
593 if (!pathIsMutable) {
594 modifiedPath = origPath;
595 pathPtr = &modifiedPath;
596 pathIsMutable =
true;
602 if (
paint->getStrokeWidth() != 0) {
603 paint.writable()->setStrokeWidth(0);
606 paint.writable()->setPathEffect(
nullptr);
609 if (this->handleInversePath(*pathPtr, *
paint, pathIsMutable)) {
613 if (!pathIsMutable) {
614 modifiedPath = origPath;
615 pathPtr = &modifiedPath;
616 pathIsMutable =
true;
619 if (
paint->getShader()) {
629 constexpr SkScalar kToleranceScale = 0.0625f;
631 SkScalar tolerance = matrixScale > 0.0f ? kToleranceScale / matrixScale : kToleranceScale;
632 bool consumeDegeratePathSegments =
664class GlyphPositioner {
670 , fCurrentMatrixOrigin(origin)
671 , fTextSkewX(textSkewX) {
673 ~GlyphPositioner() { this->flush(); }
676 fContent->writeText(
"> Tj\n");
685 bool thousandEM = fPDFFont->typeface()->getUnitsPerEm() == 1000;
686 fViewersAgreeOnAdvancesInFont = thousandEM || !convertedToType3;
693 fContent->writeText(
"1 0 ");
695 fContent->writeText(
" -1 ");
697 fContent->writeText(
" ");
699 fContent->writeText(
" Tm\n");
700 fCurrentMatrixOrigin.set(0.0f, 0.0f);
703 SkPoint position = xy - fCurrentMatrixOrigin;
704 if (!fViewersAgreeOnXAdvance || position !=
SkPoint{fXAdvance, 0}) {
707 fContent->writeText(
" ");
709 fContent->writeText(
" Td ");
710 fCurrentMatrixOrigin = xy;
712 fViewersAgreeOnXAdvance =
true;
714 fXAdvance += advanceWidth;
715 if (!fViewersAgreeOnAdvancesInFont) {
716 fViewersAgreeOnXAdvance =
false;
719 fContent->writeText(
"<");
722 if (fPDFFont->multiByteGlyphs()) {
735 bool fViewersAgreeOnAdvancesInFont =
true;
736 bool fViewersAgreeOnXAdvance =
true;
738 bool fInText =
false;
739 bool fInitialized =
false;
744 return glyph < glyphToUnicode.size() ? glyphToUnicode[
SkToInt(glyph)] : -1;
748struct PositionedGlyph {
764 return r.
left() <= p.x() && p.x() <= r.
right() &&
768void SkPDFDevice::drawGlyphRunAsPath(
781 Rec* rec = reinterpret_cast<Rec*>(ctx);
784 total.postTranslate(rec->fPos->fX + rec->fOffset.fX,
785 rec->fPos->fY + rec->fOffset.fY);
786 rec->fPath->addPath(*path, total);
790 this->internalDrawPath(this->cs(), this->localToDevice(), path, runPaint,
true);
799 if (this->localToDevice().hasPerspective()) {
801 this->internalDrawGlyphRun(tmpGlyphRun,
offset, transparent);
803 this->internalDrawGlyphRun(tmpGlyphRun,
offset, transparent);
809 if (!font || !font->hasGlyph(glyph->
getGlyphID())) {
819 bool bitmapOnly =
nullptr == glyph->
path();
821 return convertedToType3 != bitmapOnly;
824void SkPDFDevice::internalDrawGlyphRun(
831 if (!glyphCount || !glyphIDs || glyphRunFont.
getSize() <= 0 || this->hasEmptyClip()) {
837 || this->localToDevice().hasPerspective()
840 this->drawGlyphRunAsPath(glyphRun,
offset, runPaint);
845 SkDebugf(
"SkPDF: glyphRunFont has no typeface.\n");
866 SkScalar textScaleY = textSize / emSize;
878 out->writeText(
"BT\n");
893 if (clusterator.reversedChars()) {
894 out->writeText(
"/ReversedChars BMC\n");
896 SK_AT_SCOPE_EXIT(
if (clusterator.reversedChars()) { out->writeText(
"EMC\n"); } );
897 GlyphPositioner glyphPositioner(out, glyphRunFont.
getSkewX(),
offset);
904 int index = c.fGlyphIndex;
905 int glyphLimit = index + c.fGlyphCount;
907 bool actualText =
false;
909 glyphPositioner.flush();
910 out->writeText(
"EMC\n");
914 const char* textPtr = c.fUtf8Text;
915 const char* textEnd = c.fUtf8Text + c.fTextByteLength;
920 if (textPtr < textEnd || // >1 code
points in cluster
922 unichar !=
map_glyph(glyphToUnicode, glyphIDs[index]))
924 glyphPositioner.flush();
925 out->writeText(
"/Span<</ActualText ");
927 out->writeText(
" >> BDC\n");
932 for (; index < glyphLimit; ++index) {
934 if (numGlyphs <= gid) {
940 glyphs[index], textScaleX, textScaleY,
943 if (!
contains(clipStackBounds, {glyphBounds.
x(), glyphBounds.
y()})) {
947 if (!clipStackBounds.
intersects(glyphBounds)) {
955 glyphPositioner.setFont(font);
960 out->writeText(
" Tf\n");
963 font->noteGlyphUsage(gid);
970 markPoint.
fX = std::min(absoluteGlyphBounds.
fLeft , markPoint.
fX);
971 markPoint.
fY = std::max(absoluteGlyphBounds.
fBottom, markPoint.
fY);
976 glyphPositioner.writeGlyph(encodedGlyph, advance, xy);
986 this->internalDrawGlyphRun(glyphRun, glyphRunList.
origin(),
paint);
991 if (this->hasEmptyClip()) {
998 if (this->hasEmptyClip()) {
1014 pageXform.
mapRect(&shapeBounds);
1017 ScopedOutputMarkedContentTags
mark(fNodeId, point, fDocument,
content);
1030 std::vector<SkPDFIndirectReference> dst;
1031 dst.reserve(src.count());
1035 std::sort(dst.begin(), dst.end(),
1042 sort(fShaderResources),
1043 sort(fXObjectResources),
1044 sort(fFontResources));
1053 return std::make_unique<SkMemoryStream>();
1059 if (fNeedsExtraSave) {
1063 if (fNeedsExtraSave) {
1066 fNeedsExtraSave =
false;
1067 return std::unique_ptr<SkStreamAsset>(
buffer.detachAsStream());
1077bool SkPDFDevice::handleInversePath(
const SkPath& origPath,
1079 bool pathIsMutable) {
1084 if (this->hasEmptyClip()) {
1098 noInversePaint.setStrokeWidth(0);
1099 pathPtr = &modifiedPath;
1114 if (!totalMatrix.
invert(&transformInverse)) {
1129 this->internalDrawPath(this->
cs(), this->
localToDevice(), modifiedPath, noInversePaint,
true);
1136 if (!fInitialTransform.
invert(&inverseTransform)) {
1137 SkDEBUGFAIL(
"Layer initial transform should be invertible.");
1138 inverseTransform.
reset();
1141 const char* colorSpace = alpha ?
"DeviceGray" :
nullptr;
1147 this->makeResourceDict(), inverseTransform, colorSpace);
1156 return this->makeFormXObjectFromDevice(
SkIRect{0, 0, this->
width(), this->
height()}, alpha);
1165 paint.setBlendMode(mode);
1171 sMask, invertClip, SkPDFGraphicState::kAlpha_SMaskMode,
1172 fDocument),
content.stream());
1173 this->drawFormXObject(xObject,
content.stream(),
nullptr);
1174 this->clearMaskOnGraphicState(
content.stream());
1209 if (
as_SB(shader)->
type() == SkShaderBase::ShaderType::kColor) {
1222 SkRect clipStackBounds = clipStack ? clipStack->
bounds(deviceBounds)
1227 initialTransform.
mapRect(&clipStackBounds);
1231 auto c =
paint.getColor4f();
1233 {c.fR, c.fG, c.fB, 1.0f});
1270 if (!isContentEmpty()) {
1271 *
dst = this->makeFormXObjectFromDevice();
1287 fNeedsExtraSave =
true;
1309 &fGraphicStateResources);
1317void SkPDFDevice::finishContentEntry(
const SkClipStack* clipStack,
1337 fNeedsExtraSave =
true;
1347 fNeedsExtraSave =
true;
1368 if (this->isContentEmpty()) {
1377 this->drawFormXObject(dst,
content.stream(),
nullptr);
1383 srcFormXObject = this->makeFormXObjectFromDevice();
1395 if (shape !=
nullptr) {
1402 shapeDev.internalDrawPath(clipStack ? *clipStack :
empty,
1404 this->drawFormXObjectWithMask(dst, shapeDev.makeFormXObjectFromDevice(),
1417 this->drawFormXObject(srcFormXObject,
content.stream(),
nullptr);
1425 this->drawFormXObject(dst,
content.stream(),
nullptr);
1454bool SkPDFDevice::isContentEmpty() {
1469 return surface->makeImageSnapshot();
1485void SkPDFDevice::internalDrawImageRect(
SkKeyedImage imageSubset,
1491 if (this->hasEmptyClip()) {
1520 if (!
paint->isSrcOver() &&
1539 canvas->
clear(0x00000000);
1541 if (
paint->getShader() !=
nullptr) {
1542 paint.writable()->setShader(
nullptr);
1565 if (
paint->getMaskFilter()) {
1578 SkIRect maskDeviceBounds = maskDevice->cs().bounds(maskDevice->bounds()).roundOut();
1587 maskDevice->makeFormXObjectFromDevice(maskDeviceBounds,
true),
false,
1588 SkPDFGraphicState::kLuminosity_SMaskMode, fDocument),
content.stream());
1591 this->clearMaskOnGraphicState(
content.stream());
1594 if (
paint->getMaskFilter()) {
1603 bool needToRestore =
false;
1608 needToRestore =
true;
1628 SkRect physicalBounds = fInitialTransform.
mapRect(outlineBounds);
1662 matrix.setScale(1 / scaleX, 1 / scaleY);
1663 matrix.postTranslate(deltaX, deltaY);
1713 this->drawFormXObject(pdfimage,
content.stream(), &shape);
1728 if (
device->peekPixels(&pmap)) {
1736 if (pdfDevice->isContentEmpty()) {
1753 this->drawFormXObject(pdfDevice->makeFormXObjectFromDevice(),
content.stream(), &shape);
1759 if (this->hasEmptyClip()) {
1766 if (SkSpecialImages::AsBitmap(srcImg, &resultBM)) {
1768 this->internalDrawImageRect(
SkKeyedImage(resultBM),
nullptr, r, sampling,
paint,
1774 return SkSpecialImages::MakeFromRaster(
bitmap.bounds(),
bitmap, this->surfaceProps());
1778 return SkSpecialImages::MakeFromRaster(
static const int strokeWidth
static void info(const char *fmt,...) SK_PRINTF_LIKE(1
static const int points[]
@ kOpaque_SkAlphaType
pixel is opaque
#define SkDEBUGFAIL(message)
SkBlendFastPath CheckFastPath(const SkPaint &paint, bool dstIsOpaque)
@ kMultiply
r = s*(1-da) + d*(1-sa) + s*d
@ kSrcOver
r = s + (1-sa)*d
@ kSrcATop
r = s*da + d*(1-sa)
@ kDstATop
r = d*sa + s*(1-da)
@ kDstOver
r = d + (1-da)*s
void SkClipStack_AsPath(const SkClipStack &cs, SkPath *path)
SkColorSpace * sk_srgb_singleton()
@ kGray_8_SkColorType
pixel with grayscale level in 8-bit byte
constexpr SkColor SK_ColorTRANSPARENT
constexpr SkColor SK_ColorBLACK
void SK_SPI SkDebugf(const char format[],...) SK_PRINTF_LIKE(1
SkMaskFilterBase * as_MFB(SkMaskFilter *mf)
std::unique_ptr< uint8_t, SkFunctionObject< SkMaskBuilder::FreeImage > > SkAutoMaskFreeImage
SkPDFIndirectReference SkPDFSerializeImage(const SkImage *img, SkPDFDocument *doc, int encodingQuality)
sk_sp< SkImage > alpha_image_to_greyscale_image(const SkImage *mask)
static SkTCopyOnFirstWrite< SkPaint > clean_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 bool is_integral(const SkRect &r)
static SkRect get_glyph_bounds_device_space(const SkGlyph *glyph, SkScalar xScale, SkScalar yScale, SkPoint xy, const SkMatrix &ctm)
static bool needs_new_font(SkPDFFont *font, const SkGlyph *glyph, SkAdvancedTypefaceMetrics::FontType fontType)
static int add_resource(THashSet< SkPDFIndirectReference > &resources, SkPDFIndirectReference ref)
static SkSize rect_to_size(const SkRect &r)
sk_sp< SkImage > mask_to_greyscale_image(SkMaskBuilder *mask)
static bool contains(const SkRect &r, SkPoint p)
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 sk_sp< SkImage > color_filter(const SkImage *image, SkColorFilter *colorFilter)
static bool is_integer(SkScalar x)
static void transform_shader(SkPaint *paint, const SkMatrix &ctm)
static std::vector< SkPDFIndirectReference > sort(const THashSet< SkPDFIndirectReference > &src)
static void draw_points(SkCanvas::PointMode mode, size_t count, const SkPoint *points, const SkPaint &paint, const SkIRect &bounds, SkDevice *device)
static bool treat_as_regular_pdf_blend_mode(SkBlendMode blendMode)
static SkUnichar map_glyph(const std::vector< SkUnichar > &glyphToUnicode, SkGlyphID glyph)
#define SK_PDF_MASK_QUALITY
const char * SkPDFGetNodeIdKey()
void SkPDFWriteResourceName(SkWStream *dst, SkPDFResourceType type, int key)
std::unique_ptr< SkPDFDict > SkPDFMakeResourceDict(const std::vector< SkPDFIndirectReference > &graphicStateResources, const std::vector< SkPDFIndirectReference > &shaderResources, const std::vector< SkPDFIndirectReference > &xObjectResources, const std::vector< SkPDFIndirectReference > &fontResources)
SkPDFIndirectReference SkPDFMakeShader(SkPDFDocument *doc, SkShader *shader, const SkMatrix &canvasTransform, const SkIRect &surfaceBBox, SkColor4f paintColor)
void SkPDFWriteTextString(SkWStream *wStream, const char *cin, size_t len)
static std::unique_ptr< SkPDFArray > SkPDFMakeArray(Args... args)
#define NOT_IMPLEMENTED(condition, assert)
@ kIntersect_SkPathOp
intersect the two paths
static SkPath clip(const SkPath &path, const SkHalfPlane &plane)
sk_sp< T > sk_ref_sp(T *obj)
#define SkScalarTruncToScalar(x)
#define SK_AT_SCOPE_EXIT(stmt)
SkShaderBase * as_SB(SkShader *shader)
constexpr int SkToInt(S x)
constexpr uint32_t SkToU32(S x)
static void draw(SkCanvas *canvas, SkRect &target, int x, int y)
const sk_sp< Effect > & get() const
void setShape(const SkPath &shape)
ScopedContentEntry(SkPDFDevice *device, const SkClipStack *clipStack, const SkMatrix &matrix, const SkPaint &paint, SkScalar textScale=0)
ScopedContentEntry(SkPDFDevice *dev, const SkPaint &paint, SkScalar textScale=0)
SkDynamicMemoryWStream * stream()
static const char * Define_Named_Dest_Key()
static const char * Link_Named_Dest_Key()
static const char * URL_Key()
static sk_sp< SkBitmapDevice > Create(const SkImageInfo &, const SkSurfaceProps &, SkRasterHandleAllocator *=nullptr)
void allocPixels(const SkImageInfo &info, size_t rowBytes)
sk_sp< SkImage > asImage() const
bool drawsNothing() const
void drawRect(const SkRect &rect, const SkPaint &paint)
void clipRect(const SkRect &rect, SkClipOp op, bool doAntiAlias)
void clear(SkColor color)
void setMatrix(const SkM44 &matrix)
void concat(const SkMatrix &matrix)
@ kLines_PointMode
draw each pair of points as a line segment
@ kPolygon_PointMode
draw the array of points as a open polygon
@ kPoints_PointMode
draw each point separately
void drawImage(const SkImage *image, SkScalar left, SkScalar top)
SkIRect devClipBounds() const override
void clipRect(const SkRect &, const SkMatrix &matrix, SkClipOp, bool doAA)
bool isEmpty(const SkIRect &deviceBounds) const
uint32_t getTopmostGenID() const
static const uint32_t kWideOpenGenID
SkRect bounds(const SkIRect &deviceBounds) const
const SkMatrix & localToDevice() const
virtual void drawDevice(SkDevice *, const SkSamplingOptions &, const SkPaint &)
const SkM44 & deviceToGlobal() const
static bool DrawToMask(const SkPath &devPath, const SkIRect &clipBounds, const SkMaskFilter *, const SkMatrix *filterMatrix, SkMaskBuilder *dst, SkMaskBuilder::CreateMode mode, SkStrokeRec::InitStyle style)
size_t bytesWritten() const override
bool writeToAndReset(SkWStream *dst)
void prependToAndReset(SkDynamicMemoryWStream *dst)
SkTypeface * getTypeface() const
SkScalar getScaleX() const
SkScalar getSkewX() const
void setEmbolden(bool embolden)
SkGlyphID getGlyphID() const
const SkPath * path() const
SkISize dimensions() const
bool readPixels(GrDirectContext *context, const SkImageInfo &dstInfo, void *dstPixels, size_t dstRowBytes, int srcX, int srcY, CachingHint cachingHint=kAllow_CachingHint) const
sk_sp< SkShader > makeShader(SkTileMode tmx, SkTileMode tmy, const SkSamplingOptions &, const SkMatrix *localMatrix=nullptr) const
sk_sp< SkImage > makeNonTextureImage(GrDirectContext *=nullptr) const
const sk_sp< SkImage > & image() const
SkKeyedImage subset(SkIRect subset) const
const SkBitmapKey & key() const
virtual bool filterMask(SkMaskBuilder *dst, const SkMask &src, const SkMatrix &, SkIPoint *margin) const =0
static SkMatrix Scale(SkScalar sx, SkScalar sy)
SkMatrix & postTranslate(SkScalar dx, SkScalar dy)
static SkMatrix RectToRect(const SkRect &src, const SkRect &dst, ScaleToFit mode=kFill_ScaleToFit)
SkMatrix & postConcat(const SkMatrix &other)
SkMatrix & postScale(SkScalar sx, SkScalar sy, SkScalar px, SkScalar py)
void mapPoints(SkPoint dst[], const SkPoint src[], int count) const
static SkMatrix Concat(const SkMatrix &a, const SkMatrix &b)
SkMatrix & setScale(SkScalar sx, SkScalar sy, SkScalar px, SkScalar py)
bool invert(SkMatrix *inverse) const
void mapXY(SkScalar x, SkScalar y, SkPoint *result) const
static const SkMatrix & I()
bool mapRect(SkRect *dst, const SkRect &src, SkApplyPerspectiveClip pc=SkApplyPerspectiveClip::kYes) const
@ kPerspective_Mask
perspective SkMatrix
@ kIdentity_Mask
identity SkMatrix; all bits clear
SkPDFDevice(SkISize pageSize, SkPDFDocument *document, const SkMatrix &initialTransform=SkMatrix::I())
std::unique_ptr< SkStreamAsset > content()
void drawRect(const SkRect &r, const SkPaint &paint) override
sk_sp< SkDevice > createDevice(const CreateInfo &, const SkPaint *) override
void drawPoints(SkCanvas::PointMode mode, size_t count, const SkPoint[], const SkPaint &paint) override
void drawMesh(const SkMesh &, sk_sp< SkBlender >, const SkPaint &) override
void onDrawGlyphRunList(SkCanvas *, const sktext::GlyphRunList &, const SkPaint &paint) override
void drawVertices(const SkVertices *, sk_sp< SkBlender >, const SkPaint &, bool) override
void drawRRect(const SkRRect &rr, const SkPaint &paint) override
void drawPaint(const SkPaint &paint) override
sk_sp< SkSurface > makeSurface(const SkImageInfo &, const SkSurfaceProps &) override
void drawDevice(SkDevice *, const SkSamplingOptions &, const SkPaint &) override
void drawSpecial(SkSpecialImage *, const SkMatrix &, const SkSamplingOptions &, const SkPaint &, SkCanvas::SrcRectConstraint) override
void drawSprite(const SkBitmap &bitmap, int x, int y, const SkPaint &paint)
void drawImageRect(const SkImage *, const SkRect *src, const SkRect &dst, const SkSamplingOptions &, const SkPaint &, SkCanvas::SrcRectConstraint) override
void drawOval(const SkRect &oval, const SkPaint &paint) override
void drawPath(const SkPath &origpath, const SkPaint &paint, bool pathIsMutable) override
std::unique_ptr< SkPDFDict > makeResourceDict()
void drawAnnotation(const SkRect &, const char key[], SkData *value) override
sk_sp< SkPDFDevice > makeCongruentDevice()
sk_sp< SkSpecialImage > makeSpecial(const SkBitmap &) override
SkPDFIndirectReference currentPage() const
skia_private::THashMap< SkBitmapKey, SkPDFIndirectReference > fPDFBitmapMap
SkPDFIndirectReference emit(const SkPDFObject &, SkPDFIndirectReference)
void addNodeTitle(int nodeId, SkSpan< const char >)
const SkPDF::Metadata & metadata() const
const SkMatrix & currentPageTransform() const
std::vector< SkPDFNamedDestination > fNamedDestinations
SkPDFTagTree::Mark createMarkIdForNodeId(int nodeId, SkPoint)
std::vector< std::unique_ptr< SkPDFLink > > fCurrentPageLinks
SkPDFIndirectReference fNoSmaskGraphicState
bool hasCurrentPage() const
SkAdvancedTypefaceMetrics::FontType getType() const
static const SkAdvancedTypefaceMetrics * GetMetrics(const SkTypeface *typeface, SkPDFDocument *canon)
static SkPDFFont * GetFontResource(SkPDFDocument *doc, const SkGlyph *glyphs, SkTypeface *typeface)
static SkAdvancedTypefaceMetrics::FontType FontType(const SkTypeface &, const SkAdvancedTypefaceMetrics &)
static const std::vector< SkUnichar > & GetUnicodeMap(const SkTypeface *typeface, SkPDFDocument *canon)
static void RemoveColorFilter(SkPaint *, SkColorSpace *dstCS)
void setStyle(Style style)
void setColor(SkColor color)
SkPathEffect * getPathEffect() const
SkColorFilter * getColorFilter() const
@ kStroke_Style
set to stroke geometry
@ kFill_Style
set to fill geometry
@ kStrokeAndFill_Style
sets to stroke and fill geometry
void setColor4f(const SkColor4f &color, SkColorSpace *colorSpace=nullptr)
void setMaskFilter(sk_sp< SkMaskFilter > maskFilter)
SkMaskFilter * getMaskFilter() const
void setShader(sk_sp< SkShader > shader)
SkImageFilter * getImageFilter() const
bool isInverseFillType() const
static SkPath RRect(const SkRRect &, SkPathDirection dir=SkPathDirection::kCW)
static SkPath Rect(const SkRect &, SkPathDirection=SkPathDirection::kCW, unsigned startIndex=0)
SkPathFillType getFillType() const
void toggleInverseFillType()
const SkRect & getBounds() const
static SkPath Oval(const SkRect &, SkPathDirection=SkPathDirection::kCW)
void transform(const SkMatrix &matrix, SkPath *dst, SkApplyPerspectiveClip pc=SkApplyPerspectiveClip::kYes) const
SkPath makeTransform(const SkMatrix &m, SkApplyPerspectiveClip pc=SkApplyPerspectiveClip::kYes) const
constexpr bool empty() const
virtual bool isGaneshBacked() const
virtual bool isGraphiteBacked() const
static SkStrikeSpec MakePDFVector(const SkTypeface &typeface, int *size)
bool writeText(const char text[])
V * find(const K &key) const
SkSpan< const char > text() const
const SkFont & font() const
SkSpan< const SkGlyphID > glyphsIDs() const
SkSpan< const SkPoint > positions() const
EMSCRIPTEN_KEEPALIVE void empty()
static const uint8_t buffer[]
static void mark(SkCanvas *canvas, SkScalar x, SkScalar y, Fn &&fn)
union flutter::testing::@2838::KeyboardChange::@76 content
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)
SkPDFIndirectReference GetGraphicStateForPaint(SkPDFDocument *, const SkPaint &)
SkPDFIndirectReference GetSMaskGraphicState(SkPDFIndirectReference sMask, bool invert, SkPDFSMaskMode sMaskMode, SkPDFDocument *doc)
void ApplyGraphicState(int objectIndex, SkWStream *content)
void WriteUInt8(SkWStream *wStream, uint8_t value)
const char * BlendModeName(SkBlendMode)
void EmitPath(const SkPath &path, SkPaint::Style paintStyle, bool doConsumeDegerates, SkWStream *content, SkScalar tolerance=0.25f)
void AppendRectangle(const SkRect &rect, SkWStream *content)
void PaintPath(SkPaint::Style style, SkPathFillType fill, SkWStream *content)
void AppendScalar(SkScalar value, SkWStream *stream)
void MoveTo(SkScalar x, SkScalar y, SkWStream *content)
void AppendLine(SkScalar x, SkScalar y, SkWStream *content)
void WriteUInt16BE(SkWStream *wStream, uint16_t value)
void AppendTransform(const SkMatrix &, SkWStream *)
SkMatrix GetShaderLocalMatrix(const SkShader *shader)
void ClosePath(SkWStream *content)
void StrokePath(SkWStream *content)
unsigned useCenter Optional< SkMatrix > matrix
SK_API sk_sp< SkSurface > Raster(const SkImageInfo &imageInfo, size_t rowBytes, const SkSurfaceProps *surfaceProps)
SK_SPI SkUnichar NextUTF8(const char **ptr, const char *end)
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
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
font
Font Metadata and Metrics.
SK_API bool FillPathWithPaint(const SkPath &src, const SkPaint &paint, SkPath *dst, const SkRect *cullRect, SkScalar resScale=1)
static SkColor4f transform(SkColor4f c, SkColorSpace *src, SkColorSpace *dst)
static void draw_points(SkCanvas *canvas, SkImage *image)
constexpr int32_t x() const
constexpr int32_t y() const
constexpr int32_t top() const
constexpr int32_t bottom() const
constexpr int32_t height() const
constexpr int32_t right() const
constexpr int32_t width() const
void outset(int32_t dx, int32_t dy)
constexpr int32_t left() const
static SkImageInfo MakeN32Premul(int width, int height)
SkColorSpace * colorSpace() const
SkISize dimensions() const
static SkImageInfo MakeUnknown()
static SkImageInfo Make(int width, int height, SkColorType ct, SkAlphaType at)
static SkImageInfo MakeA8(int width, int height)
static void FreeImage(void *image)
@ kComputeBoundsAndRenderImage_CreateMode
compute bounds, alloc image and render into it
uint8_t const *const fImage
void updateMatrix(const SkMatrix &matrix)
void updateDrawingState(const Entry &state)
SkDynamicMemoryWStream * fContentStream
void updateClip(const SkClipStack *clipStack, const SkIRect &bounds)
constexpr float y() const
constexpr float x() const
static SkRGBA4f FromColor(SkColor color)
static SkRect Make(const SkISize &size)
SkScalar fBottom
larger y-axis bounds
constexpr float left() const
void inset(float dx, float dy)
constexpr float top() const
bool intersect(const SkRect &r)
SkScalar fLeft
smaller x-axis bounds
constexpr float x() const
constexpr float y() const
static constexpr SkRect MakeXYWH(float x, float y, float w, float h)
bool intersects(const SkRect &r) const
void roundOut(SkIRect *dst) const
void offset(float dx, float dy)
constexpr float height() const
constexpr float right() const
constexpr float width() const
static constexpr SkRect MakeWH(float w, float h)
constexpr float bottom() const