Flutter Engine
The Flutter Engine
Loading...
Searching...
No Matches
Public Member Functions | Static Public Member Functions | List of all members
SkPDFFont Class Reference

#include <SkPDFFont.h>

Public Member Functions

 ~SkPDFFont ()
 
 SkPDFFont (SkPDFFont &&)
 
SkPDFFontoperator= (SkPDFFont &&)
 
SkTypefacetypeface () const
 
SkAdvancedTypefaceMetrics::FontType getType () const
 
bool multiByteGlyphs () const
 
bool hasGlyph (SkGlyphID gid)
 
SkGlyphID glyphToPDFFontEncoding (SkGlyphID gid) const
 
void noteGlyphUsage (SkGlyphID glyph)
 
SkPDFIndirectReference indirectReference () const
 
void emitSubset (SkPDFDocument *) const
 
SkGlyphID firstGlyphID () const
 
SkGlyphID lastGlyphID () const
 
const SkPDFGlyphUseglyphUsage () const
 
sk_sp< SkTypefacerefTypeface () const
 

Static Public Member Functions

static SkAdvancedTypefaceMetrics::FontType FontType (const SkTypeface &, const SkAdvancedTypefaceMetrics &)
 
static void GetType1GlyphNames (const SkTypeface &, SkString *)
 
static bool IsMultiByte (SkAdvancedTypefaceMetrics::FontType type)
 
static SkPDFFontGetFontResource (SkPDFDocument *doc, const SkGlyph *glyphs, SkTypeface *typeface)
 
static const SkAdvancedTypefaceMetricsGetMetrics (const SkTypeface *typeface, SkPDFDocument *canon)
 
static const std::vector< SkUnichar > & GetUnicodeMap (const SkTypeface *typeface, SkPDFDocument *canon)
 
static void PopulateCommonFontDescriptor (SkPDFDict *descriptor, const SkAdvancedTypefaceMetrics &, uint16_t emSize, int16_t defaultWidth)
 
static bool CanEmbedTypeface (SkTypeface *, SkPDFDocument *)
 

Detailed Description

A PDF Object class representing a font. The font may have resources attached to it in order to embed the font. SkPDFFonts are canonicalized so that resource deduplication will only include one copy of a font. This class uses the same pattern as SkPDFGraphicState, a static weak reference to each instantiated class.

Definition at line 30 of file SkPDFFont.h.

Constructor & Destructor Documentation

◆ ~SkPDFFont()

SkPDFFont::~SkPDFFont ( )
default

◆ SkPDFFont()

SkPDFFont::SkPDFFont ( SkPDFFont &&  )
default

Member Function Documentation

◆ CanEmbedTypeface()

bool SkPDFFont::CanEmbedTypeface ( SkTypeface typeface,
SkPDFDocument doc 
)
static

Return false iff the typeface has its NotEmbeddable flag set. typeface is not nullptr

Definition at line 753 of file SkPDFFont.cpp.

753 {
755 return metrics && can_embed(*metrics);
756}
static bool can_embed(const SkAdvancedTypefaceMetrics &metrics)
static const SkAdvancedTypefaceMetrics * GetMetrics(const SkTypeface *typeface, SkPDFDocument *canon)
SkTypeface * typeface() const
Definition SkPDFFont.h:39

◆ emitSubset()

void SkPDFFont::emitSubset ( SkPDFDocument doc) const

Definition at line 736 of file SkPDFFont.cpp.

736 {
737 switch (fFontType) {
741 return emit_subset_type0(*this, doc);
742#ifndef SK_PDF_DO_NOT_SUPPORT_TYPE_1_FONTS
744 return SkPDFEmitType1Font(*this, doc);
745#endif
746 default:
747 return emit_subset_type3(*this, doc);
748 }
749}
static void emit_subset_type3(const SkPDFFont &pdfFont, SkPDFDocument *doc)
static void emit_subset_type0(const SkPDFFont &font, SkPDFDocument *doc)
void SkPDFEmitType1Font(const SkPDFFont &pdfFont, SkPDFDocument *doc)

