1/*
2 * Copyright 2006-2012 The Android Open Source Project
3 * Copyright 2012 Mozilla Foundation
4 *
5 * Use of this source code is governed by a BSD-style license that can be
6 * found in the LICENSE file.
7 */
8
9#ifndef SKFONTHOST_FREETYPE_COMMON_H_
10#define SKFONTHOST_FREETYPE_COMMON_H_
11
12#include "SkGlyph.h"
13#include "SkMutex.h"
14#include "SkScalerContext.h"
15#include "SkTypeface.h"
16#include "SkTypes.h"
17
18#include "SkFontMgr.h"
19
20// These are forward declared to avoid pimpl but also hide the FreeType implementation.
21typedef struct FT_LibraryRec_* FT_Library;
22typedef struct FT_FaceRec_* FT_Face;
23typedef struct FT_StreamRec_* FT_Stream;
24typedef signed long FT_Pos;
25
26
27#ifdef SK_DEBUG
28const char* SkTraceFtrGetError(int);
29#define SK_TRACEFTR(ERR, MSG, ...) \
30    SkDebugf("%s:%lu:1: error: 0x%x '%s' " MSG "\n", __FILE__, __LINE__, ERR, \
31            SkTraceFtrGetError((int)(ERR)), __VA_ARGS__)
32#else
33#define SK_TRACEFTR(ERR, ...) do { sk_ignore_unused_variable(ERR); } while (false)
34#endif
35
36
37class SkScalerContext_FreeType_Base : public SkScalerContext {
38protected:
39    // See http://freetype.sourceforge.net/freetype2/docs/reference/ft2-bitmap_handling.html#FT_Bitmap_Embolden
40    // This value was chosen by eyeballing the result in Firefox and trying to match it.
41    static const FT_Pos kBitmapEmboldenStrength = 1 << 6;
42
43    SkScalerContext_FreeType_Base(sk_sp<SkTypeface> typeface, const SkScalerContextEffects& effects,
44                                  const SkDescriptor *desc)
45        : INHERITED(std::move(typeface), effects, desc)
46    {}
47
48    void generateGlyphImage(FT_Face face, const SkGlyph& glyph, const SkMatrix& bitmapTransform);
49    void generateGlyphPath(FT_Face face, SkPath* path);
50private:
51    typedef SkScalerContext INHERITED;
52};
53
54class SkTypeface_FreeType : public SkTypeface {
55public:
56    /** For SkFontMgrs to make use of our ability to extract
57     *  name and style from a stream, using FreeType's API.
58     */
59    class Scanner : ::SkNoncopyable {
60    public:
61        Scanner();
62        ~Scanner();
63        struct AxisDefinition {
64            SkFourByteTag fTag;
65            SkFixed fMinimum;
66            SkFixed fDefault;
67            SkFixed fMaximum;
68        };
69        using AxisDefinitions = SkSTArray<4, AxisDefinition, true>;
70        bool recognizedFont(SkStreamAsset* stream, int* numFonts) const;
71        bool scanFont(SkStreamAsset* stream, int ttcIndex,
72                      SkString* name, SkFontStyle* style, bool* isFixedPitch,
73                      AxisDefinitions* axes) const;
74        static void computeAxisValues(
75            AxisDefinitions axisDefinitions,
76            const SkFontArguments::VariationPosition position,
77            SkFixed* axisValues,
78            const SkString& name);
79
80    private:
81        FT_Face openFace(SkStreamAsset* stream, int ttcIndex, FT_Stream ftStream) const;
82        FT_Library fLibrary;
83        mutable SkMutex fLibraryMutex;
84    };
85
86protected:
87    SkTypeface_FreeType(const SkFontStyle& style, bool isFixedPitch)
88        : INHERITED(style, isFixedPitch)
89    {}
90
91    virtual SkScalerContext* onCreateScalerContext(const SkScalerContextEffects&,
92                                                   const SkDescriptor*) const override;
93    void onFilterRec(SkScalerContextRec*) const override;
94    std::unique_ptr<SkAdvancedTypefaceMetrics> onGetAdvancedMetrics() const override;
95    int onGetUPEM() const override;
96    bool onGetKerningPairAdjustments(const uint16_t glyphs[], int count,
97                                     int32_t adjustments[]) const override;
98    int onCharsToGlyphs(const void* chars, Encoding, uint16_t glyphs[],
99                        int glyphCount) const override;
100    int onCountGlyphs() const override;
101
102    LocalizedStrings* onCreateFamilyNameIterator() const override;
103
104    int onGetVariationDesignPosition(SkFontArguments::VariationPosition::Coordinate coordinates[],
105                                     int coordinateCount) const override;
106    int onGetTableTags(SkFontTableTag tags[]) const override;
107    size_t onGetTableData(SkFontTableTag, size_t offset,
108                          size_t length, void* data) const override;
109
110private:
111    typedef SkTypeface INHERITED;
112};
113
114#endif // SKFONTHOST_FREETYPE_COMMON_H_
115