/src/mozilla-central/gfx/thebes/gfxFT2Utils.cpp
Line | Count | Source (jump to first uncovered line) |
1 | | /* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 4 -*- |
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/. */ |
5 | | |
6 | | #include "gfxFT2FontBase.h" |
7 | | #include "gfxFT2Utils.h" |
8 | | #include "mozilla/Likely.h" |
9 | | |
10 | | #ifdef HAVE_FONTCONFIG_FCFREETYPE_H |
11 | | #include <fontconfig/fcfreetype.h> |
12 | | #endif |
13 | | |
14 | | #include "ft2build.h" |
15 | | #include FT_MULTIPLE_MASTERS_H |
16 | | |
17 | | #include "prlink.h" |
18 | | |
19 | | uint32_t |
20 | | gfxFT2LockedFace::GetGlyph(uint32_t aCharCode) |
21 | 0 | { |
22 | 0 | if (MOZ_UNLIKELY(!mFace)) |
23 | 0 | return 0; |
24 | 0 | |
25 | 0 | #ifdef HAVE_FONTCONFIG_FCFREETYPE_H |
26 | 0 | // FcFreeTypeCharIndex will search starting from the most recently |
27 | 0 | // selected charmap. This can cause non-determistic behavior when more |
28 | 0 | // than one charmap supports a character but with different glyphs, as |
29 | 0 | // with older versions of MS Gothic, for example. Always prefer a Unicode |
30 | 0 | // charmap, if there is one. (FcFreeTypeCharIndex usually does the |
31 | 0 | // appropriate Unicode conversion, but some fonts have non-Roman glyphs |
32 | 0 | // for FT_ENCODING_APPLE_ROMAN characters.) |
33 | 0 | if (!mFace->charmap || mFace->charmap->encoding != FT_ENCODING_UNICODE) { |
34 | 0 | FT_Select_Charmap(mFace, FT_ENCODING_UNICODE); |
35 | 0 | } |
36 | 0 |
|
37 | 0 | return FcFreeTypeCharIndex(mFace, aCharCode); |
38 | | #else |
39 | | return FT_Get_Char_Index(mFace, aCharCode); |
40 | | #endif |
41 | | } |
42 | | |
43 | | typedef FT_UInt (*GetCharVariantFunction)(FT_Face face, |
44 | | FT_ULong charcode, |
45 | | FT_ULong variantSelector); |
46 | | |
47 | | uint32_t |
48 | | gfxFT2LockedFace::GetUVSGlyph(uint32_t aCharCode, uint32_t aVariantSelector) |
49 | 0 | { |
50 | 0 | MOZ_ASSERT(aVariantSelector, "aVariantSelector should not be NULL"); |
51 | 0 |
|
52 | 0 | if (MOZ_UNLIKELY(!mFace)) |
53 | 0 | return 0; |
54 | 0 | |
55 | 0 | // This function is available from FreeType 2.3.6 (June 2008). |
56 | 0 | static CharVariantFunction sGetCharVariantPtr = FindCharVariantFunction(); |
57 | 0 | if (!sGetCharVariantPtr) |
58 | 0 | return 0; |
59 | 0 | |
60 | 0 | #ifdef HAVE_FONTCONFIG_FCFREETYPE_H |
61 | 0 | // FcFreeTypeCharIndex may have changed the selected charmap. |
62 | 0 | // FT_Face_GetCharVariantIndex needs a unicode charmap. |
63 | 0 | if (!mFace->charmap || mFace->charmap->encoding != FT_ENCODING_UNICODE) { |
64 | 0 | FT_Select_Charmap(mFace, FT_ENCODING_UNICODE); |
65 | 0 | } |
66 | 0 | #endif |
67 | 0 |
|
68 | 0 | return (*sGetCharVariantPtr)(mFace, aCharCode, aVariantSelector); |
69 | 0 | } |
70 | | |
71 | | gfxFT2LockedFace::CharVariantFunction |
72 | | gfxFT2LockedFace::FindCharVariantFunction() |
73 | 0 | { |
74 | 0 | // This function is available from FreeType 2.3.6 (June 2008). |
75 | 0 | PRLibrary *lib = nullptr; |
76 | 0 | CharVariantFunction function = |
77 | 0 | reinterpret_cast<CharVariantFunction> |
78 | 0 | (PR_FindFunctionSymbolAndLibrary("FT_Face_GetCharVariantIndex", &lib)); |
79 | 0 | if (!lib) { |
80 | 0 | return nullptr; |
81 | 0 | } |
82 | 0 | |
83 | 0 | FT_Int major; |
84 | 0 | FT_Int minor; |
85 | 0 | FT_Int patch; |
86 | 0 | FT_Library_Version(mFace->glyph->library, &major, &minor, &patch); |
87 | 0 |
|
88 | 0 | // Versions 2.4.0 to 2.4.3 crash if configured with |
89 | 0 | // FT_CONFIG_OPTION_OLD_INTERNALS. Presence of the symbol FT_Alloc |
90 | 0 | // indicates FT_CONFIG_OPTION_OLD_INTERNALS. |
91 | 0 | if (major == 2 && minor == 4 && patch < 4 && |
92 | 0 | PR_FindFunctionSymbol(lib, "FT_Alloc")) { |
93 | 0 | function = nullptr; |
94 | 0 | } |
95 | 0 |
|
96 | 0 | // Decrement the reference count incremented in |
97 | 0 | // PR_FindFunctionSymbolAndLibrary. |
98 | 0 | PR_UnloadLibrary(lib); |
99 | 0 |
|
100 | 0 | return function; |
101 | 0 | } |
102 | | |
103 | | /*static*/ |
104 | | void |
105 | | gfxFT2Utils::GetVariationAxes(const FT_MM_Var* aMMVar, |
106 | | nsTArray<gfxFontVariationAxis>& aAxes) |
107 | 0 | { |
108 | 0 | MOZ_ASSERT(aAxes.IsEmpty()); |
109 | 0 | if (!aMMVar) { |
110 | 0 | return; |
111 | 0 | } |
112 | 0 | aAxes.SetCapacity(aMMVar->num_axis); |
113 | 0 | for (unsigned i = 0; i < aMMVar->num_axis; i++) { |
114 | 0 | const auto& a = aMMVar->axis[i]; |
115 | 0 | gfxFontVariationAxis axis; |
116 | 0 | axis.mMinValue = a.minimum / 65536.0; |
117 | 0 | axis.mMaxValue = a.maximum / 65536.0; |
118 | 0 | axis.mDefaultValue = a.def / 65536.0; |
119 | 0 | axis.mTag = a.tag; |
120 | 0 | axis.mName = a.name; |
121 | 0 | aAxes.AppendElement(axis); |
122 | 0 | } |
123 | 0 | } |
124 | | |
125 | | /*static*/ |
126 | | void |
127 | | gfxFT2Utils::GetVariationInstances( |
128 | | gfxFontEntry* aFontEntry, |
129 | | const FT_MM_Var* aMMVar, |
130 | | nsTArray<gfxFontVariationInstance>& aInstances) |
131 | 0 | { |
132 | 0 | MOZ_ASSERT(aInstances.IsEmpty()); |
133 | 0 | if (!aMMVar) { |
134 | 0 | return; |
135 | 0 | } |
136 | 0 | hb_blob_t* nameTable = |
137 | 0 | aFontEntry->GetFontTable(TRUETYPE_TAG('n','a','m','e')); |
138 | 0 | if (!nameTable) { |
139 | 0 | return; |
140 | 0 | } |
141 | 0 | aInstances.SetCapacity(aMMVar->num_namedstyles); |
142 | 0 | for (unsigned i = 0; i < aMMVar->num_namedstyles; i++) { |
143 | 0 | const auto& ns = aMMVar->namedstyle[i]; |
144 | 0 | gfxFontVariationInstance inst; |
145 | 0 | nsresult rv = |
146 | 0 | gfxFontUtils::ReadCanonicalName(nameTable, ns.strid, inst.mName); |
147 | 0 | if (NS_FAILED(rv)) { |
148 | 0 | continue; |
149 | 0 | } |
150 | 0 | inst.mValues.SetCapacity(aMMVar->num_axis); |
151 | 0 | for (unsigned j = 0; j < aMMVar->num_axis; j++) { |
152 | 0 | gfxFontVariationValue value; |
153 | 0 | value.mAxis = aMMVar->axis[j].tag; |
154 | 0 | value.mValue = ns.coords[j] / 65536.0; |
155 | 0 | inst.mValues.AppendElement(value); |
156 | 0 | } |
157 | 0 | aInstances.AppendElement(inst); |
158 | 0 | } |
159 | 0 | hb_blob_destroy(nameTable); |
160 | 0 | } |