5#include "core/fxge/cfx_face.h"
14#include "core/fxcrt/check.h"
15#include "core/fxcrt/check_op.h"
16#include "core/fxcrt/compiler_specific.h"
17#include "core/fxcrt/notreached.h"
18#include "core/fxcrt/numerics/clamped_math.h"
19#include "core/fxcrt/numerics/safe_conversions.h"
20#include "core/fxcrt/numerics/safe_math.h"
21#include "core/fxcrt/span.h"
22#include "core/fxcrt/stl_util.h"
23#include "core/fxge/cfx_font.h"
24#include "core/fxge/cfx_fontmgr.h"
25#include "core/fxge/cfx_gemodule.h"
26#include "core/fxge/cfx_glyphbitmap.h"
27#include "core/fxge/cfx_path.h"
28#include "core/fxge/cfx_substfont.h"
29#include "core/fxge/dib/cfx_dibitmap.h"
30#include "core/fxge/dib/fx_dib.h"
31#include "core/fxge/fx_font.h"
32#include "core/fxge/fx_fontencoding.h"
33#include "core/fxge/scoped_font_transform.h"
35#define EM_ADJUST(em, a) (em == 0
? (a) : (a) * 1000
/ em)
39struct OUTLINE_PARAMS {
46constexpr int kThousandthMinInt =
std::numeric_limits<
int>::min() / 1000;
47constexpr int kThousandthMaxInt =
std::numeric_limits<
int>::max() / 1000;
49constexpr int kMaxGlyphDimension = 2048;
52constexpr int kMaxRectTop = 2114445437;
54constexpr auto kWeightPow =
fxcrt::ToArray<
const uint8_t>({
55 0, 6, 12, 14, 16, 18, 22, 24, 28, 30, 32, 34, 36, 38, 40,
56 42, 44, 46, 48, 50, 52, 54, 56, 58, 60, 62, 64, 66, 68, 70,
57 70, 72, 72, 74, 74, 74, 76, 76, 76, 78, 78, 78, 80, 80, 80,
58 82, 82, 82, 84, 84, 84, 84, 86, 86, 86, 88, 88, 88, 88, 90,
59 90, 90, 90, 92, 92, 92, 92, 94, 94, 94, 94, 96, 96, 96, 96,
60 96, 98, 98, 98, 98, 100, 100, 100, 100, 100, 102, 102, 102, 102, 102,
61 104, 104, 104, 104, 104, 106, 106, 106, 106, 106,
64constexpr auto kWeightPow11 =
fxcrt::ToArray<
const uint8_t>({
65 0, 4, 7, 8, 9, 10, 12, 13, 15, 17, 18, 19, 20, 21, 22, 23, 24,
66 25, 26, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 39, 39, 40, 40, 41,
67 41, 41, 42, 42, 42, 43, 43, 43, 44, 44, 44, 45, 45, 45, 46, 46, 46,
68 46, 43, 47, 47, 48, 48, 48, 48, 45, 50, 50, 50, 46, 51, 51, 51, 52,
69 52, 52, 52, 53, 53, 53, 53, 53, 54, 54, 54, 54, 55, 55, 55, 55, 55,
70 56, 56, 56, 56, 56, 57, 57, 57, 57, 57, 58, 58, 58, 58, 58,
73constexpr auto kWeightPowShiftJis =
fxcrt::ToArray<
const uint8_t>({
74 0, 0, 2, 4, 6, 8, 10, 14, 16, 20, 22, 26, 28, 32, 34,
75 38, 42, 44, 48, 52, 56, 60, 64, 66, 70, 74, 78, 82, 86, 90,
76 96, 96, 96, 96, 98, 98, 98, 100, 100, 100, 100, 102, 102, 102, 102,
77 104, 104, 104, 104, 104, 106, 106, 106, 106, 106, 108, 108, 108, 108, 108,
78 110, 110, 110, 110, 110, 112, 112, 112, 112, 112, 112, 114, 114, 114, 114,
79 114, 114, 114, 116, 116, 116, 116, 116, 116, 116, 118, 118, 118, 118, 118,
80 118, 118, 120, 120, 120, 120, 120, 120, 120, 120,
83constexpr size_t kWeightPowArraySize = 100;
84static_assert(kWeightPowArraySize ==
std::size(kWeightPow),
"Wrong size");
85static_assert(kWeightPowArraySize ==
std::size(kWeightPow11),
"Wrong size");
86static_assert(kWeightPowArraySize ==
std::size(kWeightPowShiftJis),
89constexpr auto kAngleSkew =
fxcrt::ToArray<
const int8_t>({
90 -0, -2, -3, -5, -7, -9, -11, -12, -14, -16, -18, -19, -21, -23, -25,
91 -27, -29, -31, -32, -34, -36, -38, -40, -42, -45, -47, -49, -51, -53, -55,
95int GetWeightLevel(
FX_Charset charset, size_t index) {
96 if (index >= kWeightPowArraySize) {
101 return kWeightPowShiftJis[index];
103 return kWeightPow11[index];
106int GetSkewFromAngle(
int angle) {
109 if (angle > 0 || angle ==
std::numeric_limits<
int>::min() ||
110 static_cast<size_t>(-angle) >=
std::size(kAngleSkew)) {
113 return kAngleSkew[-angle];
116int FTPosToCBoxInt(FT_Pos pos) {
118 constexpr FT_Pos kMinCBox = -2147483;
119 constexpr FT_Pos kMaxCBox = 2147483;
120 return static_cast<
int>(
std::clamp(pos, kMinCBox, kMaxCBox));
123void Outline_CheckEmptyContour(OUTLINE_PARAMS* param) {
126 pdfium::span<
const CFX_Path::Point> points = param->m_pPath->GetPoints();
127 size = points.size();
131 points[size - 2].m_Point == points[size - 1].m_Point) {
137 points[size - 3].m_Point == points[size - 4].m_Point &&
138 points[size - 2].m_Point == points[size - 4].m_Point &&
139 points[size - 1].m_Point == points[size - 4].m_Point) {
144 param->m_pPath->GetPoints().resize(size);
147int Outline_MoveTo(
const FT_Vector* to,
void* user) {
148 OUTLINE_PARAMS* param =
static_cast<OUTLINE_PARAMS*>(user);
150 Outline_CheckEmptyContour(param);
152 param->m_pPath->ClosePath();
153 param->m_pPath->AppendPoint(
154 CFX_PointF(to->x / param->m_CoordUnit, to->y / param->m_CoordUnit),
157 param->m_CurX = to->x;
158 param->m_CurY = to->y;
162int Outline_LineTo(
const FT_Vector* to,
void* user) {
163 OUTLINE_PARAMS* param =
static_cast<OUTLINE_PARAMS*>(user);
165 param->m_pPath->AppendPoint(
166 CFX_PointF(to->x / param->m_CoordUnit, to->y / param->m_CoordUnit),
169 param->m_CurX = to->x;
170 param->m_CurY = to->y;
174int Outline_ConicTo(
const FT_Vector* control,
const FT_Vector* to,
void* user) {
175 OUTLINE_PARAMS* param =
static_cast<OUTLINE_PARAMS*>(user);
177 param->m_pPath->AppendPoint(
178 CFX_PointF((param->m_CurX + (control->x - param->m_CurX) * 2 / 3) /
180 (param->m_CurY + (control->y - param->m_CurY) * 2 / 3) /
184 param->m_pPath->AppendPoint(
185 CFX_PointF((control->x + (to->x - control->x) / 3) / param->m_CoordUnit,
186 (control->y + (to->y - control->y) / 3) / param->m_CoordUnit),
189 param->m_pPath->AppendPoint(
190 CFX_PointF(to->x / param->m_CoordUnit, to->y / param->m_CoordUnit),
193 param->m_CurX = to->x;
194 param->m_CurY = to->y;
198int Outline_CubicTo(
const FT_Vector* control1,
199 const FT_Vector* control2,
202 OUTLINE_PARAMS* param =
static_cast<OUTLINE_PARAMS*>(user);
204 param->m_pPath->AppendPoint(
CFX_PointF(control1->x / param->m_CoordUnit,
205 control1->y / param->m_CoordUnit),
208 param->m_pPath->AppendPoint(
CFX_PointF(control2->x / param->m_CoordUnit,
209 control2->y / param->m_CoordUnit),
212 param->m_pPath->AppendPoint(
213 CFX_PointF(to->x / param->m_CoordUnit, to->y / param->m_CoordUnit),
216 param->m_CurX = to->x;
217 param->m_CurY = to->y;
223 case fxge::FontEncoding::kAdobeCustom:
224 return FT_ENCODING_ADOBE_CUSTOM;
225 case fxge::FontEncoding::kAdobeExpert:
226 return FT_ENCODING_ADOBE_EXPERT;
227 case fxge::FontEncoding::kAdobeStandard:
228 return FT_ENCODING_ADOBE_STANDARD;
229 case fxge::FontEncoding::kAppleRoman:
230 return FT_ENCODING_APPLE_ROMAN;
231 case fxge::FontEncoding::kBig5:
232 return FT_ENCODING_BIG5;
233 case fxge::FontEncoding::kGB2312:
234 return FT_ENCODING_PRC;
235 case fxge::FontEncoding::kJohab:
236 return FT_ENCODING_JOHAB;
237 case fxge::FontEncoding::kLatin1:
238 return FT_ENCODING_ADOBE_LATIN_1;
239 case fxge::FontEncoding::kNone:
240 return FT_ENCODING_NONE;
241 case fxge::FontEncoding::kOldLatin2:
242 return FT_ENCODING_OLD_LATIN_2;
243 case fxge::FontEncoding::kSjis:
244 return FT_ENCODING_SJIS;
245 case fxge::FontEncoding::kSymbol:
246 return FT_ENCODING_MS_SYMBOL;
247 case fxge::FontEncoding::kUnicode:
248 return FT_ENCODING_UNICODE;
249 case fxge::FontEncoding::kWansung:
250 return FT_ENCODING_WANSUNG;
255 switch (ft_encoding) {
256 case FT_ENCODING_ADOBE_CUSTOM:
258 case FT_ENCODING_ADOBE_EXPERT:
260 case FT_ENCODING_ADOBE_STANDARD:
262 case FT_ENCODING_APPLE_ROMAN:
264 case FT_ENCODING_BIG5:
266 case FT_ENCODING_PRC:
268 case FT_ENCODING_JOHAB:
270 case FT_ENCODING_ADOBE_LATIN_1:
272 case FT_ENCODING_NONE:
274 case FT_ENCODING_OLD_LATIN_2:
276 case FT_ENCODING_SJIS:
278 case FT_ENCODING_MS_SYMBOL:
280 case FT_ENCODING_UNICODE:
282 case FT_ENCODING_WANSUNG:
293 pdfium::span<
const FT_Byte> data,
294 FT_Long face_index) {
296 if (FT_New_Memory_Face(library, data.data(),
297 pdfium::checked_cast<FT_Long>(data.size()), face_index,
302 return pdfium::WrapRetain(
new CFX_Face(pRec,
std::move(pDesc)));
307 const FT_Open_Args* args,
308 FT_Long face_index) {
310 if (FT_Open_Face(library, args, face_index, &pRec) != 0)
314 return pdfium::WrapRetain(
new CFX_Face(pRec,
nullptr));
318 return !!(GetRec()->face_flags & FT_FACE_FLAG_GLYPH_NAMES);
322 return !!(GetRec()->face_flags & FT_FACE_FLAG_SFNT);
326 return !!(GetRec()->face_flags & FT_FACE_FLAG_TRICKY);
330 return !!(GetRec()->face_flags & FT_FACE_FLAG_FIXED_WIDTH);
333#if defined(PDF_ENABLE_XFA)
334bool CFX_Face::IsScalable()
const {
335 return !!(GetRec()->face_flags & FT_FACE_FLAG_SCALABLE);
338void CFX_Face::ClearExternalStream() {
339 GetRec()->face_flags &= ~FT_FACE_FLAG_EXTERNAL_STREAM;
344 return !!(GetRec()->style_flags & FT_STYLE_FLAG_ITALIC);
348 return !!(GetRec()->style_flags & FT_STYLE_FLAG_BOLD);
378#if BUILDFLAG(IS_ANDROID)
379int16_t CFX_Face::GetHeight()
const {
380 return pdfium::checked_cast<int16_t>(GetRec()->height);
391 unsigned long length =
pdfium::checked_cast<
unsigned long>(buffer.size());
393 int error = FT_Load_Sfnt_Table(
GetRec(), table, 0, buffer.data(), &length);
394 if (error || length != buffer.size()) {
397 return buffer.size();
400 int error = FT_Load_Sfnt_Table(
GetRec(), table, 0,
nullptr, &length);
401 if (error || !length) {
404 return pdfium::checked_cast<size_t>(length);
408 auto* os2 =
static_cast<TT_OS2*>(FT_Get_Sfnt_Table(GetRec(), FT_SFNT_OS2));
412 return std::array<uint32_t, 4>{
static_cast<uint32_t>(os2->ulUnicodeRange1),
413 static_cast<uint32_t>(os2->ulUnicodeRange2),
414 static_cast<uint32_t>(os2->ulUnicodeRange3),
415 static_cast<uint32_t>(os2->ulUnicodeRange4)};
419 auto* os2 =
static_cast<TT_OS2*>(FT_Get_Sfnt_Table(GetRec(), FT_SFNT_OS2));
423 return std::array<uint32_t, 2>{
static_cast<uint32_t>(os2->ulCodePageRange1),
424 static_cast<uint32_t>(os2->ulCodePageRange2)};
428 auto* os2 =
static_cast<TT_OS2*>(FT_Get_Sfnt_Table(GetRec(), FT_SFNT_OS2));
441 uint32_t glyph_index,
447 ft_matrix.xx = matrix
.a / 64 * 65536;
448 ft_matrix.xy = matrix
.c / 64 * 65536;
449 ft_matrix.yx = matrix
.b / 64 * 65536;
450 ft_matrix.yy = matrix
.d / 64 * 65536;
451 bool bUseCJKSubFont =
false;
456 if (bUseCJKSubFont) {
462 int skew = GetSkewFromAngle(angle);
464 ft_matrix.yx += ft_matrix.yy * skew / 100;
466 ft_matrix.xy -= ft_matrix.xx * skew / 100;
470 pFont->GetFace()->AdjustVariationParams(glyph_index, dest_width,
476 int load_flags = FT_LOAD_NO_BITMAP | FT_LOAD_PEDANTIC;
478 load_flags |= FT_LOAD_NO_HINTING;
481 int error = FT_Load_Glyph(rec, glyph_index, load_flags);
484 if (load_flags & FT_LOAD_NO_HINTING) {
488 load_flags |= FT_LOAD_NO_HINTING;
489 load_flags &= ~FT_LOAD_PEDANTIC;
490 error = FT_Load_Glyph(rec, glyph_index, load_flags);
496 auto* glyph = rec->glyph;
498 if (bUseCJKSubFont) {
501 weight = pSubstFont ? pSubstFont
->m_Weight : 0;
504 uint32_t index = (weight - 400) / 10;
506 GetWeightLevel(pSubstFont->m_Charset, index);
507 if (level.ValueOrDefault(-1) < 0) {
512 (abs(
static_cast<
int>(ft_matrix.xx)) +
513 abs(
static_cast<
int>(ft_matrix.xy))) /
515 FT_Outline_Embolden(&glyph->outline, level.ValueOrDefault(0));
517 FT_Library_SetLcdFilter(CFX_GEModule::Get()->GetFontMgr()->GetFTLibrary(),
518 FT_LCD_FILTER_DEFAULT);
519 error = FT_Render_Glyph(glyph,
static_cast<FT_Render_Mode>(anti_alias));
524 const FT_Bitmap& bitmap = glyph->bitmap;
525 if (bitmap.width > kMaxGlyphDimension || bitmap.rows > kMaxGlyphDimension) {
528 int dib_width = bitmap.width;
531 const FXDIB_Format format = anti_alias == FT_RENDER_MODE_MONO
532 ? FXDIB_Format::k1bppMask
533 : FXDIB_Format::k8bppMask;
534 if (!pGlyphBitmap->GetBitmap()->Create(dib_width, bitmap.rows, format)) {
538 int dest_pitch = pGlyphBitmap->GetBitmap()->GetPitch();
539 uint8_t* pDestBuf = pGlyphBitmap->GetBitmap()->GetWritableBuffer().data();
540 const uint8_t* pSrcBuf = bitmap.buffer;
542 if (anti_alias != FT_RENDER_MODE_MONO &&
543 bitmap.pixel_mode == FT_PIXEL_MODE_MONO) {
544 unsigned int bytes = anti_alias == FT_RENDER_MODE_LCD ? 3 : 1;
545 for (
unsigned int i = 0; i < bitmap.rows; i++) {
546 for (
unsigned int n = 0; n < bitmap.width; n++) {
548 (pSrcBuf[i * bitmap.pitch + n / 8] & (0x80 >> (n % 8))) ? 255 : 0;
549 for (
unsigned int b = 0; b < bytes; b++) {
550 pDestBuf[i * dest_pitch + n * bytes + b] = data;
555 FXSYS_memset(pDestBuf, 0, dest_pitch * bitmap.rows);
556 int rowbytes =
std::min(abs(bitmap.pitch), dest_pitch);
557 for (
unsigned int row = 0; row < bitmap.rows; row++) {
558 FXSYS_memcpy(pDestBuf + row * dest_pitch, pSrcBuf + row * bitmap.pitch,
567 uint32_t glyph_index,
572 FT_Set_Pixel_Sizes(rec, 0, 64);
573 FT_Matrix ft_matrix = {65536, 0, 0, 65536};
578 ft_matrix.yx += ft_matrix.yy * skew / 100;
580 ft_matrix.xy -= ft_matrix.xx * skew / 100;
584 AdjustVariationParams(glyph_index, dest_width, subst_font
->m_Weight);
588 int load_flags = FT_LOAD_NO_BITMAP;
590 load_flags |= FT_LOAD_NO_HINTING;
592 if (FT_Load_Glyph(rec, glyph_index, load_flags)) {
597 uint32_t index =
std::min<uint32_t>((subst_font
->m_Weight - 400) / 10,
598 kWeightPowArraySize - 1);
601 level = kWeightPowShiftJis[index] * 65536 / 36655;
603 level = kWeightPow[index];
605 FT_Outline_Embolden(&rec->glyph->outline, level);
608 FT_Outline_Funcs funcs;
609 funcs.move_to = Outline_MoveTo;
610 funcs.line_to = Outline_LineTo;
611 funcs.conic_to = Outline_ConicTo;
612 funcs.cubic_to = Outline_CubicTo;
617 OUTLINE_PARAMS params;
618 params.m_pPath = pPath.get();
619 params.m_CurX = params.m_CurY = 0;
620 params.m_CoordUnit = 64 * 64.0;
622 FT_Outline_Decompose(&rec->glyph->outline, &funcs, ¶ms);
623 if (pPath->GetPoints().empty()) {
627 Outline_CheckEmptyContour(¶ms);
637 AdjustVariationParams(glyph_index, dest_width, weight);
641 int err = FT_Load_Glyph(
642 rec, glyph_index, FT_LOAD_NO_SCALE | FT_LOAD_IGNORE_GLOBAL_ADVANCE_WIDTH);
647 FT_Pos horizontal_advance = rec->glyph->metrics.horiAdvance;
648 if (horizontal_advance < kThousandthMinInt ||
649 horizontal_advance > kThousandthMaxInt) {
658 FT_Get_Glyph_Name(
GetRec(), glyph_index, name,
sizeof(name));
664 return FT_Get_Char_Index(
GetRec(), code);
669 return FT_Get_Name_Index(
GetRec(),
const_cast<
char*>(name));
677 FT_Load_Glyph(rec, glyph_index, FT_LOAD_IGNORE_GLOBAL_ADVANCE_WIDTH);
680 err = FT_Get_Glyph(rec->glyph, &glyph);
683 FT_Glyph_Get_CBox(glyph, FT_GLYPH_BBOX_PIXELS, &cbox);
684 const int xMin = FTPosToCBoxInt(cbox.xMin);
685 const int xMax = FTPosToCBoxInt(cbox.xMax);
686 const int yMin = FTPosToCBoxInt(cbox.yMin);
687 const int yMax = FTPosToCBoxInt(cbox.yMax);
688 const int pixel_size_x = rec->size->metrics.x_ppem;
689 const int pixel_size_y = rec->size->metrics.y_ppem;
690 if (pixel_size_x == 0 || pixel_size_y == 0) {
694 FX_RECT(xMin * 1000 / pixel_size_x
, yMax * 1000 / pixel_size_y
,
695 xMax * 1000 / pixel_size_x
, yMin * 1000 / pixel_size_y
);
699 FT_Done_Glyph(glyph);
703 int err = FT_Load_Glyph(rec, glyph_index, FT_LOAD_NO_SCALE);
706 if (rect
.top <= kMaxRectTop) {
709 rect
.top =
std::numeric_limits<
int>::max();
717 const auto* glyph =
GetRec()->glyph;
718 pdfium::ClampedNumeric<FT_Pos> left = glyph->metrics.horiBearingX;
719 pdfium::ClampedNumeric<FT_Pos> top = glyph->metrics.horiBearingY;
721 return FX_RECT(NormalizeFontMetric(left, upem),
722 NormalizeFontMetric(top, upem),
723 NormalizeFontMetric(left + glyph->metrics.width, upem),
724 NormalizeFontMetric(top - glyph->metrics.height, upem));
730 char_code_and_index
.char_code =
static_cast<uint32_t>(
732 if (char_code_and_index
.char_code > max_char) {
735 std::vector<CharCodeAndIndex> results = {char_code_and_index};
737 char_code_and_index
.char_code =
static_cast<uint32_t>(FT_Get_Next_Char(
739 if (char_code_and_index
.char_code > max_char ||
743 results.push_back(char_code_and_index);
755 return ToFontEncoding(
GetRec()->charmap->encoding);
777 return GetRec()->charmaps
778 ? pdfium::checked_cast<size_t>(GetRec()->num_charmaps)
783 FT_Set_Charmap(
GetRec(),
static_cast<FT_CharMap>(map));
793 FT_Error error = FT_Select_Charmap(GetRec(), ToFTEncoding(encoding));
798 FT_Error error = FT_Set_Pixel_Sizes(
GetRec(), width, height);
803bool CFX_Face::CanEmbed() {
804 FT_UShort fstype = FT_Get_FSType_Flags(GetRec());
805 return (fstype & (FT_FSTYPE_RESTRICTED_LICENSE_EMBEDDING |
806 FT_FSTYPE_BITMAP_EMBEDDING_ONLY)) == 0;
811 : m_pRec(rec), m_pDesc(std::move(pDesc)) {
817void CFX_Face::AdjustVariationParams(
int glyph_index,
824 if (!variation_desc) {
830 coords[0] = variation_desc.GetAxisDefault(0) / 65536;
835 if (dest_width == 0) {
836 coords[1] = variation_desc.GetAxisDefault(1) / 65536;
838 FT_Long min_param = variation_desc.GetAxisMin(1) / 65536;
839 FT_Long max_param = variation_desc.GetAxisMax(1) / 65536;
840 coords[1] = min_param;
841 FT_Set_MM_Design_Coordinates(rec, 2, coords);
842 FT_Load_Glyph(rec, glyph_index,
843 FT_LOAD_NO_SCALE | FT_LOAD_IGNORE_GLOBAL_ADVANCE_WIDTH);
844 FT_Pos min_width = rec->glyph->metrics.horiAdvance * 1000 /
GetUnitsPerEm();
845 coords[1] = max_param;
846 FT_Set_MM_Design_Coordinates(rec, 2, coords);
847 FT_Load_Glyph(rec, glyph_index,
848 FT_LOAD_NO_SCALE | FT_LOAD_IGNORE_GLOBAL_ADVANCE_WIDTH);
849 FT_Pos max_width = rec->glyph->metrics.horiAdvance * 1000 /
GetUnitsPerEm();
850 if (max_width == min_width) {
853 FT_Pos param = min_param + (max_param - min_param) *
854 (dest_width - min_width) /
855 (max_width - min_width);
858 FT_Set_MM_Design_Coordinates(rec, 2, coords);
fxcrt::ByteString ByteString
ByteString GetStyleName() const
size_t GetCharMapCount() const
std::optional< std::array< uint32_t, 4 > > GetOs2UnicodeRange()
int GetCharMapEncodingIdByIndex(size_t index) const
bool IsFixedWidth() const
std::optional< std::array< uint8_t, 2 > > GetOs2Panose()
bool SelectCharMap(fxge::FontEncoding encoding)
bool HasGlyphNames() const
int16_t GetAscender() const
FX_RECT GetCharBBox(uint32_t code, int glyph_index)
FX_RECT GetGlyphBBox() 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)
ByteString GetGlyphName(uint32_t glyph_index)
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)
std::optional< std::array< uint32_t, 2 > > GetOs2CodePageRange()
int GetGlyphCount() const
void SetCharMap(CharMap map)
int16_t GetDescender() const
void SetCharMapByIndex(size_t index)
pdfium::span< uint8_t > GetData() const
int GetCharMapPlatformIdByIndex(size_t index) const
std::optional< fxge::FontEncoding > GetCurrentCharMapEncoding() const
int GetNameIndex(const char *name)
const FXFT_FaceRec * GetRec() const
CharMap GetCurrentCharMap() const
int GetCharIndex(uint32_t code)
std::vector< CharCodeAndIndex > GetCharCodesAndIndices(char32_t max_char)
ByteString GetFamilyName() const
uint16_t GetUnitsPerEm() const
size_t GetSfntTable(uint32_t table, pdfium::span< uint8_t > buffer)
bool SetPixelSize(uint32_t width, uint32_t height)
CFX_SubstFont * GetSubstFont() const
bool IsBuiltInGenericFont() const
ScopedFXFTMMVar(FXFT_FaceRec *face)
ByteString(const char *ptr)
#define UNSAFE_BUFFERS(...)
CFX_PTemplate< float > CFX_PointF
struct FT_FaceRec_ FXFT_FaceRec
#define NOTREACHED_NORETURN()
FX_RECT & operator=(const FX_RECT &that)=default
constexpr FX_RECT(int l, int t, int r, int b)