Flutter Engine
The Flutter Engine
Classes | Functions | Variables
SkPDFFont.cpp File Reference
#include "src/pdf/SkPDFFont.h"
#include "include/core/SkBitmap.h"
#include "include/core/SkCanvas.h"
#include "include/core/SkData.h"
#include "include/core/SkDrawable.h"
#include "include/core/SkFont.h"
#include "include/core/SkFontMetrics.h"
#include "include/core/SkFontStyle.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/private/base/SkDebug.h"
#include "include/private/base/SkTPin.h"
#include "include/private/base/SkTo.h"
#include "src/base/SkBitmaskEnum.h"
#include "src/base/SkUTF.h"
#include "src/core/SkDevice.h"
#include "src/core/SkGlyph.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/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 <algorithm>
#include <cstddef>
#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 bool can_subset (const SkAdvancedTypefaceMetrics &metrics)
 
static SkGlyphID first_nonzero_glyph_for_single_byte_encoding (SkGlyphID gid)
 
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 110 of file SkPDFFont.cpp.

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

◆ can_subset()

static bool can_subset ( const SkAdvancedTypefaceMetrics metrics)
static

Definition at line 114 of file SkPDFFont.cpp.

◆ emit_subset_type0()

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

Definition at line 295 of file SkPDFFont.cpp.