◆ firstGlyphID()

SkGlyphID SkPDFFont::firstGlyphID ( ) const
inline

Definition at line 118 of file SkPDFFont.h.

118{ return fGlyphUsage.firstNonZero(); }
SkGlyphID firstNonZero() const

◆ FontType()

SkAdvancedTypefaceMetrics::FontType SkPDFFont::FontType ( const SkTypeface typeface,
const SkAdvancedTypefaceMetrics metrics 
)
static

Definition at line 173 of file SkPDFFont.cpp.

174 {
176 // PDF is actually interested in the encoding of the data, not just the logical format.
177 // If the TrueType is actually wOFF or wOF2 then it should not be directly embedded in PDF.
178 // For now export these as Type3 until the subsetter can handle table based fonts.
179 // See https://github.com/harfbuzz/harfbuzz/issues/3609 and
180 // https://skia-review.googlesource.com/c/skia/+/543485
183 // force Type3 fallback.
185 }
186 if (typeface.getTableSize(kCOLRTableTag)) {
187 // https://bugs.chromium.org/p/skia/issues/detail?id=12650
188 // Don't embed COLRv0 / COLRv1 fonts, fall back to bitmaps.
190 }
191 return metrics.fType;
192}
static constexpr bool SkToBool(const T &x)
Definition SkTo.h:35
size_t getTableSize(SkFontTableTag) const
@ kNotEmbeddable_FontFlag
May not be embedded.
@ kAltDataFormat_FontFlag
Data compressed. Table access may still work.
@ kVariable_FontFlag
May be true for Type1, CFF, or TrueType fonts.

◆ GetFontResource()

SkPDFFont * SkPDFFont::GetFontResource ( SkPDFDocument doc,
const SkGlyph glyphs,
SkTypeface typeface 
)
static

Get the font resource for the passed typeface and glyphID. The reference count of the object is incremented and it is the caller's responsibility to unreference it when done. This is needed to accommodate the weak reference pattern used when the returned object is new and has no other references.

Parameters
typefaceThe typeface to find, not nullptr.
glyphIDSpecify which section of a large font is of interest.

Definition at line 198 of file SkPDFFont.cpp.

200 {
201 SkASSERT(doc);
202 SkASSERT(face); // All SkPDFDevice::internalDrawText ensures this.
203 const SkAdvancedTypefaceMetrics* fontMetrics = SkPDFFont::GetMetrics(face, doc);
204 SkASSERT(fontMetrics); // SkPDFDevice::internalDrawText ensures the typeface is good.
205 // GetMetrics only returns null to signify a bad typeface.
206 const SkAdvancedTypefaceMetrics& metrics = *fontMetrics;
208 if (!(glyph->isEmpty() || glyph->path())) {
210 }
211 bool multibyte = SkPDFFont::IsMultiByte(type);
212 SkGlyphID subsetCode =
213 multibyte ? 0 : first_nonzero_glyph_for_single_byte_encoding(glyph->getGlyphID());
214 uint64_t typefaceID = (static_cast<uint64_t>(face->uniqueID()) << 16) | subsetCode;
215
216 if (SkPDFFont* found = doc->fFontMap.find(typefaceID)) {
217 SkASSERT(multibyte == found->multiByteGlyphs());
218 return found;
219 }
220
223
224 SkGlyphID lastGlyph = SkToU16(typeface->countGlyphs() - 1);
225
226 // should be caught by SkPDFDevice::internalDrawText
227 SkASSERT(glyph->getGlyphID() <= lastGlyph);
228
229 SkGlyphID firstNonZeroGlyph;
230 if (multibyte) {
231 firstNonZeroGlyph = 1;
232 } else {
233 firstNonZeroGlyph = subsetCode;
234 lastGlyph = SkToU16(std::min<int>((int)lastGlyph, 254 + (int)subsetCode));
235 }
236 auto ref = doc->reserveRef();
237 return doc->fFontMap.set(
238 typefaceID, SkPDFFont(std::move(typeface), firstNonZeroGlyph, lastGlyph, type, ref));
239}
#define SkASSERT(cond)
Definition SkAssert.h:116
static SkGlyphID first_nonzero_glyph_for_single_byte_encoding(SkGlyphID gid)
sk_sp< T > sk_ref_sp(T *obj)
Definition SkRefCnt.h:381
constexpr uint16_t SkToU16(S x)
Definition SkTo.h:24
uint16_t SkGlyphID
Definition SkTypes.h:179
skia_private::THashMap< uint64_t, SkPDFFont > fFontMap
SkPDFIndirectReference reserveRef()
static SkAdvancedTypefaceMetrics::FontType FontType(const SkTypeface &, const SkAdvancedTypefaceMetrics &)
static bool IsMultiByte(SkAdvancedTypefaceMetrics::FontType type)
Definition SkPDFFont.h:50
int countGlyphs() const
V * find(const K &key) const
Definition SkTHash.h:479
V * set(K key, V val)
Definition SkTHash.h:472

