no bug - Bumping Firefox l10n changesets r=release a=l10n-bump DONTBUILD CLOSED TREE
[gecko.git] / gfx / thebes / gfxFT2Utils.cpp
blob94403c9dc195c385b465a5d436a16ac22d218157
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>
12 #endif
14 #include "ft2build.h"
15 #include FT_MULTIPLE_MASTERS_H
17 #include "prlink.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
30 // characters.)
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);
40 #else
41 uint32_t gid = FT_Get_Char_Index(mFace, aCharCode);
42 #endif
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);
49 return gid;
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);
71 #endif
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));
82 if (!lib) {
83 return nullptr;
86 FT_Int major;
87 FT_Int minor;
88 FT_Int patch;
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")) {
96 function = nullptr;
99 // Decrement the reference count incremented in
100 // PR_FindFunctionSymbolAndLibrary.
101 PR_UnloadLibrary(lib);
103 return function;
106 /*static*/
107 void gfxFT2Utils::GetVariationAxes(const FT_MM_Var* aMMVar,
108 nsTArray<gfxFontVariationAxis>& aAxes) {
109 MOZ_ASSERT(aAxes.IsEmpty());
110 if (!aMMVar) {
111 return;
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;
120 axis.mTag = a.tag;
121 axis.mName = a.name;
122 aAxes.AppendElement(axis);
126 /*static*/
127 void gfxFT2Utils::GetVariationInstances(
128 gfxFontEntry* aFontEntry, const FT_MM_Var* aMMVar,
129 nsTArray<gfxFontVariationInstance>& aInstances) {
130 MOZ_ASSERT(aInstances.IsEmpty());
131 if (!aMMVar) {
132 return;
134 gfxFontUtils::AutoHBBlob nameTable(
135 aFontEntry->GetFontTable(TRUETYPE_TAG('n', 'a', 'm', 'e')));
136 if (!nameTable) {
137 return;
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;
143 nsresult rv =
144 gfxFontUtils::ReadCanonicalName(nameTable, ns.strid, inst.mName);
145 if (NS_FAILED(rv)) {
146 continue;
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);