Coverage Report

Created: 2018-09-25 14:53

/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
}