◆ GetMetrics()

const SkAdvancedTypefaceMetrics * SkPDFFont::GetMetrics ( const SkTypeface typeface,
SkPDFDocument canon 
)
static

Gets SkAdvancedTypefaceMetrics, and caches the result.

Parameters
typefacecan not be nullptr.
Returns
nullptr only when typeface is bad.

Definition at line 108 of file SkPDFFont.cpp.

109 {
112 if (std::unique_ptr<SkAdvancedTypefaceMetrics>* ptr = canon->fTypefaceMetrics.find(id)) {
113 return ptr->get(); // canon retains ownership.
114 }
115 int count = typeface->countGlyphs();
116 if (count <= 0 || count > 1 + SkTo<int>(UINT16_MAX)) {
117 // Cache nullptr to skip this check. Use SkSafeUnref().
118 canon->fTypefaceMetrics.set(id, nullptr);
119 return nullptr;
120 }
121 std::unique_ptr<SkAdvancedTypefaceMetrics> metrics = typeface->getAdvancedMetrics();
122 if (!metrics) {
123 metrics = std::make_unique<SkAdvancedTypefaceMetrics>();
124 }
125
126 if (0 == metrics->fStemV || 0 == metrics->fCapHeight) {
127 SkFont font;
128 font.setHinting(SkFontHinting::kNone);
129 font.setTypeface(sk_ref_sp(typeface));
130 font.setSize(1000); // glyph coordinate system
131 if (0 == metrics->fStemV) {
132 // Figure out a good guess for StemV - Min width of i, I, !, 1.
133 // This probably isn't very good with an italic font.
134 int16_t stemV = SHRT_MAX;
135 for (char c : {'i', 'I', '!', '1'}) {
136 uint16_t g = font.unicharToGlyph(c);
138 font.getBounds(&g, 1, &bounds, nullptr);
139 stemV = std::min(stemV, SkToS16(SkScalarRoundToInt(bounds.width())));
140 }
141 metrics->fStemV = stemV;
142 }
143 if (0 == metrics->fCapHeight) {
144 // Figure out a good guess for CapHeight: average the height of M and X.
145 SkScalar capHeight = 0;
146 for (char c : {'M', 'X'}) {
147 uint16_t g = font.unicharToGlyph(c);
149 font.getBounds(&g, 1, &bounds, nullptr);
150 capHeight += bounds.height();
151 }
152 metrics->fCapHeight = SkToS16(SkScalarRoundToInt(capHeight / 2));
153 }
154 }
155 // Fonts are always subset, so always prepend the subset tag.
156 metrics->fPostScriptName.prepend(canon->nextFontSubsetTag());
157 return canon->fTypefaceMetrics.set(id, std::move(metrics))->get();
158}
int count
@ kNone
glyph outlines unchanged
#define SkScalarRoundToInt(x)
Definition SkScalar.h:37
constexpr int16_t SkToS16(S x)
Definition SkTo.h:23
uint32_t SkTypefaceID
Definition SkTypeface.h:38
SkString nextFontSubsetTag()
skia_private::THashMap< uint32_t, std::unique_ptr< SkAdvancedTypefaceMetrics > > fTypefaceMetrics
SkTypefaceID uniqueID() const
Definition SkTypeface.h:101
float SkScalar
Definition extension.cpp:12
Optional< SkRect > bounds
Definition SkRecords.h:189
font
Font Metadata and Metrics.