295 {
296 const SkAdvancedTypefaceMetrics* metricsPtr = SkPDFFont::GetMetrics(font.typeface(), doc);
297 SkASSERT(metricsPtr);
298 if (!metricsPtr) {
299 return;
300 }
301 const SkAdvancedTypefaceMetrics& metrics = *metricsPtr;
302 SkASSERT(can_embed(metrics));
304 SkTypeface* face = font.typeface();
305 SkASSERT(face);
306
307 auto descriptor = SkPDFMakeDict("FontDescriptor");
308 uint16_t emSize = SkToU16(font.typeface()->getUnitsPerEm());
309 SkPDFFont::PopulateCommonFontDescriptor(descriptor.get(), metrics, emSize, 0);
310
311 int ttcIndex;
312 std::unique_ptr<SkStreamAsset> fontAsset = face->openStream(&ttcIndex);
313 size_t fontSize = fontAsset ? fontAsset->getLength() : 0;
314 if (0 == fontSize) {
315 SkDebugf("Error: (SkTypeface)(%p)::openStream() returned "
316 "empty stream (%p) when identified as kType1CID_Font "
317 "or kTrueType_Font.\n", face, fontAsset.get());
320 {
321 sk_sp<SkData> subsetFontData;
322 if (can_subset(metrics)) {
323 SkASSERT(font.firstGlyphID() == 1);
324 subsetFontData = SkPDFSubsetFont(*face, font.glyphUsage());
325 }
326 std::unique_ptr<SkStreamAsset> subsetFontAsset;
327 if (subsetFontData) {
328 subsetFontAsset = SkMemoryStream::Make(std::move(subsetFontData));
329 } else {
330 // If subsetting fails, fall back to original font data.
331 subsetFontAsset = std::move(fontAsset);
332 }
333 std::unique_ptr<SkPDFDict> streamDict = SkPDFMakeDict();
334 streamDict->insertInt("Length1", subsetFontAsset->getLength());
335 const char* fontFileKey;
337 fontFileKey = "FontFile2";
338 } else {
339 streamDict->insertName("Subtype", "OpenType");
340 fontFileKey = "FontFile3";
341 }
342 descriptor->insertRef(fontFileKey,
343 SkPDFStreamOut(std::move(streamDict), std::move(subsetFontAsset),
346 std::unique_ptr<SkPDFDict> streamDict = SkPDFMakeDict();
347 streamDict->insertName("Subtype", "CIDFontType0C");
348 descriptor->insertRef("FontFile3",
349 SkPDFStreamOut(std::move(streamDict), std::move(fontAsset),
351 } else {
352 SkASSERT(false);
353 }
354
355 auto newCIDFont = SkPDFMakeDict("Font");
356 newCIDFont->insertRef("FontDescriptor", doc->emit(*descriptor));
357 newCIDFont->insertName("BaseFont", metrics.fPostScriptName);
358
359 switch (type) {
361 newCIDFont->insertName("Subtype", "CIDFontType0");
362 break;
364 newCIDFont->insertName("Subtype", "CIDFontType0");
365 newCIDFont->insertName("CIDToGIDMap", "Identity");
366 break;
368 newCIDFont->insertName("Subtype", "CIDFontType2");
369 newCIDFont->insertName("CIDToGIDMap", "Identity");
370 break;
371 default:
372 SkASSERT(false);
373 }
374 auto sysInfo = SkPDFMakeDict();
375 // These are actually ASCII strings.
376 sysInfo->insertByteString("Registry", "Adobe");
377 sysInfo->insertByteString("Ordering", "Identity");
378 sysInfo->insertInt("Supplement", 0);
379 newCIDFont->insertObject("CIDSystemInfo", std::move(sysInfo));
380
381 // Unfortunately, poppler enforces DW (default width) must be an integer.
382 int32_t defaultWidth = 0;
383 {
384 std::unique_ptr<SkPDFArray> widths = SkPDFMakeCIDGlyphWidthsArray(
385 *face, font.glyphUsage(), &defaultWidth);
386 if (widths && widths->size() > 0) {
387 newCIDFont->insertObject("W", std::move(widths));
388 }
389 newCIDFont->insertInt("DW", defaultWidth);
390 }
391
392 ////////////////////////////////////////////////////////////////////////////
393
394 SkPDFDict fontDict("Font");
395 fontDict.insertName("Subtype", "Type0");
396 fontDict.insertName("BaseFont", metrics.fPostScriptName);
397 fontDict.insertName("Encoding", "Identity-H");
398 auto descendantFonts = SkPDFMakeArray();
399 descendantFonts->appendRef(doc->emit(*newCIDFont));
400 fontDict.insertObject("DescendantFonts", std::move(descendantFonts));
401
402 const std::vector<SkUnichar>& glyphToUnicode =
403 SkPDFFont::GetUnicodeMap(font.typeface(), doc);
404 SkASSERT(SkToSizeT(font.typeface()->countGlyphs()) == glyphToUnicode.size());
405 std::unique_ptr<SkStreamAsset> toUnicode =
406 SkPDFMakeToUnicodeCmap(glyphToUnicode.data(),
407 &font.glyphUsage(),
408 font.multiByteGlyphs(),
409 font.firstGlyphID(),
410 font.lastGlyphID());
411 fontDict.insertRef("ToUnicode", SkPDFStreamOut(nullptr, std::move(toUnicode), doc));
412
413 doc->emit(fontDict, font.indirectReference());
414}
#define SkASSERT(cond)
Definition: SkAssert.h:116
void SK_SPI SkDebugf(const char format[],...) SK_PRINTF_LIKE(1
static bool can_subset(const SkAdvancedTypefaceMetrics &metrics)
Definition: SkPDFFont.cpp:114
static bool can_embed(const SkAdvancedTypefaceMetrics &metrics)
Definition: SkPDFFont.cpp:110
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(const SkTypeface &, const SkPDFGlyphUse &)
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
static std::unique_ptr< SkPDFArray > SkPDFMakeArray(Args... args)
Definition: SkPDFTypes.h:125
constexpr size_t SkToSizeT(S x)
Definition: SkTo.h:31
constexpr uint16_t SkToU16(S x)
Definition: SkTo.h:24
const SkScalar widths[]
Definition: StrokerTest.cpp:39
GLenum type
static std::unique_ptr< SkMemoryStream > Make(sk_sp< SkData > data)
Definition: SkStream.cpp:314
SkPDFIndirectReference emit(const SkPDFObject &, SkPDFIndirectReference)
static const SkAdvancedTypefaceMetrics * GetMetrics(const SkTypeface *typeface, SkPDFDocument *canon)
Definition: SkPDFFont.cpp:118
static void PopulateCommonFontDescriptor(SkPDFDict *descriptor, const SkAdvancedTypefaceMetrics &, uint16_t emSize, int16_t defaultWidth)
Definition: SkPDFFont.cpp:265
static const std::vector< SkUnichar > & GetUnicodeMap(const SkTypeface *typeface, SkPDFDocument *canon)
Definition: SkPDFFont.cpp:170
std::unique_ptr< SkStreamAsset > openStream(int *ttcIndex) const
Definition: SkTypeface.cpp:332
font
Font Metadata and Metrics.

◆ emit_subset_type3()

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

Definition at line 568 of file SkPDFFont.cpp.

568 {
569 SkTypeface* typeface = pdfFont.typeface();
570 SkGlyphID firstGlyphID = pdfFont.firstGlyphID();
571 SkGlyphID lastGlyphID = pdfFont.lastGlyphID();
572 const SkPDFGlyphUse& subset = pdfFont.glyphUsage();
573 SkASSERT(lastGlyphID >= firstGlyphID);
574 // Remove unused glyphs at the end of the range.
575 // Keep the lastGlyphID >= firstGlyphID invariant true.
576 while (lastGlyphID > firstGlyphID && !subset.has(lastGlyphID)) {
577 --lastGlyphID;
578 }
579 int unitsPerEm;
580 SkStrikeSpec strikeSpec = SkStrikeSpec::MakePDFVector(*typeface, &unitsPerEm);
581 auto strike = strikeSpec.findOrCreateStrike();
582 SkASSERT(strike);
583 SkScalar emSize = (SkScalar)unitsPerEm;
584 SkScalar xHeight = strike->getFontMetrics().fXHeight;
585 SkBulkGlyphMetricsAndPaths metricsAndPaths((sk_sp<SkStrike>(strike)));
586 SkBulkGlyphMetricsAndDrawables metricsAndDrawables(std::move(strike));
587
588 SkStrikeSpec strikeSpecSmall = kBitmapFontSize > 0 ? make_small_strike(*typeface)
589 : strikeSpec;
590
591 SkBulkGlyphMetricsAndImages smallGlyphs(strikeSpecSmall);
592 float bitmapScale = kBitmapFontSize > 0 ? emSize / kBitmapFontSize : 1.0f;
593
594 SkPDFDict font("Font");
595 font.insertName("Subtype", "Type3");
596 // Flip about the x-axis and scale by 1/emSize.
597 SkMatrix fontMatrix;
598 fontMatrix.setScale(SkScalarInvert(emSize), -SkScalarInvert(emSize));
599 font.insertObject("FontMatrix", SkPDFUtils::MatrixToArray(fontMatrix));
600
601 auto charProcs = SkPDFMakeDict();
602 auto encoding = SkPDFMakeDict("Encoding");
603
604 auto encDiffs = SkPDFMakeArray();
605 // length(firstGlyphID .. lastGlyphID) == lastGlyphID - firstGlyphID + 1
606 // plus 1 for glyph 0;
607 SkASSERT(firstGlyphID > 0);
608 SkASSERT(lastGlyphID >= firstGlyphID);
609 int glyphCount = lastGlyphID - firstGlyphID + 2;
610 // one other entry for the index of first glyph.
611 encDiffs->reserve(glyphCount + 1);
612 encDiffs->appendInt(0); // index of first glyph
613
614 auto widthArray = SkPDFMakeArray();
615 widthArray->reserve(glyphCount);
616
618
619 std::vector<std::pair<SkGlyphID, SkPDFIndirectReference>> imageGlyphs;
620 for (SkGlyphID gID : SingleByteGlyphIdIterator(firstGlyphID, lastGlyphID)) {
621 bool skipGlyph = gID != 0 && !subset.has(gID);
622 SkString characterName;
623 SkScalar advance = 0.0f;
624 SkIRect glyphBBox;
625 if (skipGlyph) {
626 characterName.set("g0");
627 } else {
628 characterName.printf("g%X", gID);
629 const SkGlyph* pathGlyph = metricsAndPaths.glyph(gID);
630 const SkGlyph* drawableGlyph = metricsAndDrawables.glyph(gID);
631 advance = pathGlyph->advanceX();
632 glyphBBox = pathGlyph->iRect();
633 bbox.join(glyphBBox);
634 const SkPath* path = pathGlyph->path();
635 SkDrawable* drawable = drawableGlyph->drawable();
637 if (drawable && !drawable->getBounds().isEmpty()) {
638 sk_sp<SkPDFDevice> glyphDevice = sk_make_sp<SkPDFDevice>(glyphBBox.size(), doc);
639 SkCanvas canvas(glyphDevice);
640 canvas.translate(-glyphBBox.fLeft, -glyphBBox.fTop);
641 canvas.drawDrawable(drawable);
643 doc, glyphDevice->content(),
644 SkPDFMakeArray(0, 0, glyphBBox.width(), glyphBBox.height()),
645 glyphDevice->makeResourceDict(),
646 SkMatrix::Translate(glyphBBox.fLeft, glyphBBox.fTop), nullptr);
647 imageGlyphs.emplace_back(gID, xobject);
648 SkPDFUtils::AppendScalar(drawableGlyph->advanceX(), &content);
649 content.writeText(" 0 d0\n1 0 0 1 0 0 cm\n/X");
650 content.write(characterName.c_str(), characterName.size());
651 content.writeText(" Do\n");
652 } else if (path && !path->isEmpty()) {
653 setGlyphWidthAndBoundingBox(pathGlyph->advanceX(), glyphBBox, &content);
656 } else {
657 auto pimg = to_image(gID, &smallGlyphs);
658 if (!pimg.fImage) {
659 setGlyphWidthAndBoundingBox(pathGlyph->advanceX(), glyphBBox, &content);
660 } else {
662 imageGlyphs.emplace_back(gID, SkPDFSerializeImage(pimg.fImage.get(), doc));
663 AppendScalar(pathGlyph->advanceX(), &content);
664 content.writeText(" 0 d0\n");
665 AppendScalar(pimg.fImage->width() * bitmapScale, &content);
666 content.writeText(" 0 0 ");
667 AppendScalar(-pimg.fImage->height() * bitmapScale, &content);
668 content.writeText(" ");
669 AppendScalar(pimg.fOffset.x() * bitmapScale, &content);
670 content.writeText(" ");
671 AppendScalar((pimg.fImage->height() + pimg.fOffset.y()) * bitmapScale,
672 &content);
673 content.writeText(" cm\n/X");
674 content.write(characterName.c_str(), characterName.size());
675 content.writeText(" Do\n");
676 }
677 }
678 charProcs->insertRef(characterName, SkPDFStreamOut(nullptr,
679 content.detachAsStream(), doc));
680 }
681 encDiffs->appendName(std::move(characterName));
682 widthArray->appendScalar(advance);
683 }
684
685 if (!imageGlyphs.empty()) {
686 auto d0 = SkPDFMakeDict();
687 for (const auto& pair : imageGlyphs) {
688 d0->insertRef(SkStringPrintf("Xg%X", pair.first), pair.second);
689 }
690 auto d1 = SkPDFMakeDict();
691 d1->insertObject("XObject", std::move(d0));
692 font.insertObject("Resources", std::move(d1));
693 }
694
695 encoding->insertObject("Differences", std::move(encDiffs));
696 font.insertInt("FirstChar", 0);
697 font.insertInt("LastChar", lastGlyphID - firstGlyphID + 1);
698 /* FontBBox: "A rectangle expressed in the glyph coordinate
699 system, specifying the font bounding box. This is the smallest
700 rectangle enclosing the shape that would result if all of the
701 glyphs of the font were placed with their origins coincident and
702 then filled." */
703 font.insertObject("FontBBox", SkPDFMakeArray(bbox.left(),
704 bbox.bottom(),
705 bbox.right(),
706 bbox.top()));
707
708 font.insertName("CIDToGIDMap", "Identity");
709
710 const std::vector<SkUnichar>& glyphToUnicode = SkPDFFont::GetUnicodeMap(typeface, doc);
711 SkASSERT(glyphToUnicode.size() == SkToSizeT(typeface->countGlyphs()));
712 auto toUnicodeCmap = SkPDFMakeToUnicodeCmap(glyphToUnicode.data(),
713 &subset,
714 false,
715 firstGlyphID,
716 lastGlyphID);
717 font.insertRef("ToUnicode", SkPDFStreamOut(nullptr, std::move(toUnicodeCmap), doc));
718 font.insertRef("FontDescriptor", type3_descriptor(doc, typeface, xHeight));
719 font.insertObject("Widths", std::move(widthArray));
720 font.insertObject("Encoding", std::move(encoding));
721 font.insertObject("CharProcs", std::move(charProcs));
722
723 doc->emit(font, pdfFont.indirectReference());
724}
SkPDFIndirectReference SkPDFSerializeImage(const SkImage *img, SkPDFDocument *doc, int encodingQuality)
SkStrikeSpec make_small_strike(const SkTypeface &typeface)
Definition: SkPDFFont.cpp:557
static SkPDFIndirectReference type3_descriptor(SkPDFDocument *doc, const SkTypeface *typeface, SkScalar xHeight)
Definition: SkPDFFont.cpp:496
static ImageAndOffset to_image(SkGlyphID gid, SkBulkGlyphMetricsAndImages *smallGlyphs)
Definition: SkPDFFont.cpp:454
static constexpr float kBitmapFontSize
Definition: SkPDFFont.cpp:554
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 SkStringPrintf(const char *format,...) SK_PRINTF_LIKE(1
Creates a new string and writes into it using a printf()-style format.
uint16_t SkGlyphID
Definition: SkTypes.h:179
SkRect getBounds()
Definition: SkDrawable.cpp:71
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
std::unique_ptr< SkStreamAsset > content()
std::unique_ptr< SkPDFDict > makeResourceDict()
SkPDFIndirectReference indirectReference() const
Definition: SkPDFFont.h:83
SkGlyphID lastGlyphID() const
Definition: SkPDFFont.h:121
SkGlyphID firstGlyphID() const
Definition: SkPDFFont.h:120
const SkPDFGlyphUse & glyphUsage() const
Definition: SkPDFFont.h:122
SkTypeface * typeface() const
Definition: SkPDFFont.h:41
bool has(SkGlyphID gid) const
Definition: SkPDFGlyphUse.h:23
@ kFill_Style
set to fill geometry
Definition: SkPaint.h:193
Definition: SkPath.h:59
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
Definition: SkTypeface.cpp:432
float SkScalar
Definition: extension.cpp:12
union flutter::testing::@2836::KeyboardChange::@76 content
std::unique_ptr< SkPDFArray > MatrixToArray(const SkMatrix &matrix)
Definition: SkPDFUtils.cpp:67
void EmitPath(const SkPath &path, SkPaint::Style paintStyle, bool doConsumeDegerates, SkWStream *content, SkScalar tolerance=0.25f)
Definition: SkPDFUtils.cpp:132
void PaintPath(SkPaint::Style style, SkPathFillType fill, SkWStream *content)
Definition: SkPDFUtils.cpp:231
void AppendScalar(SkScalar value, SkWStream *stream)
Definition: SkPDFUtils.h:98
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
Definition: SkRect.h:32
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 204 of file SkPDFFont.cpp.

204 {
205 return gid != 0 ? gid - (gid - 1) % 255 : 1;
206}

◆ make_small_strike()

SkStrikeSpec make_small_strike ( const SkTypeface typeface)

Definition at line 557 of file SkPDFFont.cpp.

557 {
559 font.setHinting(SkFontHinting::kNone);
560 font.setEdging(SkFont::Edging::kAlias);
562 SkPaint(),
565 SkMatrix::I());
566}
@ kNone
glyph outlines unchanged
sk_sp< T > sk_ref_sp(T *obj)
Definition: SkRefCnt.h:381
Definition: SkFont.h:35
@ kAlias
no transparent pixels on glyph edges
static const SkMatrix & I()
Definition: SkMatrix.cpp:1544
static SkStrikeSpec MakeMask(const SkFont &font, const SkPaint &paint, const SkSurfaceProps &surfaceProps, SkScalerContextFlags scalerContextFlags, const SkMatrix &deviceMatrix)

◆ to_image()

static ImageAndOffset to_image ( SkGlyphID  gid,
SkBulkGlyphMetricsAndImages smallGlyphs 
)
static

Definition at line 454 of file SkPDFFont.cpp.

454 {
455 const SkGlyph* glyph = smallGlyphs->glyph(SkPackedGlyphID{gid});
456 SkMask mask = glyph->mask();
457 if (!mask.fImage) {
458 return {nullptr, {0, 0}};
459 }
460 SkIRect bounds = mask.fBounds;
461 SkBitmap bm;
462 switch (mask.fFormat) {
464 bm.allocPixels(SkImageInfo::MakeA8(bounds.width(), bounds.height()));
465 for (int y = 0; y < bm.height(); ++y) {
466 for (int x8 = 0; x8 < bm.width(); x8 += 8) {
467 uint8_t v = *mask.getAddr1(x8 + bounds.x(), y + bounds.y());
468 int e = std::min(x8 + 8, bm.width());
469 for (int x = x8; x < e; ++x) {
470 *bm.getAddr8(x, y) = (v >> (x & 0x7)) & 0x1 ? 0xFF : 0x00;
471 }
472 }
473 }
474 bm.setImmutable();
475 return {bm.asImage(), {bounds.x(), bounds.y()}};
478 SkImageInfo::MakeA8(bounds.width(), bounds.height()),
480 mask.fRowBytes),
481 {bounds.x(), bounds.y()}};
484 SkImageInfo::MakeN32Premul(bounds.width(), bounds.height()),
486 mask.fRowBytes),
487 {bounds.x(), bounds.y()}};
490 default:
491 SkASSERT(false);
492 return {nullptr, {0, 0}};
493 }
494}
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
static float min(float r, float g, float b)
Definition: hsl.cpp:48
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)
Definition: SkMask.h:25
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 496 of file SkPDFFont.cpp.

