Flutter Engine
The Flutter Engine
Loading...
Searching...
No Matches
Classes | Macros | Typedefs | Enumerations | Functions
SkFontMgr_fontconfig.cpp File Reference
#include "include/core/SkDataTable.h"
#include "include/core/SkFontArguments.h"
#include "include/core/SkFontMgr.h"
#include "include/core/SkFontStyle.h"
#include "include/core/SkMatrix.h"
#include "include/core/SkRefCnt.h"
#include "include/core/SkScalar.h"
#include "include/core/SkStream.h"
#include "include/core/SkString.h"
#include "include/core/SkTypeface.h"
#include "include/core/SkTypes.h"
#include "include/private/base/SkDebug.h"
#include "include/private/base/SkMutex.h"
#include "include/private/base/SkTArray.h"
#include "include/private/base/SkTDArray.h"
#include "include/private/base/SkTemplates.h"
#include "include/private/base/SkThreadAnnotations.h"
#include "src/base/SkTSort.h"
#include "src/core/SkAdvancedTypefaceMetrics.h"
#include "src/core/SkFontDescriptor.h"
#include "src/core/SkOSFile.h"
#include "src/core/SkScalerContext.h"
#include "src/core/SkTypefaceCache.h"
#include "src/ports/SkTypeface_FreeType.h"
#include <fontconfig/fontconfig.h>
#include <string.h>
#include <array>
#include <cstddef>
#include <cstdint>
#include <memory>
#include <utility>

Go to the source code of this file.

Classes

class  SkAutoFc< T, C, D >
 
struct  MapRanges
 
class  SkTypeface_fontconfig
 
class  SkFontMgr_fontconfig
 

Macros

#define FC_POSTSCRIPT_NAME   "postscriptname"
 
#define FC_WEIGHT_DEMILIGHT   65
 

Typedefs

typedef SkAutoFc< FcCharSet, FcCharSetCreate, FcCharSetDestroy > SkAutoFcCharSet
 
typedef SkAutoFc< FcConfig, FcConfigCreate, FcConfigDestroy > SkAutoFcConfig
 
typedef SkAutoFc< FcFontSet, FcFontSetCreate, FcFontSetDestroy > SkAutoFcFontSet
 
typedef SkAutoFc< FcLangSet, FcLangSetCreate, FcLangSetDestroy > SkAutoFcLangSet
 
typedef SkAutoFc< FcObjectSet, FcObjectSetCreate, FcObjectSetDestroy > SkAutoFcObjectSet
 
typedef SkAutoFc< FcPattern, FcPatternCreate, FcPatternDestroy > SkAutoFcPattern
 

Enumerations

enum  SkWeakReturn { kIsWeak_WeakReturn , kIsStrong_WeakReturn , kNoId_WeakReturn }
 

Functions

template<typename T , void(*)(T *) D>
void FcTDestroy (T *t)
 
static bool get_bool (FcPattern *pattern, const char object[], bool missing=false)
 
static int get_int (FcPattern *pattern, const char object[], int missing)
 
static const char * get_string (FcPattern *pattern, const char object[], const char *missing="")
 
static const FcMatrix * get_matrix (FcPattern *pattern, const char object[])
 
static SkWeakReturn is_weak (FcPattern *pattern, const char object[], int id)
 
static void remove_weak (FcPattern *pattern, const char object[])
 
static int map_range (SkScalar value, SkScalar old_min, SkScalar old_max, SkScalar new_min, SkScalar new_max)
 
static SkScalar map_ranges (SkScalar val, MapRanges const ranges[], int rangesCount)
 
static SkFontStyle skfontstyle_from_fcpattern (FcPattern *pattern)
 
static void fcpattern_from_skfontstyle (SkFontStyle style, FcPattern *pattern)
 
sk_sp< SkFontMgrSkFontMgr_New_FontConfig (FcConfig *fc)
 

Macro Definition Documentation

◆ FC_POSTSCRIPT_NAME

#define FC_POSTSCRIPT_NAME   "postscriptname"

Definition at line 52 of file SkFontMgr_fontconfig.cpp.

◆ FC_WEIGHT_DEMILIGHT

#define FC_WEIGHT_DEMILIGHT   65

Definition at line 316 of file SkFontMgr_fontconfig.cpp.

Typedef Documentation

◆ SkAutoFcCharSet

typedef SkAutoFc<FcCharSet, FcCharSetCreate, FcCharSetDestroy> SkAutoFcCharSet