◆ getType()

SkAdvancedTypefaceMetrics::FontType SkPDFFont::getType ( ) const
inline

Returns the font type represented in this font. For Type0 fonts, returns the type of the descendant font.

Definition at line 44 of file SkPDFFont.h.

44{ return fFontType; }

◆ GetType1GlyphNames()

void SkPDFFont::GetType1GlyphNames ( const SkTypeface face,
SkString dst 
)
static

Definition at line 53 of file SkPDFFont.cpp.

53 {
55}
virtual void getPostScriptGlyphNames(SkString *) const =0

◆ GetUnicodeMap()

const std::vector< SkUnichar > & SkPDFFont::GetUnicodeMap ( const SkTypeface typeface,
SkPDFDocument canon 
)
static

Definition at line 160 of file SkPDFFont.cpp.

161 {
163 SkASSERT(canon);
165 if (std::vector<SkUnichar>* ptr = canon->fToUnicodeMap.find(id)) {
166 return *ptr;
167 }
168 std::vector<SkUnichar> buffer(typeface->countGlyphs());
170 return *canon->fToUnicodeMap.set(id, std::move(buffer));
171}
skia_private::THashMap< uint32_t, std::vector< SkUnichar > > fToUnicodeMap
virtual void getGlyphToUnicodeMap(SkUnichar *dstArray) const =0
static const uint8_t buffer[]

◆ glyphToPDFFontEncoding()

SkGlyphID SkPDFFont::glyphToPDFFontEncoding ( SkGlyphID  gid) const
inline

Convert the input glyph ID into the font encoding.

Definition at line 67 of file SkPDFFont.h.

67 {
68 if (this->multiByteGlyphs() || gid == 0) {
69 return gid;
70 }
71 SkASSERT(gid >= this->firstGlyphID() && gid <= this->lastGlyphID());
72 SkASSERT(this->firstGlyphID() > 0);
73 return gid - this->firstGlyphID() + 1;
74 }
bool multiByteGlyphs() const
Definition SkPDFFont.h:58
SkGlyphID lastGlyphID() const
Definition SkPDFFont.h:119
SkGlyphID firstGlyphID() const
Definition SkPDFFont.h:118

◆ glyphUsage()

const SkPDFGlyphUse & SkPDFFont::glyphUsage ( ) const
inline

Definition at line 120 of file SkPDFFont.h.

120{ return fGlyphUsage; }

◆ hasGlyph()

bool SkPDFFont::hasGlyph ( SkGlyphID  gid)
inline

Return true if this font has an encoding for the passed glyph id.

Definition at line 62 of file SkPDFFont.h.

62 {
63 return (gid >= this->firstGlyphID() && gid <= this->lastGlyphID()) || gid == 0;
64 }

◆ indirectReference()

SkPDFIndirectReference SkPDFFont::indirectReference ( ) const
inline

Definition at line 81 of file SkPDFFont.h.

81{ return fIndirectReference; }

◆ IsMultiByte()

static bool SkPDFFont::IsMultiByte ( SkAdvancedTypefaceMetrics::FontType  type)
inlinestatic

◆ lastGlyphID()

