5#include "core/fxge/cfx_face.h"
13#include "core/fxge/cfx_font.h"
14#include "core/fxge/cfx_fontmgr.h"
15#include "core/fxge/cfx_gemodule.h"
16#include "core/fxge/cfx_glyphbitmap.h"
17#include "core/fxge/cfx_path.h"
18#include "core/fxge/cfx_substfont.h"
19#include "core/fxge/dib/cfx_dibitmap.h"
20#include "core/fxge/dib/fx_dib.h"
21#include "core/fxge/fx_fontencoding.h"
22#include "core/fxge/scoped_font_transform.h"
23#include "third_party/base/check.h"
24#include "third_party/base/check_op.h"
25#include "third_party/base/notreached.h"
26#include "third_party/base/numerics/safe_conversions.h"
27#include "third_party/base/numerics/safe_math.h"
29#define EM_ADJUST(em, a) (em == 0
? (a) : (a) * 1000
/ em)
33struct OUTLINE_PARAMS {
40constexpr int kThousandthMinInt =
std::numeric_limits<
int>::min() / 1000;
41constexpr int kThousandthMaxInt =
std::numeric_limits<
int>::max() / 1000;
43constexpr int kMaxGlyphDimension = 2048;
45constexpr uint8_t kWeightPow[] = {
46 0, 6, 12, 14, 16, 18, 22, 24, 28, 30, 32, 34, 36, 38, 40,
47 42, 44, 46, 48, 50, 52, 54, 56, 58, 60, 62, 64, 66, 68, 70,
48 70, 72, 72, 74, 74, 74, 76, 76, 76, 78, 78, 78, 80, 80, 80,
49 82, 82, 82, 84, 84, 84, 84, 86, 86, 86, 88, 88, 88, 88, 90,
50 90, 90, 90, 92, 92, 92, 92, 94, 94, 94, 94, 96, 96, 96, 96,
51 96, 98, 98, 98, 98, 100, 100, 100, 100, 100, 102, 102, 102, 102, 102,
52 104, 104, 104, 104, 104, 106, 106, 106, 106, 106,
55constexpr uint8_t kWeightPow11[] = {
56 0, 4, 7, 8, 9, 10, 12, 13, 15, 17, 18, 19, 20, 21, 22, 23, 24,
57 25, 26, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 39, 39, 40, 40, 41,
58 41, 41, 42, 42, 42, 43, 43, 43, 44, 44, 44, 45, 45, 45, 46, 46, 46,
59 46, 43, 47, 47, 48, 48, 48, 48, 45, 50, 50, 50, 46, 51, 51, 51, 52,
60 52, 52, 52, 53, 53, 53, 53, 53, 54, 54, 54, 54, 55, 55, 55, 55, 55,
61 56, 56, 56, 56, 56, 57, 57, 57, 57, 57, 58, 58, 58, 58, 58,
64constexpr uint8_t kWeightPowShiftJis[] = {
65 0, 0, 2, 4, 6, 8, 10, 14, 16, 20, 22, 26, 28, 32, 34,
66 38, 42, 44, 48, 52, 56, 60, 64, 66, 70, 74, 78, 82, 86, 90,
67 96, 96, 96, 96, 98, 98, 98, 100, 100, 100, 100, 102, 102, 102, 102,
68 104, 104, 104, 104, 104, 106, 106, 106, 106, 106, 108, 108, 108, 108, 108,
69 110, 110, 110, 110, 110, 112, 112, 112, 112, 112, 112, 114, 114, 114, 114,
70 114, 114, 114, 116, 116, 116, 116, 116, 116, 116, 118, 118, 118, 118, 118,
71 118, 118, 120, 120, 120, 120, 120, 120, 120, 120,
74constexpr size_t kWeightPowArraySize = 100;
75static_assert(kWeightPowArraySize ==
std::size(kWeightPow),
"Wrong size");
76static_assert(kWeightPowArraySize ==
std::size(kWeightPow11),
"Wrong size");
77static_assert(kWeightPowArraySize ==
std::size(kWeightPowShiftJis),
81int GetWeightLevel(
FX_Charset charset, size_t index) {
82 if (index >= kWeightPowArraySize) {
87 return kWeightPowShiftJis[index];
89 return kWeightPow11[index];
92int GetSkewFromAngle(
int angle) {
93 static constexpr int8_t kAngleSkew[] = {
94 -0, -2, -3, -5, -7, -9, -11, -12, -14, -16, -18, -19, -21, -23, -25,
95 -27, -29, -31, -32, -34, -36, -38, -40, -42, -45, -47, -49, -51, -53, -55,
100 if (angle > 0 || angle ==
std::numeric_limits<
int>::min() ||
101 static_cast<size_t>(-angle) >=
std::size(kAngleSkew)) {
104 return kAngleSkew[-angle];
107void Outline_CheckEmptyContour(OUTLINE_PARAMS* param) {
110 pdfium::span<
const CFX_Path::
Point> points = param->m_pPath->GetPoints();
111 size = points.size();
115 points[size - 2].m_Point == points[size - 1].m_Point) {
121 points[size - 3].m_Point == points[size - 4].m_Point &&
122 points[size - 2].m_Point == points[size - 4].m_Point &&
123 points[size - 1].m_Point == points[size - 4].m_Point) {
128 param->m_pPath->GetPoints().resize(size);
131int Outline_MoveTo(
const FT_Vector* to,
void* user) {
132 OUTLINE_PARAMS* param =
static_cast<OUTLINE_PARAMS*>(user);
134 Outline_CheckEmptyContour(param);
136 param->m_pPath->ClosePath();
137 param->m_pPath->AppendPoint(
138 CFX_PointF(to->x / param->m_CoordUnit, to->y / param->m_CoordUnit),
141 param->m_CurX = to->x;
142 param->m_CurY = to->y;
146int Outline_LineTo(
const FT_Vector* to,
void* user) {
147 OUTLINE_PARAMS* param =
static_cast<OUTLINE_PARAMS*>(user);
149 param->m_pPath->AppendPoint(
150 CFX_PointF(to->x / param->m_CoordUnit, to->y / param->m_CoordUnit),
153 param->m_CurX = to->x;
154 param->m_CurY = to->y;
158int Outline_ConicTo(
const FT_Vector* control,
const FT_Vector* to,
void* user) {
159 OUTLINE_PARAMS* param =
static_cast<OUTLINE_PARAMS*>(user);
161 param->m_pPath->AppendPoint(
162 CFX_PointF((param->m_CurX + (control->x - param->m_CurX) * 2 / 3) /
164 (param->m_CurY + (control->y - param->m_CurY) * 2 / 3) /
168 param->m_pPath->AppendPoint(
169 CFX_PointF((control->x + (to->x - control->x) / 3) / param->m_CoordUnit,
170 (control->y + (to->y - control->y) / 3) / param->m_CoordUnit),
173 param->m_pPath->AppendPoint(
174 CFX_PointF(to->x / param->m_CoordUnit, to->y / param->m_CoordUnit),
177 param->m_CurX = to->x;
178 param->m_CurY = to->y;
182int Outline_CubicTo(
const FT_Vector* control1,
183 const FT_Vector* control2,
186 OUTLINE_PARAMS* param =
static_cast<OUTLINE_PARAMS*>(user);
188 param->m_pPath->AppendPoint(CFX_PointF(control1->x / param->m_CoordUnit,
189 control1->y / param->m_CoordUnit),
192 param->m_pPath->AppendPoint(CFX_PointF(control2->x / param->m_CoordUnit,
193 control2->y / param->m_CoordUnit),
196 param->m_pPath->AppendPoint(
197 CFX_PointF(to->x / param->m_CoordUnit, to->y / param->m_CoordUnit),
200 param->m_CurX = to->x;
201 param->m_CurY = to->y;
207 case fxge::FontEncoding::kAdobeCustom:
208 return FT_ENCODING_ADOBE_CUSTOM;
209 case fxge::FontEncoding::kAdobeExpert:
210 return FT_ENCODING_ADOBE_EXPERT;
211 case fxge::FontEncoding::kAdobeStandard:
212 return FT_ENCODING_ADOBE_STANDARD;
213 case fxge::FontEncoding::kAppleRoman:
214 return FT_ENCODING_APPLE_ROMAN;
215 case fxge::FontEncoding::kBig5:
216 return FT_ENCODING_BIG5;
217 case fxge::FontEncoding::kGB2312:
218 return FT_ENCODING_PRC;
219 case fxge::FontEncoding::kJohab:
220 return FT_ENCODING_JOHAB;
221 case fxge::FontEncoding::kLatin1:
222 return FT_ENCODING_ADOBE_LATIN_1;
223 case fxge::FontEncoding::kNone:
224 return FT_ENCODING_NONE;
225 case fxge::FontEncoding::kOldLatin2:
226 return FT_ENCODING_OLD_LATIN_2;
227 case fxge::FontEncoding::kSjis:
228 return FT_ENCODING_SJIS;
229 case fxge::FontEncoding::kSymbol:
230 return FT_ENCODING_MS_SYMBOL;
231 case fxge::FontEncoding::kUnicode:
232 return FT_ENCODING_UNICODE;
233 case fxge::FontEncoding::kWansung:
234 return FT_ENCODING_WANSUNG;
239 switch (ft_encoding) {
240 case FT_ENCODING_ADOBE_CUSTOM:
242 case FT_ENCODING_ADOBE_EXPERT:
244 case FT_ENCODING_ADOBE_STANDARD:
246 case FT_ENCODING_APPLE_ROMAN:
248 case FT_ENCODING_BIG5:
250 case FT_ENCODING_PRC:
252 case FT_ENCODING_JOHAB:
254 case FT_ENCODING_ADOBE_LATIN_1:
256 case FT_ENCODING_NONE:
258 case FT_ENCODING_OLD_LATIN_2:
260 case FT_ENCODING_SJIS:
262 case FT_ENCODING_MS_SYMBOL:
264 case FT_ENCODING_UNICODE:
266 case FT_ENCODING_WANSUNG:
269 NOTREACHED_NORETURN();
277 pdfium::span<
const FT_Byte> data,
278 FT_Long face_index) {
279 FXFT_FaceRec* pRec =
nullptr;
280 if (FT_New_Memory_Face(library, data.data(),
281 pdfium::base::checked_cast<FT_Long>(data.size()),
282 face_index, &pRec) != 0) {
286 return pdfium::WrapRetain(
new CFX_Face(pRec,
std::move(pDesc)));
291 const FT_Open_Args* args,
292 FT_Long face_index) {
293 FXFT_FaceRec* pRec =
nullptr;
294 if (FT_Open_Face(library, args, face_index, &pRec) != 0)
298 return pdfium::WrapRetain(
new CFX_Face(pRec,
nullptr));
302 return !!(GetRec()->face_flags & FT_FACE_FLAG_GLYPH_NAMES);
306 return !!(GetRec()->face_flags & FT_FACE_FLAG_SFNT);
310 return !!(GetRec()->face_flags & FT_FACE_FLAG_TRICKY);
314 return !!(GetRec()->face_flags & FT_FACE_FLAG_FIXED_WIDTH);
317#if defined(PDF_ENABLE_XFA)
318bool CFX_Face::IsScalable()
const {
319 return !!(GetRec()->face_flags & FT_FACE_FLAG_SCALABLE);
322void CFX_Face::ClearExternalStream() {
323 GetRec()->face_flags &= ~FT_FACE_FLAG_EXTERNAL_STREAM;
328 return !!(GetRec()->style_flags & FT_STYLE_FLAG_ITALIC);
332 return !!(GetRec()->style_flags & FT_STYLE_FLAG_BOLD);
336 return ByteString(
GetRec()->family_name);
340 return ByteString(
GetRec()->style_name);
344 return FX_RECT(pdfium::base::checked_cast<int32_t>(
GetRec()->bbox.xMin),
345 pdfium::base::checked_cast<int32_t>(
GetRec()->bbox.yMin),
346 pdfium::base::checked_cast<int32_t>(
GetRec()->bbox.xMax),
347 pdfium::base::checked_cast<int32_t>(
GetRec()->bbox.yMax));
351 return pdfium::base::checked_cast<uint16_t>(
GetRec()->units_per_EM);
355 return pdfium::base::checked_cast<int16_t>(
GetRec()->ascender);
359 return pdfium::base::checked_cast<int16_t>(
GetRec()->descender);
364 CHECK_GE(ascender, kThousandthMinInt);
365 CHECK_LE(ascender, kThousandthMaxInt);
371 CHECK_GE(descender, kThousandthMinInt);
372 CHECK_LE(descender, kThousandthMaxInt);
376#if BUILDFLAG(IS_ANDROID)
377int16_t CFX_Face::GetHeight()
const {
378 return pdfium::base::checked_cast<int16_t>(GetRec()->height);
382pdfium::span<uint8_t> CFX_Face::
GetData()
const {
387 unsigned long length =
388 pdfium::base::checked_cast<
unsigned long>(buffer.size());
390 int error = FT_Load_Sfnt_Table(
GetRec(), table, 0, buffer.data(), &length);
391 if (error || length != buffer.size()) {
394 return buffer.size();
397 int error = FT_Load_Sfnt_Table(
GetRec(), table, 0,
nullptr, &length);
398 if (error || !length) {
401 return pdfium::base::checked_cast<size_t>(length);
405 auto* os2 =
static_cast<TT_OS2*>(FT_Get_Sfnt_Table(GetRec(), FT_SFNT_OS2));
407 return absl::nullopt;
409 return std::array<uint32_t, 4>{
static_cast<uint32_t>(os2->ulUnicodeRange1),
410 static_cast<uint32_t>(os2->ulUnicodeRange2),
411 static_cast<uint32_t>(os2->ulUnicodeRange3),
412 static_cast<uint32_t>(os2->ulUnicodeRange4)};
416 auto* os2 =
static_cast<TT_OS2*>(FT_Get_Sfnt_Table(GetRec(), FT_SFNT_OS2));
418 return absl::nullopt;
420 return std::array<uint32_t, 2>{
static_cast<uint32_t>(os2->ulCodePageRange1),
421 static_cast<uint32_t>(os2->ulCodePageRange2)};
425 auto* os2 =
static_cast<TT_OS2*>(FT_Get_Sfnt_Table(GetRec(), FT_SFNT_OS2));
427 return absl::nullopt;
429 return std::array<uint8_t, 2>{os2->panose[0], os2->panose[1]};
433 return pdfium::base::checked_cast<
int>(
GetRec()->num_glyphs);
437 uint32_t glyph_index,
443 ft_matrix.xx = matrix
.a / 64 * 65536;
444 ft_matrix.xy = matrix
.c / 64 * 65536;
445 ft_matrix.yx = matrix
.b / 64 * 65536;
446 ft_matrix.yy = matrix
.d / 64 * 65536;
447 bool bUseCJKSubFont =
false;
452 if (bUseCJKSubFont) {
458 int skew = GetSkewFromAngle(angle);
460 ft_matrix.yx += ft_matrix.yy * skew / 100;
462 ft_matrix.xy -= ft_matrix.xx * skew / 100;
466 pFont->GetFace()->AdjustVariationParams(glyph_index, dest_width,
472 int load_flags = FT_LOAD_NO_BITMAP | FT_LOAD_PEDANTIC;
474 load_flags |= FT_LOAD_NO_HINTING;
477 int error = FT_Load_Glyph(rec, glyph_index, load_flags);
480 if (load_flags & FT_LOAD_NO_HINTING) {
484 load_flags |= FT_LOAD_NO_HINTING;
485 load_flags &= ~FT_LOAD_PEDANTIC;
486 error = FT_Load_Glyph(rec, glyph_index, load_flags);
492 auto* glyph = rec->glyph;
494 if (bUseCJKSubFont) {
497 weight = pSubstFont ? pSubstFont
->m_Weight : 0;
500 uint32_t index = (weight - 400) / 10;
501 pdfium::base::CheckedNumeric<
signed long> level =
502 GetWeightLevel(pSubstFont->m_Charset, index);
503 if (level.ValueOrDefault(-1) < 0) {
508 (abs(
static_cast<
int>(ft_matrix.xx)) +
509 abs(
static_cast<
int>(ft_matrix.xy))) /
511 FT_Outline_Embolden(&glyph->outline, level.ValueOrDefault(0));
513 FT_Library_SetLcdFilter(CFX_GEModule::Get()->GetFontMgr()->GetFTLibrary(),
514 FT_LCD_FILTER_DEFAULT);
515 error = FT_Render_Glyph(glyph,
static_cast<FT_Render_Mode>(anti_alias));
520 const FT_Bitmap& bitmap = glyph->bitmap;
521 if (bitmap.width > kMaxGlyphDimension || bitmap.rows > kMaxGlyphDimension) {
524 int dib_width = bitmap.width;
527 pGlyphBitmap->GetBitmap()->Create(dib_width, bitmap.rows,
528 anti_alias == FT_RENDER_MODE_MONO
529 ? FXDIB_Format::k1bppMask
530 : FXDIB_Format::k8bppMask);
531 int dest_pitch = pGlyphBitmap->GetBitmap()->GetPitch();
532 uint8_t* pDestBuf = pGlyphBitmap->GetBitmap()->GetWritableBuffer().data();
533 const uint8_t* pSrcBuf = bitmap.buffer;
534 if (anti_alias != FT_RENDER_MODE_MONO &&
535 bitmap.pixel_mode == FT_PIXEL_MODE_MONO) {
536 unsigned int bytes = anti_alias == FT_RENDER_MODE_LCD ? 3 : 1;
537 for (
unsigned int i = 0; i < bitmap.rows; i++) {
538 for (
unsigned int n = 0; n < bitmap.width; n++) {
540 (pSrcBuf[i * bitmap.pitch + n / 8] & (0x80 >> (n % 8))) ? 255 : 0;
541 for (
unsigned int b = 0; b < bytes; b++) {
542 pDestBuf[i * dest_pitch + n * bytes + b] = data;
547 FXSYS_memset(pDestBuf, 0, dest_pitch * bitmap.rows);
548 int rowbytes =
std::min(abs(bitmap.pitch), dest_pitch);
549 for (
unsigned int row = 0; row < bitmap.rows; row++) {
550 FXSYS_memcpy(pDestBuf + row * dest_pitch, pSrcBuf + row * bitmap.pitch,
558 uint32_t glyph_index,
563 FT_Set_Pixel_Sizes(rec, 0, 64);
564 FT_Matrix ft_matrix = {65536, 0, 0, 65536};
569 ft_matrix.yx += ft_matrix.yy * skew / 100;
571 ft_matrix.xy -= ft_matrix.xx * skew / 100;
575 AdjustVariationParams(glyph_index, dest_width, subst_font
->m_Weight);
579 int load_flags = FT_LOAD_NO_BITMAP;
581 load_flags |= FT_LOAD_NO_HINTING;
583 if (FT_Load_Glyph(rec, glyph_index, load_flags)) {
588 uint32_t index =
std::min<uint32_t>((subst_font
->m_Weight - 400) / 10,
589 kWeightPowArraySize - 1);
592 level = kWeightPowShiftJis[index] * 65536 / 36655;
594 level = kWeightPow[index];
596 FT_Outline_Embolden(&rec->glyph->outline, level);
599 FT_Outline_Funcs funcs;
600 funcs.move_to = Outline_MoveTo;
601 funcs.line_to = Outline_LineTo;
602 funcs.conic_to = Outline_ConicTo;
603 funcs.cubic_to = Outline_CubicTo;
608 OUTLINE_PARAMS params;
609 params.m_pPath = pPath.get();
610 params.m_CurX = params.m_CurY = 0;
611 params.m_CoordUnit = 64 * 64.0;
613 FT_Outline_Decompose(&rec->glyph->outline, &funcs, ¶ms);
614 if (pPath->GetPoints().empty()) {
618 Outline_CheckEmptyContour(¶ms);
628 AdjustVariationParams(glyph_index, dest_width, weight);
632 int err = FT_Load_Glyph(
633 rec, glyph_index, FT_LOAD_NO_SCALE | FT_LOAD_IGNORE_GLOBAL_ADVANCE_WIDTH);
638 FT_Pos horizontal_advance = rec->glyph->metrics.horiAdvance;
639 if (horizontal_advance < kThousandthMinInt ||
640 horizontal_advance > kThousandthMaxInt) {
648 return FT_Get_Char_Index(
GetRec(), code);
653 return FT_Get_Name_Index(
GetRec(),
const_cast<
char*>(name));
659 char_code_and_index
.char_code =
static_cast<uint32_t>(
661 if (char_code_and_index
.char_code > max_char) {
664 std::vector<CharCodeAndIndex> results = {char_code_and_index};
666 char_code_and_index
.char_code =
static_cast<uint32_t>(FT_Get_Next_Char(
668 if (char_code_and_index
.char_code > max_char ||
672 results.push_back(char_code_and_index);
682 return absl::nullopt;
684 return ToFontEncoding(
GetRec()->charmap->encoding);
688 CHECK_LT(index, GetCharMapCount());
689 return GetRec()->charmaps[index]->platform_id;
693 CHECK_LT(index, GetCharMapCount());
694 return GetRec()->charmaps[index]->encoding_id;
698 CHECK_LT(index, GetCharMapCount());
699 return ToFontEncoding(
GetRec()->charmaps[index]->encoding);
703 return GetRec()->charmaps
704 ? pdfium::base::checked_cast<size_t>(GetRec()->num_charmaps)
709 FT_Set_Charmap(
GetRec(),
static_cast<FT_CharMap>(map));
713 CHECK_LT(index, GetCharMapCount());
718 FT_Error error = FT_Select_Charmap(GetRec(), ToFTEncoding(encoding));
723bool CFX_Face::CanEmbed() {
724 FT_UShort fstype = FT_Get_FSType_Flags(GetRec());
725 return (fstype & (FT_FSTYPE_RESTRICTED_LICENSE_EMBEDDING |
726 FT_FSTYPE_BITMAP_EMBEDDING_ONLY)) == 0;
731 : m_pRec(rec), m_pDesc(std::move(pDesc)) {
737void CFX_Face::AdjustVariationParams(
int glyph_index,
740 DCHECK(dest_width >= 0);
744 if (!variation_desc) {
750 coords[0] = variation_desc.GetAxisDefault(0) / 65536;
755 if (dest_width == 0) {
756 coords[1] = variation_desc.GetAxisDefault(1) / 65536;
758 FT_Long min_param = variation_desc.GetAxisMin(1) / 65536;
759 FT_Long max_param = variation_desc.GetAxisMax(1) / 65536;
760 coords[1] = min_param;
761 FT_Set_MM_Design_Coordinates(rec, 2, coords);
762 FT_Load_Glyph(rec, glyph_index,
763 FT_LOAD_NO_SCALE | FT_LOAD_IGNORE_GLOBAL_ADVANCE_WIDTH);
764 FT_Pos min_width = rec->glyph->metrics.horiAdvance * 1000 / GetUnitsPerEm();
765 coords[1] = max_param;
766 FT_Set_MM_Design_Coordinates(rec, 2, coords);
767 FT_Load_Glyph(rec, glyph_index,
768 FT_LOAD_NO_SCALE | FT_LOAD_IGNORE_GLOBAL_ADVANCE_WIDTH);
769 FT_Pos max_width = rec->glyph->metrics.horiAdvance * 1000 / GetUnitsPerEm();
770 if (max_width == min_width) {
773 FT_Pos param = min_param + (max_param - min_param) *
774 (dest_width - min_width) /
775 (max_width - min_width);
778 FT_Set_MM_Design_Coordinates(rec, 2, coords);
ByteString GetStyleName() const
absl::optional< std::array< uint8_t, 2 > > GetOs2Panose()
size_t GetCharMapCount() const
int GetCharMapEncodingIdByIndex(size_t index) const
bool IsFixedWidth() const
bool SelectCharMap(fxge::FontEncoding encoding)
bool HasGlyphNames() const
absl::optional< std::array< uint32_t, 2 > > GetOs2CodePageRange()
int16_t GetAscender() const
std::unique_ptr< CFX_Path > LoadGlyphPath(uint32_t glyph_index, int dest_width, bool is_vertical, const CFX_SubstFont *subst_font)
fxge::FontEncoding GetCharMapEncodingByIndex(size_t index) const
int GetGlyphWidth(uint32_t glyph_index, int dest_width, int weight, const CFX_SubstFont *subst_font)
int GetAdjustedDescender() const
std::unique_ptr< CFX_GlyphBitmap > RenderGlyph(const CFX_Font *pFont, uint32_t glyph_index, bool bFontStyle, const CFX_Matrix &matrix, int dest_width, int anti_alias)
int GetGlyphCount() const
void SetCharMap(CharMap map)
absl::optional< std::array< uint32_t, 4 > > GetOs2UnicodeRange()
int16_t GetDescender() const
void SetCharMapByIndex(size_t index)
pdfium::span< uint8_t > GetData() const
int GetCharMapPlatformIdByIndex(size_t index) const
int GetNameIndex(const char *name)
const FXFT_FaceRec * GetRec() const
CharMap GetCurrentCharMap() const
absl::optional< fxge::FontEncoding > GetCurrentCharMapEncoding() const
int GetCharIndex(uint32_t code)
std::vector< CharCodeAndIndex > GetCharCodesAndIndices(char32_t max_char)
int GetAdjustedAscender() const
ByteString GetFamilyName() const
uint16_t GetUnitsPerEm() const
size_t GetSfntTable(uint32_t table, pdfium::span< uint8_t > buffer)
CFX_SubstFont * GetSubstFont() const
bool IsBuiltInGenericFont() const
ScopedFXFTMMVar(FXFT_FaceRec *face)