Definition at line 128 of file SkFontMgr_fontconfig.cpp.

◆ SkAutoFcConfig

typedef SkAutoFc<FcConfig, FcConfigCreate, FcConfigDestroy> SkAutoFcConfig

Definition at line 129 of file SkFontMgr_fontconfig.cpp.

◆ SkAutoFcFontSet

typedef SkAutoFc<FcFontSet, FcFontSetCreate, FcFontSetDestroy> SkAutoFcFontSet

Definition at line 130 of file SkFontMgr_fontconfig.cpp.

◆ SkAutoFcLangSet

typedef SkAutoFc<FcLangSet, FcLangSetCreate, FcLangSetDestroy> SkAutoFcLangSet

Definition at line 131 of file SkFontMgr_fontconfig.cpp.

◆ SkAutoFcObjectSet

typedef SkAutoFc<FcObjectSet, FcObjectSetCreate, FcObjectSetDestroy> SkAutoFcObjectSet

Definition at line 132 of file SkFontMgr_fontconfig.cpp.

◆ SkAutoFcPattern

typedef SkAutoFc<FcPattern, FcPatternCreate, FcPatternDestroy> SkAutoFcPattern

Definition at line 133 of file SkFontMgr_fontconfig.cpp.

Enumeration Type Documentation

◆ SkWeakReturn

Enumerator
kIsWeak_WeakReturn 
kIsStrong_WeakReturn 
kNoId_WeakReturn 

Definition at line 167 of file SkFontMgr_fontconfig.cpp.

Function Documentation

◆ fcpattern_from_skfontstyle()

static void fcpattern_from_skfontstyle ( SkFontStyle  style,
FcPattern *  pattern 
)
static

Definition at line 365 of file SkFontMgr_fontconfig.cpp.

365 {
366 FCLocker::AssertHeld();
367
368 typedef SkFontStyle SkFS;
369
370 // FcWeightFromOpenType was buggy until 2.12.4
371 static constexpr MapRanges weightRanges[] = {
372 { SkFS::kThin_Weight, FC_WEIGHT_THIN },
373 { SkFS::kExtraLight_Weight, FC_WEIGHT_EXTRALIGHT },
374 { SkFS::kLight_Weight, FC_WEIGHT_LIGHT },
375 { 350, FC_WEIGHT_DEMILIGHT },
376 { 380, FC_WEIGHT_BOOK },
377 { SkFS::kNormal_Weight, FC_WEIGHT_REGULAR },
378 { SkFS::kMedium_Weight, FC_WEIGHT_MEDIUM },
379 { SkFS::kSemiBold_Weight, FC_WEIGHT_DEMIBOLD },
380 { SkFS::kBold_Weight, FC_WEIGHT_BOLD },
381 { SkFS::kExtraBold_Weight, FC_WEIGHT_EXTRABOLD },
382 { SkFS::kBlack_Weight, FC_WEIGHT_BLACK },
383 { SkFS::kExtraBlack_Weight, FC_WEIGHT_EXTRABLACK },
384 };
385 int weight = map_ranges(style.weight(), weightRanges, std::size(weightRanges));
386
387 static constexpr MapRanges widthRanges[] = {
388 { SkFS::kUltraCondensed_Width, FC_WIDTH_ULTRACONDENSED },
389 { SkFS::kExtraCondensed_Width, FC_WIDTH_EXTRACONDENSED },
390 { SkFS::kCondensed_Width, FC_WIDTH_CONDENSED },
391 { SkFS::kSemiCondensed_Width, FC_WIDTH_SEMICONDENSED },
392 { SkFS::kNormal_Width, FC_WIDTH_NORMAL },
393 { SkFS::kSemiExpanded_Width, FC_WIDTH_SEMIEXPANDED },
394 { SkFS::kExpanded_Width, FC_WIDTH_EXPANDED },
395 { SkFS::kExtraExpanded_Width, FC_WIDTH_EXTRAEXPANDED },
396 { SkFS::kUltraExpanded_Width, FC_WIDTH_ULTRAEXPANDED },
397 };
398 int width = map_ranges(style.width(), widthRanges, std::size(widthRanges));
399
400 int slant = FC_SLANT_ROMAN;
401 switch (style.slant()) {
402 case SkFS::kUpright_Slant: slant = FC_SLANT_ROMAN ; break;
403 case SkFS::kItalic_Slant : slant = FC_SLANT_ITALIC ; break;
404 case SkFS::kOblique_Slant: slant = FC_SLANT_OBLIQUE; break;
405 default: SkASSERT(false); break;
406 }
407
408 FcPatternAddInteger(pattern, FC_WEIGHT, weight);
409 FcPatternAddInteger(pattern, FC_WIDTH , width);
410 FcPatternAddInteger(pattern, FC_SLANT , slant);
411}
#define SkASSERT(cond)
Definition SkAssert.h:116
#define FC_WEIGHT_DEMILIGHT
static SkScalar map_ranges(SkScalar val, MapRanges const ranges[], int rangesCount)
Slant slant() const
Definition SkFontStyle.h:64
int width() const
Definition SkFontStyle.h:63
int weight() const
Definition SkFontStyle.h:62
int32_t width

