Bug 1728955: part 6) Log result of Windows' `OleSetClipboardResult`. r=masayuki
[gecko.git] / gfx / thebes / gfxFT2Utils.cpp
bloba4b193ae881a4a6e425b3bb5f37f0453ac107953
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 HAVE_FONTCONFIG_FCFREETYPE_H
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 HAVE_FONTCONFIG_FCFREETYPE_H
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 return FcFreeTypeCharIndex(mFace, aCharCode);
40 #else
41 return FT_Get_Char_Index(mFace, aCharCode);
42 #endif
45 typedef FT_UInt (*GetCharVariantFunction)(FT_Face face, FT_ULong charcode,
46 FT_ULong variantSelector);
48 uint32_t gfxFT2LockedFace::GetUVSGlyph(uint32_t aCharCode,
49 uint32_t aVariantSelector) {
50 MOZ_ASSERT(aVariantSelector, "aVariantSelector should not be NULL");
52 if (MOZ_UNLIKELY(!mFace)) return 0;
54 // This function is available from FreeType 2.3.6 (June 2008).
55 static CharVariantFunction sGetCharVariantPtr = FindCharVariantFunction();
56 if (!sGetCharVariantPtr) return 0;
58 #ifdef HAVE_FONTCONFIG_FCFREETYPE_H
59 // FcFreeTypeCharIndex may have changed the selected charmap.
60 // FT_Face_GetCharVariantIndex needs a unicode charmap.
61 if (!mFace->charmap || mFace->charmap->encoding != FT_ENCODING_UNICODE) {
62 FT_Select_Charmap(mFace, FT_ENCODING_UNICODE);
64 #endif
66 return (*sGetCharVariantPtr)(mFace, aCharCode, aVariantSelector);
69 gfxFT2LockedFace::CharVariantFunction
70 gfxFT2LockedFace::FindCharVariantFunction() {
71 // This function is available from FreeType 2.3.6 (June 2008).
72 PRLibrary* lib = nullptr;
73 CharVariantFunction function = reinterpret_cast<CharVariantFunction>(
74 PR_FindFunctionSymbolAndLibrary("FT_Face_GetCharVariantIndex", &lib));
75 if (!lib) {
76 return nullptr;
79 FT_Int major;
80 FT_Int minor;
81 FT_Int patch;
82 FT_Library_Version(mFace->glyph->library, &major, &minor, &patch);
84 // Versions 2.4.0 to 2.4.3 crash if configured with
85 // FT_CONFIG_OPTION_OLD_INTERNALS. Presence of the symbol FT_Alloc
86 // indicates FT_CONFIG_OPTION_OLD_INTERNALS.
87 if (major == 2 && minor == 4 && patch < 4 &&
88 PR_FindFunctionSymbol(lib, "FT_Alloc")) {
89 function = nullptr;
92 // Decrement the reference count incremented in
93 // PR_FindFunctionSymbolAndLibrary.
94 PR_UnloadLibrary(lib);
96 return function;
99 /*static*/
100 void gfxFT2Utils::GetVariationAxes(const FT_MM_Var* aMMVar,
101 nsTArray<gfxFontVariationAxis>& aAxes) {
102 MOZ_ASSERT(aAxes.IsEmpty());
103 if (!aMMVar) {
104 return;
106 aAxes.SetCapacity(aMMVar->num_axis);
107 for (unsigned i = 0; i < aMMVar->num_axis; i++) {
108 const auto& a = aMMVar->axis[i];
109 gfxFontVariationAxis axis;
110 axis.mMinValue = a.minimum / 65536.0;
111 axis.mMaxValue = a.maximum / 65536.0;
112 axis.mDefaultValue = a.def / 65536.0;
113 axis.mTag = a.tag;
114 axis.mName = a.name;
115 aAxes.AppendElement(axis);
119 /*static*/
120 void gfxFT2Utils::GetVariationInstances(
121 gfxFontEntry* aFontEntry, const FT_MM_Var* aMMVar,
122 nsTArray<gfxFontVariationInstance>& aInstances) {
123 MOZ_ASSERT(aInstances.IsEmpty());
124 if (!aMMVar) {
125 return;
127 hb_blob_t* nameTable =
128 aFontEntry->GetFontTable(TRUETYPE_TAG('n', 'a', 'm', 'e'));
129 if (!nameTable) {
130 return;
132 aInstances.SetCapacity(aMMVar->num_namedstyles);
133 for (unsigned i = 0; i < aMMVar->num_namedstyles; i++) {
134 const auto& ns = aMMVar->namedstyle[i];
135 gfxFontVariationInstance inst;
136 nsresult rv =
137 gfxFontUtils::ReadCanonicalName(nameTable, ns.strid, inst.mName);
138 if (NS_FAILED(rv)) {
139 continue;
141 inst.mValues.SetCapacity(aMMVar->num_axis);
142 for (unsigned j = 0; j < aMMVar->num_axis; j++) {
143 gfxFontVariationValue value;
144 value.mAxis = aMMVar->axis[j].tag;
145 value.mValue = ns.coords[j] / 65536.0;
146 inst.mValues.AppendElement(value);
148 aInstances.AppendElement(inst);
150 hb_blob_destroy(nameTable);