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>
15 #include FT_MULTIPLE_MASTERS_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
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
);
41 return FT_Get_Char_Index(mFace
, aCharCode
);
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
);
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
));
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")) {
92 // Decrement the reference count incremented in
93 // PR_FindFunctionSymbolAndLibrary.
94 PR_UnloadLibrary(lib
);
100 void gfxFT2Utils::GetVariationAxes(const FT_MM_Var
* aMMVar
,
101 nsTArray
<gfxFontVariationAxis
>& aAxes
) {
102 MOZ_ASSERT(aAxes
.IsEmpty());
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;
115 aAxes
.AppendElement(axis
);
120 void gfxFT2Utils::GetVariationInstances(
121 gfxFontEntry
* aFontEntry
, const FT_MM_Var
* aMMVar
,
122 nsTArray
<gfxFontVariationInstance
>& aInstances
) {
123 MOZ_ASSERT(aInstances
.IsEmpty());
127 hb_blob_t
* nameTable
=
128 aFontEntry
->GetFontTable(TRUETYPE_TAG('n', 'a', 'm', 'e'));
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
;
137 gfxFontUtils::ReadCanonicalName(nameTable
, ns
.strid
, inst
.mName
);
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
);