◆ FcTDestroy()

template<typename T , void(*)(T *) D>
void FcTDestroy ( T t)

Definition at line 111 of file SkFontMgr_fontconfig.cpp.

111 {
112 FCLocker::AssertHeld();
113 D(t);
114}

◆ get_bool()

static bool get_bool ( FcPattern *  pattern,
const char  object[],
bool  missing = false 
)
static

Definition at line 135 of file SkFontMgr_fontconfig.cpp.

135 {
136 FcBool value;
137 if (FcPatternGetBool(pattern, object, 0, &value) != FcResultMatch) {
138 return missing;
139 }
140 return value;
141}
uint8_t value

◆ get_int()

static int get_int ( FcPattern *  pattern,
const char  object[],
int  missing 
)
static

Definition at line 143 of file SkFontMgr_fontconfig.cpp.

143 {
144 int value;
145 if (FcPatternGetInteger(pattern, object, 0, &value) != FcResultMatch) {
146 return missing;
147 }
148 return value;
149}

◆ get_matrix()

static const FcMatrix * get_matrix ( FcPattern *  pattern,
const char  object[] 
)
static

Definition at line 159 of file SkFontMgr_fontconfig.cpp.

159 {
160 FcMatrix* matrix;
161 if (FcPatternGetMatrix(pattern, object, 0, &matrix) != FcResultMatch) {
162 return nullptr;
163 }
164 return matrix;
165}
unsigned useCenter Optional< SkMatrix > matrix
Definition SkRecords.h:258

◆ get_string()

static const char * get_string ( FcPattern *  pattern,
const char  object[],
const char *  missing = "" 
)
static

Definition at line 151 of file SkFontMgr_fontconfig.cpp.

151 {
152 FcChar8* value;
153 if (FcPatternGetString(pattern, object, 0, &value) != FcResultMatch) {
154 return missing;
155 }
156 return (const char*)value;
157}

◆ is_weak()

static SkWeakReturn is_weak ( FcPattern *  pattern,
const char  object[],
int  id 
)
static

Ideally there would exist a call like FcResult FcPatternIsWeak(pattern, object, id, FcBool* isWeak); Sometime after 2.12.4 FcPatternGetWithBinding was added which can retrieve the binding.

However, there is no such call and as of Fc 2.11.0 even FcPatternEquals ignores the weak bit. Currently, the only reliable way of finding the weak bit is by its effect on matching. The weak bit only affects the matching of FC_FAMILY and FC_POSTSCRIPT_NAME object values. A element with the weak bit is scored after FC_LANG, without the weak bit is scored before. Note that the weak bit is stored on the element, not on the value it holds.

Definition at line 182 of file SkFontMgr_fontconfig.cpp.

