1 /* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*-
2 * This Source Code Form is subject to the terms of the Mozilla Public
3 * License, v. 2.0. If a copy of the MPL was not distributed with this
4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6 #include "gfxFT2FontBase.h"
7 #include "gfxFT2Utils.h"
8 #include "mozilla/Likely.h"
10 #ifdef USE_FC_FREETYPE
11 # include <fontconfig/fcfreetype.h>
15 #include FT_MULTIPLE_MASTERS_H
19 uint32_t gfxFT2LockedFace::GetGlyph(uint32_t aCharCode
) {
20 if (MOZ_UNLIKELY(!mFace
)) return 0;
22 #ifdef USE_FC_FREETYPE
23 // FcFreeTypeCharIndex will search starting from the most recently
24 // selected charmap. This can cause non-determistic behavior when more
25 // than one charmap supports a character but with different glyphs, as
26 // with older versions of MS Gothic, for example. Always prefer a Unicode
27 // charmap, if there is one; failing that, try MS_SYMBOL.
28 // (FcFreeTypeCharIndex usually does the appropriate Unicode conversion,
29 // but some fonts have non-Roman glyphs for FT_ENCODING_APPLE_ROMAN
31 if (!mFace
->charmap
|| (mFace
->charmap
->encoding
!= FT_ENCODING_UNICODE
&&
32 mFace
->charmap
->encoding
!= FT_ENCODING_MS_SYMBOL
)) {
33 if (FT_Err_Ok
!= FT_Select_Charmap(mFace
, FT_ENCODING_UNICODE
) &&
34 FT_Err_Ok
!= FT_Select_Charmap(mFace
, FT_ENCODING_MS_SYMBOL
)) {
35 NS_WARNING("failed to select Unicode or symbol charmap");
39 uint32_t gid
= FcFreeTypeCharIndex(mFace
, aCharCode
);
41 uint32_t gid
= FT_Get_Char_Index(mFace
, aCharCode
);
43 if (!gid
&& mFace
->charmap
&&
44 mFace
->charmap
->encoding
== FT_ENCODING_MS_SYMBOL
) {
45 if (auto pua
= gfxFontUtils::MapLegacySymbolFontCharToPUA(aCharCode
)) {
46 gid
= FT_Get_Char_Index(mFace
, pua
);
52 typedef FT_UInt (*GetCharVariantFunction
)(FT_Face face
, FT_ULong charcode
,
53 FT_ULong variantSelector
);
55 uint32_t gfxFT2LockedFace::GetUVSGlyph(uint32_t aCharCode
,
56 uint32_t aVariantSelector
) {
57 MOZ_ASSERT(aVariantSelector
, "aVariantSelector should not be NULL");
59 if (MOZ_UNLIKELY(!mFace
)) return 0;
61 // This function is available from FreeType 2.3.6 (June 2008).
62 static CharVariantFunction sGetCharVariantPtr
= FindCharVariantFunction();
63 if (!sGetCharVariantPtr
) return 0;
65 #ifdef USE_FC_FREETYPE
66 // FcFreeTypeCharIndex may have changed the selected charmap.
67 // FT_Face_GetCharVariantIndex needs a unicode charmap.
68 if (!mFace
->charmap
|| mFace
->charmap
->encoding
!= FT_ENCODING_UNICODE
) {
69 FT_Select_Charmap(mFace
, FT_ENCODING_UNICODE
);
73 return (*sGetCharVariantPtr
)(mFace
, aCharCode
, aVariantSelector
);
76 gfxFT2LockedFace::CharVariantFunction
77 gfxFT2LockedFace::FindCharVariantFunction() {
78 // This function is available from FreeType 2.3.6 (June 2008).
79 PRLibrary
* lib
= nullptr;
80 CharVariantFunction function
= reinterpret_cast<CharVariantFunction
>(
81 PR_FindFunctionSymbolAndLibrary("FT_Face_GetCharVariantIndex", &lib
));
89 FT_Library_Version(mFace
->glyph
->library
, &major
, &minor
, &patch
);
91 // Versions 2.4.0 to 2.4.3 crash if configured with
92 // FT_CONFIG_OPTION_OLD_INTERNALS. Presence of the symbol FT_Alloc
93 // indicates FT_CONFIG_OPTION_OLD_INTERNALS.
94 if (major
== 2 && minor
== 4 && patch
< 4 &&
95 PR_FindFunctionSymbol(lib
, "FT_Alloc")) {
99 // Decrement the reference count incremented in
100 // PR_FindFunctionSymbolAndLibrary.
101 PR_UnloadLibrary(lib
);
107 void gfxFT2Utils::GetVariationAxes(const FT_MM_Var
* aMMVar
,
108 nsTArray
<gfxFontVariationAxis
>& aAxes
) {
109 MOZ_ASSERT(aAxes
.IsEmpty());
113 aAxes
.SetCapacity(aMMVar
->num_axis
);
114 for (unsigned i
= 0; i
< aMMVar
->num_axis
; i
++) {
115 const auto& a
= aMMVar
->axis
[i
];
116 gfxFontVariationAxis axis
;
117 axis
.mMinValue
= a
.minimum
/ 65536.0;
118 axis
.mMaxValue
= a
.maximum
/ 65536.0;
119 axis
.mDefaultValue
= a
.def
/ 65536.0;
122 aAxes
.AppendElement(axis
);
127 void gfxFT2Utils::GetVariationInstances(
128 gfxFontEntry
* aFontEntry
, const FT_MM_Var
* aMMVar
,
129 nsTArray
<gfxFontVariationInstance
>& aInstances
) {
130 MOZ_ASSERT(aInstances
.IsEmpty());
134 gfxFontUtils::AutoHBBlob
nameTable(
135 aFontEntry
->GetFontTable(TRUETYPE_TAG('n', 'a', 'm', 'e')));
139 aInstances
.SetCapacity(aMMVar
->num_namedstyles
);
140 for (unsigned i
= 0; i
< aMMVar
->num_namedstyles
; i
++) {
141 const auto& ns
= aMMVar
->namedstyle
[i
];
142 gfxFontVariationInstance inst
;
144 gfxFontUtils::ReadCanonicalName(nameTable
, ns
.strid
, inst
.mName
);
148 inst
.mValues
.SetCapacity(aMMVar
->num_axis
);
149 for (unsigned j
= 0; j
< aMMVar
->num_axis
; j
++) {
150 gfxFontVariationValue value
;
151 value
.mAxis
= aMMVar
->axis
[j
].tag
;
152 value
.mValue
= ns
.coords
[j
] / 65536.0;
153 inst
.mValues
.AppendElement(value
);
155 aInstances
.AppendElement(inst
);