498 {
499 if (SkPDFIndirectReference* ptr = doc->fType3FontDescriptors.find(typeface->uniqueID())) {
500 return *ptr;
501 }
502
503 SkPDFDict descriptor("FontDescriptor");
504 int32_t fontDescriptorFlags = kPdfSymbolic;
505
506 /** PDF32000_2008: FontFamily should be used for Type3 fonts in Tagged PDF documents. */
507 SkString familyName;
508 typeface->getFamilyName(&familyName);
509 if (!familyName.isEmpty()) {
510 descriptor.insertByteString("FontFamily", familyName);
511 }
512
513 /** PDF32000_2008: FontStretch should be used for Type3 fonts in Tagged PDF documents. */
514 static constexpr const char* stretchNames[9] = {
515 "UltraCondensed",
516 "ExtraCondensed",
517 "Condensed",
518 "SemiCondensed",
519 "Normal",
520 "SemiExpanded",
521 "Expanded",
522 "ExtraExpanded",
523 "UltraExpanded",
524 };
525 const char* stretchName = stretchNames[typeface->fontStyle().width() - 1];
526 descriptor.insertName("FontStretch", stretchName);
527
528 /** PDF32000_2008: FontWeight should be used for Type3 fonts in Tagged PDF documents. */
529 int weight = (typeface->fontStyle().weight() + 50) / 100;
530 descriptor.insertInt("FontWeight", SkTPin(weight, 1, 9) * 100);
531
532 if (const SkAdvancedTypefaceMetrics* metrics = SkPDFFont::GetMetrics(typeface, doc)) {
533 // Type3 FontDescriptor does not require all the same fields.
534 descriptor.insertName("FontName", metrics->fPostScriptName);
535 descriptor.insertInt("ItalicAngle", metrics->fItalicAngle);
536 fontDescriptorFlags |= (int32_t)metrics->fStyle;
537 // Adobe requests CapHeight, XHeight, and StemV be added
538 // to "greatly help our workflow downstream".
539 if (metrics->fCapHeight != 0) { descriptor.insertInt("CapHeight", metrics->fCapHeight); }
540 if (metrics->fStemV != 0) { descriptor.insertInt("StemV", metrics->fStemV); }
541 if (xHeight != 0) {
542 descriptor.insertScalar("XHeight", xHeight);
543 }
544 }
545 descriptor.insertInt("Flags", fontDescriptorFlags);
546 SkPDFIndirectReference ref = doc->emit(descriptor);
547 doc->fType3FontDescriptors.set(typeface->uniqueID(), ref);
548 return ref;
549}
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
Definition: SkTypeface.cpp:459
SkFontStyle fontStyle() const
Definition: SkTypeface.h:55
V * find(const K &key) const
Definition: SkTHash.h:494
V * set(K key, V val)
Definition: SkTHash.h:487
if(end==-1)

Variable Documentation

◆ kBitmapFontSize

constexpr float kBitmapFontSize = 64
staticconstexpr

Definition at line 554 of file SkPDFFont.cpp.