182 {
183 FCLocker::AssertHeld();
184
185 FcResult result;
186
187 // Create a copy of the pattern with only the value 'pattern'['object'['id']] in it.
188 // Internally, FontConfig pattern objects are linked lists, so faster to remove from head.
189 SkAutoFcObjectSet requestedObjectOnly(FcObjectSetBuild(object, nullptr));
190 SkAutoFcPattern minimal(FcPatternFilter(pattern, requestedObjectOnly));
191 FcBool hasId = true;
192 for (int i = 0; hasId && i < id; ++i) {
193 hasId = FcPatternRemove(minimal, object, 0);
194 }
195 if (!hasId) {
196 return kNoId_WeakReturn;
197 }
198 FcValue value;
199 result = FcPatternGet(minimal, object, 0, &value);
200 if (result != FcResultMatch) {
201 return kNoId_WeakReturn;
202 }
203 while (hasId) {
204 hasId = FcPatternRemove(minimal, object, 1);
205 }
206
207 // Create a font set with two patterns.
208 // 1. the same 'object' as minimal and a lang object with only 'nomatchlang'.
209 // 2. a different 'object' from minimal and a lang object with only 'matchlang'.
210 SkAutoFcFontSet fontSet;
211
212 SkAutoFcLangSet strongLangSet;
213 FcLangSetAdd(strongLangSet, (const FcChar8*)"nomatchlang");
214 SkAutoFcPattern strong(FcPatternDuplicate(minimal));
215 FcPatternAddLangSet(strong, FC_LANG, strongLangSet);
216
217 SkAutoFcLangSet weakLangSet;
218 FcLangSetAdd(weakLangSet, (const FcChar8*)"matchlang");
219 SkAutoFcPattern weak;
220 FcPatternAddString(weak, object, (const FcChar8*)"nomatchstring");
221 FcPatternAddLangSet(weak, FC_LANG, weakLangSet);
222
223 FcFontSetAdd(fontSet, strong.release());
224 FcFontSetAdd(fontSet, weak.release());
225
226 // Add 'matchlang' to the copy of the pattern.
227 FcPatternAddLangSet(minimal, FC_LANG, weakLangSet);
228
229 // Run a match against the copy of the pattern.
230 // If the 'id' was weak, then we should match the pattern with 'matchlang'.
231 // If the 'id' was strong, then we should match the pattern with 'nomatchlang'.
232
233 // Note that this config is only used for FcFontRenderPrepare, which we don't even want.
234 // However, there appears to be no way to match/sort without it.
235 SkAutoFcConfig config;
236 FcFontSet* fontSets[1] = { fontSet };
237 SkAutoFcPattern match(FcFontSetMatch(config, fontSets, std::size(fontSets),
238 minimal, &result));
239
240 FcLangSet* matchLangSet;
241 FcPatternGetLangSet(match, FC_LANG, 0, &matchLangSet);
242 return FcLangEqual == FcLangSetHasLang(matchLangSet, (const FcChar8*)"matchlang")
244}
static bool match(const char *needle, const char *haystack)
Definition DM.cpp:1132
GAsyncResult * result
const uintptr_t id

◆ map_range()

static int map_range ( SkScalar  value,
SkScalar  old_min,
SkScalar  old_max,
SkScalar  new_min,
SkScalar  new_max 
)
static

Definition at line 282 of file SkFontMgr_fontconfig.cpp.

285{
286 SkASSERT(old_min < old_max);
287 SkASSERT(new_min <= new_max);
288 return new_min + ((value - old_min) * (new_max - new_min) / (old_max - old_min));
289}

◆ map_ranges()

static SkScalar map_ranges ( SkScalar  val,
MapRanges const  ranges[],
int  rangesCount 
)
static

Definition at line 296 of file SkFontMgr_fontconfig.cpp.

296 {
297 // -Inf to [0]
298 if (val < ranges[0].old_val) {
299 return ranges[0].new_val;
300 }
301
302 // Linear from [i] to [i+1]
303 for (int i = 0; i < rangesCount - 1; ++i) {
304 if (val < ranges[i+1].old_val) {
305 return map_range(val, ranges[i].old_val, ranges[i+1].old_val,
306 ranges[i].new_val, ranges[i+1].new_val);
307 }
308 }
309
310 // From [n] to +Inf
311 // if (fcweight < Inf)
312 return ranges[rangesCount-1].new_val;
313}
static int map_range(SkScalar value, SkScalar old_min, SkScalar old_max, SkScalar new_min, SkScalar new_max)

◆ remove_weak()

static void remove_weak ( FcPattern *  pattern,
const char  object[] 
)
static

Removes weak elements from either FC_FAMILY or FC_POSTSCRIPT_NAME objects in the property. This can be quite expensive, and should not be used more than once per font lookup. This removes all of the weak elements after the last strong element.

Definition at line 250 of file SkFontMgr_fontconfig.cpp.

250 {
251 FCLocker::AssertHeld();
252
253 SkAutoFcObjectSet requestedObjectOnly(FcObjectSetBuild(object, nullptr));
254 SkAutoFcPattern minimal(FcPatternFilter(pattern, requestedObjectOnly));
255
256 int lastStrongId = -1;
257 int numIds;
259 for (int id = 0; ; ++id) {
260 result = is_weak(minimal, object, 0);
261 if (kNoId_WeakReturn == result) {
262 numIds = id;
263 break;
264 }
266 lastStrongId = id;
267 }
268 SkAssertResult(FcPatternRemove(minimal, object, 0));
269 }
270
271 // If they were all weak, then leave the pattern alone.
272 if (lastStrongId < 0) {
273 return;
274 }
275
276 // Remove everything after the last strong.
277 for (int id = lastStrongId + 1; id < numIds; ++id) {
278 SkAssertResult(FcPatternRemove(pattern, object, lastStrongId + 1));
279 }
280}
#define SkAssertResult(cond)
Definition SkAssert.h:123
static SkWeakReturn is_weak(FcPattern *pattern, const char object[], int id)

◆ SkFontMgr_New_FontConfig()

sk_sp< SkFontMgr > SkFontMgr_New_FontConfig ( FcConfig *  fc)

Create a font manager around a FontConfig instance. If 'fc' is NULL, will use a new default config. Takes ownership of 'fc' and will call FcConfigDestroy on it.

Definition at line 970 of file SkFontMgr_fontconfig.cpp.

970 {
971 return sk_make_sp<SkFontMgr_fontconfig>(fc);
972}

◆ skfontstyle_from_fcpattern()

static SkFontStyle skfontstyle_from_fcpattern ( FcPattern *  pattern)
static

Definition at line 319 of file SkFontMgr_fontconfig.cpp.

319 {
320 typedef SkFontStyle SkFS;
321
322 // FcWeightToOpenType was buggy until 2.12.4
323 static constexpr MapRanges weightRanges[] = {
324 { FC_WEIGHT_THIN, SkFS::kThin_Weight },
325 { FC_WEIGHT_EXTRALIGHT, SkFS::kExtraLight_Weight },
326 { FC_WEIGHT_LIGHT, SkFS::kLight_Weight },
327 { FC_WEIGHT_DEMILIGHT, 350 },
328 { FC_WEIGHT_BOOK, 380 },
329 { FC_WEIGHT_REGULAR, SkFS::kNormal_Weight },
330 { FC_WEIGHT_MEDIUM, SkFS::kMedium_Weight },
331 { FC_WEIGHT_DEMIBOLD, SkFS::kSemiBold_Weight },
332 { FC_WEIGHT_BOLD, SkFS::kBold_Weight },
333 { FC_WEIGHT_EXTRABOLD, SkFS::kExtraBold_Weight },
334 { FC_WEIGHT_BLACK, SkFS::kBlack_Weight },
335 { FC_WEIGHT_EXTRABLACK, SkFS::kExtraBlack_Weight },
336 };
337 SkScalar weight = map_ranges(get_int(pattern, FC_WEIGHT, FC_WEIGHT_REGULAR),
338 weightRanges, std::size(weightRanges));
339
340 static constexpr MapRanges widthRanges[] = {
341 { FC_WIDTH_ULTRACONDENSED, SkFS::kUltraCondensed_Width },
342 { FC_WIDTH_EXTRACONDENSED, SkFS::kExtraCondensed_Width },
343 { FC_WIDTH_CONDENSED, SkFS::kCondensed_Width },
344 { FC_WIDTH_SEMICONDENSED, SkFS::kSemiCondensed_Width },
345 { FC_WIDTH_NORMAL, SkFS::kNormal_Width },
346 { FC_WIDTH_SEMIEXPANDED, SkFS::kSemiExpanded_Width },
347 { FC_WIDTH_EXPANDED, SkFS::kExpanded_Width },
348 { FC_WIDTH_EXTRAEXPANDED, SkFS::kExtraExpanded_Width },
349 { FC_WIDTH_ULTRAEXPANDED, SkFS::kUltraExpanded_Width },
350 };
351 SkScalar width = map_ranges(get_int(pattern, FC_WIDTH, FC_WIDTH_NORMAL),
352 widthRanges, std::size(widthRanges));
353
354 SkFS::Slant slant = SkFS::kUpright_Slant;
355 switch (get_int(pattern, FC_SLANT, FC_SLANT_ROMAN)) {
356 case FC_SLANT_ROMAN: slant = SkFS::kUpright_Slant; break;
357 case FC_SLANT_ITALIC : slant = SkFS::kItalic_Slant ; break;
358 case FC_SLANT_OBLIQUE: slant = SkFS::kOblique_Slant; break;
359 default: SkASSERT(false); break;
360 }
361
363}
static int get_int(FcPattern *pattern, const char object[], int missing)
#define SkScalarRoundToInt(x)
Definition SkScalar.h:37
float SkScalar
Definition extension.cpp:12