SkGlyphID SkPDFFont::lastGlyphID ( ) const
inline

Definition at line 119 of file SkPDFFont.h.

119{ return fGlyphUsage.lastGlyph(); }
SkGlyphID lastGlyph() const

◆ multiByteGlyphs()

bool SkPDFFont::multiByteGlyphs ( ) const
inline

Returns true if this font encoding supports glyph IDs above 255.

Definition at line 58 of file SkPDFFont.h.

58{ return SkPDFFont::IsMultiByte(this->getType()); }
SkAdvancedTypefaceMetrics::FontType getType() const
Definition SkPDFFont.h:44

◆ noteGlyphUsage()

void SkPDFFont::noteGlyphUsage ( SkGlyphID  glyph)
inline

Definition at line 76 of file SkPDFFont.h.

76 {
77 SkASSERT(this->hasGlyph(glyph));
78 fGlyphUsage.set(glyph);
79 }
bool hasGlyph(SkGlyphID gid)
Definition SkPDFFont.h:62
void set(SkGlyphID gid)

◆ operator=()

SkPDFFont & SkPDFFont::operator= ( SkPDFFont &&  )
default

◆ PopulateCommonFontDescriptor()

void SkPDFFont::PopulateCommonFontDescriptor ( SkPDFDict descriptor,
const SkAdvancedTypefaceMetrics metrics,
uint16_t  emSize,
int16_t  defaultWidth 
)
static

Definition at line 255 of file SkPDFFont.cpp.

258 {
259 descriptor->insertName("FontName", metrics.fPostScriptName);
260 descriptor->insertInt("Flags", (size_t)(metrics.fStyle | kPdfSymbolic));
261 descriptor->insertScalar("Ascent",
262 scaleFromFontUnits(metrics.fAscent, emSize));
263 descriptor->insertScalar("Descent",
264 scaleFromFontUnits(metrics.fDescent, emSize));
265 descriptor->insertScalar("StemV",
266 scaleFromFontUnits(metrics.fStemV, emSize));
267 descriptor->insertScalar("CapHeight",
268 scaleFromFontUnits(metrics.fCapHeight, emSize));
269 descriptor->insertInt("ItalicAngle", metrics.fItalicAngle);
270 descriptor->insertObject("FontBBox",
271 SkPDFMakeArray(scaleFromFontUnits(metrics.fBBox.left(), emSize),
272 scaleFromFontUnits(metrics.fBBox.bottom(), emSize),
273 scaleFromFontUnits(metrics.fBBox.right(), emSize),
274 scaleFromFontUnits(metrics.fBBox.top(), emSize)));
275 if (defaultWidth > 0) {
276 descriptor->insertScalar("MissingWidth",
277 scaleFromFontUnits(defaultWidth, emSize));
278 }
279}
static std::unique_ptr< SkPDFArray > SkPDFMakeArray(Args... args)
Definition SkPDFTypes.h:135
void insertName(const char key[], const char nameValue[])
void insertObject(const char key[], std::unique_ptr< SkPDFObject > &&)
void insertInt(const char key[], int32_t value)
void insertScalar(const char key[], SkScalar value)
constexpr int32_t top() const
Definition SkRect.h:120
constexpr int32_t bottom() const
Definition SkRect.h:134
constexpr int32_t right() const
Definition SkRect.h:127
constexpr int32_t left() const
Definition SkRect.h:113

◆ refTypeface()

sk_sp< SkTypeface > SkPDFFont::refTypeface ( ) const
inline

Definition at line 121 of file SkPDFFont.h.

121{ return fTypeface; }

◆ typeface()

SkTypeface * SkPDFFont::typeface ( ) const
inline

Returns the typeface represented by this class. Returns nullptr for the default typeface.

Definition at line 39 of file SkPDFFont.h.

39{ return fTypeface.get(); }
T * get() const
Definition SkRefCnt.h:303

The documentation for this class was generated from the following files: