Flutter Engine
The Flutter Engine
Loading...
Searching...
No Matches
Classes | Functions | Variables
SkPDFFont.cpp File Reference
#include "include/core/SkBitmap.h"
#include "include/core/SkData.h"
#include "include/core/SkFont.h"
#include "include/core/SkFontMetrics.h"
#include "include/core/SkFontTypes.h"
#include "include/core/SkImage.h"
#include "include/core/SkImageInfo.h"
#include "include/core/SkMatrix.h"
#include "include/core/SkPaint.h"
#include "include/core/SkPath.h"
#include "include/core/SkPoint.h"
#include "include/core/SkRect.h"
#include "include/core/SkRefCnt.h"
#include "include/core/SkScalar.h"
#include "include/core/SkStream.h"
#include "include/core/SkString.h"
#include "include/core/SkSurfaceProps.h"
#include "include/core/SkTypes.h"
#include "include/docs/SkPDFDocument.h"
#include "include/private/base/SkTo.h"
#include "src/base/SkBitmaskEnum.h"
#include "src/base/SkUTF.h"
#include "src/core/SkGlyph.h"
#include "src/core/SkImagePriv.h"
#include "src/core/SkMask.h"
#include "src/core/SkScalerContext.h"
#include "src/core/SkStrike.h"
#include "src/core/SkStrikeSpec.h"
#include "src/core/SkTHash.h"
#include "src/pdf/SkPDFBitmap.h"
#include "src/pdf/SkPDFDevice.h"
#include "src/pdf/SkPDFDocumentPriv.h"
#include "src/pdf/SkPDFFont.h"
#include "src/pdf/SkPDFFormXObject.h"
#include "src/pdf/SkPDFMakeCIDGlyphWidthsArray.h"
#include "src/pdf/SkPDFMakeToUnicodeCmap.h"
#include "src/pdf/SkPDFSubsetFont.h"
#include "src/pdf/SkPDFType1Font.h"
#include "src/pdf/SkPDFUtils.h"
#include <limits.h>
#include <initializer_list>
#include <memory>
#include <utility>

Go to the source code of this file.

Classes

struct  ImageAndOffset
 

Functions

static bool can_embed (const SkAdvancedTypefaceMetrics &metrics)
 
static SkGlyphID first_nonzero_glyph_for_single_byte_encoding (SkGlyphID gid)
 
static sk_sp< SkDatastream_to_data (std::unique_ptr< SkStreamAsset > stream)
 
static void emit_subset_type0 (const SkPDFFont &font, SkPDFDocument *doc)
 
static ImageAndOffset to_image (SkGlyphID gid, SkBulkGlyphMetricsAndImages *smallGlyphs)
 
static SkPDFIndirectReference type3_descriptor (SkPDFDocument *doc, const SkTypeface *typeface, SkScalar xHeight)
 
SkStrikeSpec make_small_strike (const SkTypeface &typeface)
 
static void emit_subset_type3 (const SkPDFFont &pdfFont, SkPDFDocument *doc)
 

Variables

static constexpr float kBitmapFontSize = 64
 

Function Documentation

◆ can_embed()

static bool can_embed ( const SkAdvancedTypefaceMetrics metrics)
static

Definition at line 104 of file SkPDFFont.cpp.

104 {
106}
static constexpr bool SkToBool(const T &x)
Definition SkTo.h:35
@ kNotEmbeddable_FontFlag
May not be embedded.

◆ emit_subset_type0()

static void emit_subset_type0 ( const SkPDFFont font,
SkPDFDocument doc 
)
static

Definition at line 299 of file SkPDFFont.cpp.

299 {
300 const SkAdvancedTypefaceMetrics* metricsPtr =
301 SkPDFFont::GetMetrics(font.typeface(), doc);
302 SkASSERT(metricsPtr);
303 if (!metricsPtr) { return; }
304 const SkAdvancedTypefaceMetrics& metrics = *metricsPtr;
305 SkASSERT(can_embed(metrics));
307 SkTypeface* face = font.typeface();
308 SkASSERT(face);
309
310 auto descriptor = SkPDFMakeDict("FontDescriptor");
311 uint16_t emSize = SkToU16(font.typeface()->getUnitsPerEm());
312 SkPDFFont::PopulateCommonFontDescriptor(descriptor.get(), metrics, emSize, 0);
313
314 int ttcIndex;
315 std::unique_ptr<SkStreamAsset> fontAsset = face->openStream(&ttcIndex);
316 size_t fontSize = fontAsset ? fontAsset->getLength() : 0;
317 if (0 == fontSize) {
318 SkDebugf("Error: (SkTypeface)(%p)::openStream() returned "
319 "empty stream (%p) when identified as kType1CID_Font "
320 "or kTrueType_Font.\n", face, fontAsset.get());
321 } else {
322 switch (type) {
325 if (!SkToBool(metrics.fFlags &
327 SkASSERT(font.firstGlyphID() == 1);
328 sk_sp<SkData> subsetFontData = SkPDFSubsetFont(
329 stream_to_data(std::move(fontAsset)), font.glyphUsage(),
330 doc->metadata().fSubsetter,
331 ttcIndex);
332 if (subsetFontData) {
333 std::unique_ptr<SkPDFDict> tmp = SkPDFMakeDict();
334 tmp->insertInt("Length1", SkToInt(subsetFontData->size()));
335 descriptor->insertRef(
336 "FontFile2",
337 SkPDFStreamOut(std::move(tmp),
338 SkMemoryStream::Make(std::move(subsetFontData)),
340 break;
341 }
342 // If subsetting fails, fall back to original font data.
343 fontAsset = face->openStream(&ttcIndex);
344 SkASSERT(fontAsset);
345 SkASSERT(fontAsset->getLength() == fontSize);
346 if (!fontAsset || fontAsset->getLength() == 0) { break; }
347 }
348 std::unique_ptr<SkPDFDict> tmp = SkPDFMakeDict();
349 tmp->insertInt("Length1", fontSize);
350 descriptor->insertRef("FontFile2",
351 SkPDFStreamOut(std::move(tmp), std::move(fontAsset),
353 break;
354 }
356 std::unique_ptr<SkPDFDict> tmp = SkPDFMakeDict();
357 tmp->insertName("Subtype", "CIDFontType0C");
358 descriptor->insertRef("FontFile3",
359 SkPDFStreamOut(std::move(tmp), std::move(fontAsset),
361 break;
362 }
363 default:
364 SkASSERT(false);
365 }
366 }
367
368 auto newCIDFont = SkPDFMakeDict("Font");
369 newCIDFont->insertRef("FontDescriptor", doc->emit(*descriptor));
370 newCIDFont->insertName("BaseFont", metrics.fPostScriptName);
371
372 switch (type) {
374 newCIDFont->insertName("Subtype", "CIDFontType0");
375 break;
378 newCIDFont->insertName("Subtype", "CIDFontType2");
379 newCIDFont->insertName("CIDToGIDMap", "Identity");
380 break;
381 default:
382 SkASSERT(false);
383 }
384 auto sysInfo = SkPDFMakeDict();
385 // These are actually ASCII strings.
386 sysInfo->insertByteString("Registry", "Adobe");
387 sysInfo->insertByteString("Ordering", "Identity");
388 sysInfo->insertInt("Supplement", 0);
389 newCIDFont->insertObject("CIDSystemInfo", std::move(sysInfo));
390
391 // Unfortunately, poppler enforces DW (default width) must be an integer.
392 int32_t defaultWidth = 0;
393 {
394 std::unique_ptr<SkPDFArray> widths = SkPDFMakeCIDGlyphWidthsArray(
395 *face, font.glyphUsage(), &defaultWidth);
396 if (widths && widths->size() > 0) {
397 newCIDFont->insertObject("W", std::move(widths));
398 }
399 newCIDFont->insertInt("DW", defaultWidth);
400 }
401
402 ////////////////////////////////////////////////////////////////////////////
403
404 SkPDFDict fontDict("Font");
405 fontDict.insertName("Subtype", "Type0");
406 fontDict.insertName("BaseFont", metrics.fPostScriptName);
407 fontDict.insertName("Encoding", "Identity-H");
408 auto descendantFonts = SkPDFMakeArray();
409 descendantFonts->appendRef(doc->emit(*newCIDFont));
410 fontDict.insertObject("DescendantFonts", std::move(descendantFonts));
411
412 const std::vector<SkUnichar>& glyphToUnicode =
413 SkPDFFont::GetUnicodeMap(font.typeface(), doc);
414 SkASSERT(SkToSizeT(font.typeface()->countGlyphs()) == glyphToUnicode.size());
415 std::unique_ptr<SkStreamAsset> toUnicode =
416 SkPDFMakeToUnicodeCmap(glyphToUnicode.data(),
417 &font.glyphUsage(),
418 font.multiByteGlyphs(),
419 font.firstGlyphID(),
420 font.lastGlyphID());
421 fontDict.insertRef("ToUnicode", SkPDFStreamOut(nullptr, std::move(toUnicode), doc));
422
423 doc->emit(fontDict, font.indirectReference());
424}
#define SkASSERT(cond)
Definition SkAssert.h:116
void SK_SPI SkDebugf(const char format[],...) SK_PRINTF_LIKE(1
static bool can_embed(const SkAdvancedTypefaceMetrics &metrics)
static sk_sp< SkData > stream_to_data(std::unique_ptr< SkStreamAsset > stream)
std::unique_ptr< SkPDFArray > SkPDFMakeCIDGlyphWidthsArray(const SkTypeface &typeface, const SkPDFGlyphUse &subset, int32_t *defaultAdvance)
std::unique_ptr< SkStreamAsset > SkPDFMakeToUnicodeCmap(const SkUnichar *glyphToUnicode, const SkPDFGlyphUse *subset, bool multiByteGlyphs, SkGlyphID firstGlyphID, SkGlyphID lastGlyphID)
sk_sp< SkData > SkPDFSubsetFont(sk_sp< SkData >, const SkPDFGlyphUse &, SkPDF::Metadata::Subsetter, int)
SkPDFIndirectReference SkPDFStreamOut(std::unique_ptr< SkPDFDict > dict, std::unique_ptr< SkStreamAsset > content, SkPDFDocument *doc, SkPDFSteamCompressionEnabled compress)
static std::unique_ptr< SkPDFDict > SkPDFMakeDict(const char *type=nullptr)
Definition SkPDFTypes.h:195
static std::unique_ptr< SkPDFArray > SkPDFMakeArray(Args... args)
Definition SkPDFTypes.h:135
constexpr size_t SkToSizeT(S x)
Definition SkTo.h:31
constexpr uint16_t SkToU16(S x)
Definition SkTo.h:24
constexpr int SkToInt(S x)
Definition SkTo.h:29
const SkScalar widths[]
static std::unique_ptr< SkMemoryStream > Make(sk_sp< SkData > data)
Definition SkStream.cpp:314
SkPDFIndirectReference emit(const SkPDFObject &, SkPDFIndirectReference)
const SkPDF::Metadata & metadata() const
static const SkAdvancedTypefaceMetrics * GetMetrics(const SkTypeface *typeface, SkPDFDocument *canon)
static void PopulateCommonFontDescriptor(SkPDFDict *descriptor, const SkAdvancedTypefaceMetrics &, uint16_t emSize, int16_t defaultWidth)
static const std::vector< SkUnichar > & GetUnicodeMap(const SkTypeface *typeface, SkPDFDocument *canon)
std::unique_ptr< SkStreamAsset > openStream(int *ttcIndex) const
font
Font Metadata and Metrics.
@ kNotSubsettable_FontFlag
May not be subset.
enum SkPDF::Metadata::Subsetter fSubsetter

◆ emit_subset_type3()

static void emit_subset_type3 ( const SkPDFFont pdfFont,
SkPDFDocument doc 
)
static

Definition at line 578 of file SkPDFFont.cpp.

578 {
579 SkTypeface* typeface = pdfFont.typeface();
580 SkGlyphID firstGlyphID = pdfFont.firstGlyphID();
581 SkGlyphID lastGlyphID = pdfFont.lastGlyphID();
582 const SkPDFGlyphUse& subset = pdfFont.glyphUsage();
583 SkASSERT(lastGlyphID >= firstGlyphID);
584 // Remove unused glyphs at the end of the range.
585 // Keep the lastGlyphID >= firstGlyphID invariant true.
586 while (lastGlyphID > firstGlyphID && !subset.has(lastGlyphID)) {
587 --lastGlyphID;
588 }
589 int unitsPerEm;
590 SkStrikeSpec strikeSpec = SkStrikeSpec::MakePDFVector(*typeface, &unitsPerEm);
591 auto strike = strikeSpec.findOrCreateStrike();
592 SkASSERT(strike);
593 SkScalar emSize = (SkScalar)unitsPerEm;
594 SkScalar xHeight = strike->getFontMetrics().fXHeight;
595 SkBulkGlyphMetricsAndPaths metricsAndPaths((sk_sp<SkStrike>(strike)));
596 SkBulkGlyphMetricsAndDrawables metricsAndDrawables(std::move(strike));
597
598 SkStrikeSpec strikeSpecSmall = kBitmapFontSize > 0 ? make_small_strike(*typeface)
599 : strikeSpec;
600
601 SkBulkGlyphMetricsAndImages smallGlyphs(strikeSpecSmall);
602 float bitmapScale = kBitmapFontSize > 0 ? emSize / kBitmapFontSize : 1.0f;
603
604 SkPDFDict font("Font");
605 font.insertName("Subtype", "Type3");
606 // Flip about the x-axis and scale by 1/emSize.
607 SkMatrix fontMatrix;
608 fontMatrix.setScale(SkScalarInvert(emSize), -SkScalarInvert(emSize));
609 font.insertObject("FontMatrix", SkPDFUtils::MatrixToArray(fontMatrix));
610
611 auto charProcs = SkPDFMakeDict();
612 auto encoding = SkPDFMakeDict("Encoding");
613
614 auto encDiffs = SkPDFMakeArray();
615 // length(firstGlyphID .. lastGlyphID) == lastGlyphID - firstGlyphID + 1
616 // plus 1 for glyph 0;
617 SkASSERT(firstGlyphID > 0);
618 SkASSERT(lastGlyphID >= firstGlyphID);
619 int glyphCount = lastGlyphID - firstGlyphID + 2;
620 // one other entry for the index of first glyph.
621 encDiffs->reserve(glyphCount + 1);
622 encDiffs->appendInt(0); // index of first glyph
623
624 auto widthArray = SkPDFMakeArray();
625 widthArray->reserve(glyphCount);
626
628
629 std::vector<std::pair<SkGlyphID, SkPDFIndirectReference>> imageGlyphs;
630 for (SkGlyphID gID : SingleByteGlyphIdIterator(firstGlyphID, lastGlyphID)) {
631 bool skipGlyph = gID != 0 && !subset.has(gID);
632 SkString characterName;
633 SkScalar advance = 0.0f;
634 SkIRect glyphBBox;
635 if (skipGlyph) {
636 characterName.set("g0");
637 } else {
638 characterName.printf("g%X", gID);
639 const SkGlyph* pathGlyph = metricsAndPaths.glyph(gID);
640 const SkGlyph* drawableGlyph = metricsAndDrawables.glyph(gID);
641 advance = pathGlyph->advanceX();
642 glyphBBox = pathGlyph->iRect();
643 bbox.join(glyphBBox);
644 const SkPath* path = pathGlyph->path();
645 SkDrawable* drawable = drawableGlyph->drawable();
647 if (drawable && !drawable->getBounds().isEmpty()) {
648 sk_sp<SkPDFDevice> glyphDevice = sk_make_sp<SkPDFDevice>(glyphBBox.size(), doc);
649 SkCanvas canvas(glyphDevice);
650 canvas.translate(-glyphBBox.fLeft, -glyphBBox.fTop);
651 canvas.drawDrawable(drawable);
653 doc, glyphDevice->content(),
654 SkPDFMakeArray(0, 0, glyphBBox.width(), glyphBBox.height()),
655 glyphDevice->makeResourceDict(),
656 SkMatrix::Translate(glyphBBox.fLeft, glyphBBox.fTop), nullptr);
657 imageGlyphs.emplace_back(gID, xobject);
658 SkPDFUtils::AppendScalar(drawableGlyph->advanceX(), &content);
659 content.writeText(" 0 d0\n1 0 0 1 0 0 cm\n/X");
660 content.write(characterName.c_str(), characterName.size());
661 content.writeText(" Do\n");
662 } else if (path && !path->isEmpty()) {
663 setGlyphWidthAndBoundingBox(pathGlyph->advanceX(), glyphBBox, &content);
666 } else {
667 auto pimg = to_image(gID, &smallGlyphs);
668 if (!pimg.fImage) {
669 setGlyphWidthAndBoundingBox(pathGlyph->advanceX(), glyphBBox, &content);
670 } else {
672 imageGlyphs.emplace_back(gID, SkPDFSerializeImage(pimg.fImage.get(), doc));
673 AppendScalar(pathGlyph->advanceX(), &content);
674 content.writeText(" 0 d0\n");
675 AppendScalar(pimg.fImage->width() * bitmapScale, &content);
676 content.writeText(" 0 0 ");
677 AppendScalar(-pimg.fImage->height() * bitmapScale, &content);
678 content.writeText(" ");
679 AppendScalar(pimg.fOffset.x() * bitmapScale, &content);
680 content.writeText(" ");
681 AppendScalar((pimg.fImage->height() + pimg.fOffset.y()) * bitmapScale,
682 &content);
683 content.writeText(" cm\n/X");
684 content.write(characterName.c_str(), characterName.size());
685 content.writeText(" Do\n");
686 }
687 }
688 charProcs->insertRef(characterName, SkPDFStreamOut(nullptr,
689 content.detachAsStream(), doc));
690 }
691 encDiffs->appendName(std::move(characterName));
692 widthArray->appendScalar(advance);
693 }
694
695 if (!imageGlyphs.empty()) {
696 auto d0 = SkPDFMakeDict();
697 for (const auto& pair : imageGlyphs) {
698 d0->insertRef(SkStringPrintf("Xg%X", pair.first), pair.second);
699 }
700 auto d1 = SkPDFMakeDict();
701 d1->insertObject("XObject", std::move(d0));
702 font.insertObject("Resources", std::move(d1));
703 }
704
705 encoding->insertObject("Differences", std::move(encDiffs));
706 font.insertInt("FirstChar", 0);
707 font.insertInt("LastChar", lastGlyphID - firstGlyphID + 1);
708 /* FontBBox: "A rectangle expressed in the glyph coordinate
709 system, specifying the font bounding box. This is the smallest
710 rectangle enclosing the shape that would result if all of the
711 glyphs of the font were placed with their origins coincident and
712 then filled." */
713 font.insertObject("FontBBox", SkPDFMakeArray(bbox.left(),
714 bbox.bottom(),
715 bbox.right(),
716 bbox.top()));
717
718 font.insertName("CIDToGIDMap", "Identity");
719
720 const std::vector<SkUnichar>& glyphToUnicode = SkPDFFont::GetUnicodeMap(typeface, doc);
721 SkASSERT(glyphToUnicode.size() == SkToSizeT(typeface->countGlyphs()));
722 auto toUnicodeCmap = SkPDFMakeToUnicodeCmap(glyphToUnicode.data(),
723 &subset,
724 false,
725 firstGlyphID,
726 lastGlyphID);
727 font.insertRef("ToUnicode", SkPDFStreamOut(nullptr, std::move(toUnicodeCmap), doc));
728 font.insertRef("FontDescriptor", type3_descriptor(doc, typeface, xHeight));
729 font.insertObject("Widths", std::move(widthArray));
730 font.insertObject("Encoding", std::move(encoding));
731 font.insertObject("CharProcs", std::move(charProcs));
732
733 doc->emit(font, pdfFont.indirectReference());
734}
SkPDFIndirectReference SkPDFSerializeImage(const SkImage *img, SkPDFDocument *doc, int encodingQuality)
SkStrikeSpec make_small_strike(const SkTypeface &typeface)
static SkPDFIndirectReference type3_descriptor(SkPDFDocument *doc, const SkTypeface *typeface, SkScalar xHeight)
static ImageAndOffset to_image(SkGlyphID gid, SkBulkGlyphMetricsAndImages *smallGlyphs)
static constexpr float kBitmapFontSize
SkPDFIndirectReference SkPDFMakeFormXObject(SkPDFDocument *doc, std::unique_ptr< SkStreamAsset > content, std::unique_ptr< SkPDFArray > mediaBox, std::unique_ptr< SkPDFDict > resourceDict, const SkMatrix &inverseTransform, const char *colorSpace)
#define SkScalarInvert(x)
Definition SkScalar.h:73
SK_API SkString static SkString SkStringPrintf()
Definition SkString.h:287
uint16_t SkGlyphID
Definition SkTypes.h:179
SkRect getBounds()
const SkPath * path() const
Definition SkGlyph.cpp:284
SkScalar advanceX() const
Definition SkGlyph.h:426
SkIRect iRect() const
Definition SkGlyph.h:505
SkDrawable * drawable() const
Definition SkGlyph.cpp:327
static SkMatrix Translate(SkScalar dx, SkScalar dy)
Definition SkMatrix.h:91
SkMatrix & setScale(SkScalar sx, SkScalar sy, SkScalar px, SkScalar py)
Definition SkMatrix.cpp:296
SkPDFIndirectReference indirectReference() const
Definition SkPDFFont.h:81
SkGlyphID lastGlyphID() const
Definition SkPDFFont.h:119
SkGlyphID firstGlyphID() const
Definition SkPDFFont.h:118
const SkPDFGlyphUse & glyphUsage() const
Definition SkPDFFont.h:120
SkTypeface * typeface() const
Definition SkPDFFont.h:39
bool has(SkGlyphID gid) const
@ kFill_Style
set to fill geometry
Definition SkPaint.h:193
sk_sp< SkStrike > findOrCreateStrike() const
static SkStrikeSpec MakePDFVector(const SkTypeface &typeface, int *size)
void printf(const char format[],...) SK_PRINTF_LIKE(2
Definition SkString.cpp:534
size_t size() const
Definition SkString.h:131
void set(const SkString &src)
Definition SkString.h:186
const char * c_str() const
Definition SkString.h:133
int countGlyphs() const
float SkScalar
Definition extension.cpp:12
union flutter::testing::@2838::KeyboardChange::@76 content
std::unique_ptr< SkPDFArray > MatrixToArray(const SkMatrix &matrix)
void EmitPath(const SkPath &path, SkPaint::Style paintStyle, bool doConsumeDegerates, SkWStream *content, SkScalar tolerance=0.25f)
void PaintPath(SkPaint::Style style, SkPathFillType fill, SkWStream *content)
void AppendScalar(SkScalar value, SkWStream *stream)
Definition SkPDFUtils.h:86
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
Definition switches.h:57
constexpr int32_t top() const
Definition SkRect.h:120
constexpr SkISize size() const
Definition SkRect.h:172
constexpr int32_t bottom() const
Definition SkRect.h:134
constexpr int32_t height() const
Definition SkRect.h:165
constexpr int32_t right() const
Definition SkRect.h:127
int32_t fTop
smaller y-axis bounds
Definition SkRect.h:34
void join(const SkIRect &r)
Definition SkRect.cpp:31
static constexpr SkIRect MakeEmpty()
Definition SkRect.h:45
constexpr int32_t width() const
Definition SkRect.h:158
int32_t fLeft
smaller x-axis bounds
Definition SkRect.h:33
constexpr int32_t left() const
Definition SkRect.h:113
bool isEmpty() const
Definition SkRect.h:693

◆ first_nonzero_glyph_for_single_byte_encoding()

static SkGlyphID first_nonzero_glyph_for_single_byte_encoding ( SkGlyphID  gid)
static

Definition at line 194 of file SkPDFFont.cpp.

194 {
195 return gid != 0 ? gid - (gid - 1) % 255 : 1;
196}

◆ make_small_strike()

SkStrikeSpec make_small_strike ( const SkTypeface typeface)

Definition at line 567 of file SkPDFFont.cpp.

567 {
569 font.setHinting(SkFontHinting::kNone);
570 font.setEdging(SkFont::Edging::kAlias);
571 return SkStrikeSpec::MakeMask(font,
572 SkPaint(),
575 SkMatrix::I());
576}
@ kNone
glyph outlines unchanged
sk_sp< T > sk_ref_sp(T *obj)
Definition SkRefCnt.h:381
@ kAlias
no transparent pixels on glyph edges
static const SkMatrix & I()
static SkStrikeSpec MakeMask(const SkFont &font, const SkPaint &paint, const SkSurfaceProps &surfaceProps, SkScalerContextFlags scalerContextFlags, const SkMatrix &deviceMatrix)

◆ stream_to_data()

static sk_sp< SkData > stream_to_data ( std::unique_ptr< SkStreamAsset stream)
static

Definition at line 286 of file SkPDFFont.cpp.

286 {
287 SkASSERT(stream);
288 (void)stream->rewind();
289 SkASSERT(stream->hasLength());
290 size_t size = stream->getLength();
291 if (const void* base = stream->getMemoryBase()) {
293 [](const void*, void* ctx) { delete (SkStreamAsset*)ctx; };
294 return SkData::MakeWithProc(base, size, proc, stream.release());
295 }
296 return SkData::MakeFromStream(stream.get(), size);
297}
void(* ReleaseProc)(const void *ptr, void *context)
Definition SkData.h:78
static sk_sp< SkData > MakeWithProc(const void *ptr, size_t length, ReleaseProc proc, void *ctx)
Definition SkData.cpp:128
static sk_sp< SkData > MakeFromStream(SkStream *, size_t size)
Definition SkData.cpp:208
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

◆ to_image()

static ImageAndOffset to_image ( SkGlyphID  gid,
SkBulkGlyphMetricsAndImages smallGlyphs 
)
static

Definition at line 464 of file SkPDFFont.cpp.

464 {
465 const SkGlyph* glyph = smallGlyphs->glyph(SkPackedGlyphID{gid});
466 SkMask mask = glyph->mask();
467 if (!mask.fImage) {
468 return {nullptr, {0, 0}};
469 }
470 SkIRect bounds = mask.fBounds;
471 SkBitmap bm;
472 switch (mask.fFormat) {
474 bm.allocPixels(SkImageInfo::MakeA8(bounds.width(), bounds.height()));
475 for (int y = 0; y < bm.height(); ++y) {
476 for (int x8 = 0; x8 < bm.width(); x8 += 8) {
477 uint8_t v = *mask.getAddr1(x8 + bounds.x(), y + bounds.y());
478 int e = std::min(x8 + 8, bm.width());
479 for (int x = x8; x < e; ++x) {
480 *bm.getAddr8(x, y) = (v >> (x & 0x7)) & 0x1 ? 0xFF : 0x00;
481 }
482 }
483 }
484 bm.setImmutable();
485 return {bm.asImage(), {bounds.x(), bounds.y()}};
488 SkImageInfo::MakeA8(bounds.width(), bounds.height()),
490 mask.fRowBytes),
491 {bounds.x(), bounds.y()}};
494 SkImageInfo::MakeN32Premul(bounds.width(), bounds.height()),
496 mask.fRowBytes),
497 {bounds.x(), bounds.y()}};
500 default:
501 SkASSERT(false);
502 return {nullptr, {0, 0}};
503 }
504}
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
uint8_t * getAddr8(int x, int y) const
Definition SkBitmap.h:1270
int width() const
Definition SkBitmap.h:149
int height() const
Definition SkBitmap.h:158
const SkGlyph * glyph(SkPackedGlyphID packedID)
static sk_sp< SkData > MakeWithCopy(const void *data, size_t length)
Definition SkData.cpp:111
SkMask mask() const
Definition SkGlyph.cpp:125
double y
double x
SK_API sk_sp< SkImage > RasterFromData(const SkImageInfo &info, sk_sp< SkData > pixels, size_t rowBytes)
Optional< SkRect > bounds
Definition SkRecords.h:189
static SkImageInfo MakeN32Premul(int width, int height)
static SkImageInfo MakeA8(int width, int height)
const uint32_t fRowBytes
Definition SkMask.h:43
@ k3D_Format
3 8bit per pixl planes: alpha, mul, add
Definition SkMask.h:29
@ kA8_Format
8bits per pixel mask (e.g. antialiasing)
Definition SkMask.h:28
@ kLCD16_Format
565 alpha for r/g/b
Definition SkMask.h:31
@ kARGB32_Format
SkPMColor.
Definition SkMask.h:30
@ kBW_Format
1bit per pixel mask (e.g. monochrome)
Definition SkMask.h:27
const uint8_t * getAddr1(int x, int y) const
Definition SkMask.h:68
uint8_t const *const fImage
Definition SkMask.h:41
const SkIRect fBounds
Definition SkMask.h:42
size_t computeTotalImageSize() const
Definition SkMask.cpp:34
const Format fFormat
Definition SkMask.h:44

◆ type3_descriptor()

static SkPDFIndirectReference type3_descriptor ( SkPDFDocument doc,
const SkTypeface typeface,
SkScalar  xHeight 
)
static

PDF32000_2008: FontFamily should be used for Type3 fonts in Tagged PDF documents.

PDF32000_2008: FontStretch should be used for Type3 fonts in Tagged PDF documents.

PDF32000_2008: FontWeight should be used for Type3 fonts in Tagged PDF documents.

Definition at line 506 of file SkPDFFont.cpp.

508 {
509 if (SkPDFIndirectReference* ptr = doc->fType3FontDescriptors.find(typeface->uniqueID())) {
510 return *ptr;
511 }
512
513 SkPDFDict descriptor("FontDescriptor");
514 int32_t fontDescriptorFlags = kPdfSymbolic;
515
516 /** PDF32000_2008: FontFamily should be used for Type3 fonts in Tagged PDF documents. */
517 SkString familyName;
518 typeface->getFamilyName(&familyName);
519 if (!familyName.isEmpty()) {
520 descriptor.insertByteString("FontFamily", familyName);
521 }
522
523 /** PDF32000_2008: FontStretch should be used for Type3 fonts in Tagged PDF documents. */
524 static constexpr const char* stretchNames[9] = {
525 "UltraCondensed",
526 "ExtraCondensed",
527 "Condensed",
528 "SemiCondensed",
529 "Normal",
530 "SemiExpanded",
531 "Expanded",
532 "ExtraExpanded",
533 "UltraExpanded",
534 };
535 const char* stretchName = stretchNames[typeface->fontStyle().width() - 1];
536 descriptor.insertName("FontStretch", stretchName);
537
538 /** PDF32000_2008: FontWeight should be used for Type3 fonts in Tagged PDF documents. */
539 int weight = (typeface->fontStyle().weight() + 50) / 100;
540 descriptor.insertInt("FontWeight", SkTPin(weight, 1, 9) * 100);
541
542 if (const SkAdvancedTypefaceMetrics* metrics = SkPDFFont::GetMetrics(typeface, doc)) {
543 // Type3 FontDescriptor does not require all the same fields.
544 descriptor.insertName("FontName", metrics->fPostScriptName);
545 descriptor.insertInt("ItalicAngle", metrics->fItalicAngle);
546 fontDescriptorFlags |= (int32_t)metrics->fStyle;
547 // Adobe requests CapHeight, XHeight, and StemV be added
548 // to "greatly help our workflow downstream".
549 if (metrics->fCapHeight != 0) { descriptor.insertInt("CapHeight", metrics->fCapHeight); }
550 if (metrics->fStemV != 0) { descriptor.insertInt("StemV", metrics->fStemV); }
551 if (xHeight != 0) {
552 descriptor.insertScalar("XHeight", xHeight);
553 }
554 }
555 descriptor.insertInt("Flags", fontDescriptorFlags);
556 SkPDFIndirectReference ref = doc->emit(descriptor);
557 doc->fType3FontDescriptors.set(typeface->uniqueID(), ref);
558 return ref;
559}
static constexpr const T & SkTPin(const T &x, const T &lo, const T &hi)
Definition SkTPin.h:19
int width() const
Definition SkFontStyle.h:63
int weight() const
Definition SkFontStyle.h:62
skia_private::THashMap< uint32_t, SkPDFIndirectReference > fType3FontDescriptors
bool isEmpty() const
Definition SkString.h:130
SkTypefaceID uniqueID() const
Definition SkTypeface.h:101
void getFamilyName(SkString *name) const
SkFontStyle fontStyle() const
Definition SkTypeface.h:55
V * find(const K &key) const
Definition SkTHash.h:479
V * set(K key, V val)
Definition SkTHash.h:472

Variable Documentation

◆ kBitmapFontSize

constexpr float kBitmapFontSize = 64
staticconstexpr

Definition at line 564 of file SkPDFFont.cpp.