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 "include/core/SkTypeface.h"
13#include "include/core/SkTypes.h"
14#include "include/private/SkMutex.h"
15#include "src/core/SkGlyph.h"
16#include "src/core/SkScalerContext.h"
17#include "src/utils/SkCharToGlyphCache.h"
18
19#include "include/core/SkFontMgr.h"
20
21// These are forward declared to avoid pimpl but also hide the FreeType implementation.
22typedef struct FT_LibraryRec_* FT_Library;
23typedef struct FT_FaceRec_* FT_Face;
24typedef struct FT_StreamRec_* FT_Stream;
25typedef signed long FT_Pos;
26
27
28#ifdef SK_DEBUG
29const char* SkTraceFtrGetError(int);
30#define SK_TRACEFTR(ERR, MSG, ...) \
31 SkDebugf("%s:%lu:1: error: 0x%x '%s' " MSG "\n", __FILE__, __LINE__, ERR, \
32 SkTraceFtrGetError((int)(ERR)), __VA_ARGS__)
33#else
34#define SK_TRACEFTR(ERR, ...) do { sk_ignore_unused_variable(ERR); } while (false)
35#endif
36
37
38class SkScalerContext_FreeType_Base : public SkScalerContext {
39protected:
40 // See http://freetype.sourceforge.net/freetype2/docs/reference/ft2-bitmap_handling.html#FT_Bitmap_Embolden
41 // This value was chosen by eyeballing the result in Firefox and trying to match it.
42 static const FT_Pos kBitmapEmboldenStrength = 1 << 6;
43
44 SkScalerContext_FreeType_Base(sk_sp<SkTypeface> typeface, const SkScalerContextEffects& effects,
45 const SkDescriptor *desc)
46 : INHERITED(std::move(typeface), effects, desc)
47 {}
48
49 void generateGlyphImage(FT_Face face, const SkGlyph& glyph, const SkMatrix& bitmapTransform);
50 bool generateGlyphPath(FT_Face face, SkPath* path);
51 bool generateFacePath(FT_Face face, SkGlyphID glyphID, SkPath* path);
52private:
53 typedef SkScalerContext INHERITED;
54};
55
56class SkTypeface_FreeType : public SkTypeface {
57public:
58 /** For SkFontMgrs to make use of our ability to extract
59 * name and style from a stream, using FreeType's API.
60 */
61 class Scanner : ::SkNoncopyable {
62 public:
63 Scanner();
64 ~Scanner();
65 struct AxisDefinition {
66 SkFourByteTag fTag;
67 SkFixed fMinimum;
68 SkFixed fDefault;
69 SkFixed fMaximum;
70 };
71 using AxisDefinitions = SkSTArray<4, AxisDefinition, true>;
72 bool recognizedFont(SkStreamAsset* stream, int* numFonts) const;
73 bool scanFont(SkStreamAsset* stream, int ttcIndex,
74 SkString* name, SkFontStyle* style, bool* isFixedPitch,
75 AxisDefinitions* axes) const;
76 static void computeAxisValues(
77 AxisDefinitions axisDefinitions,
78 const SkFontArguments::VariationPosition position,
79 SkFixed* axisValues,
80 const SkString& name);
81 static bool GetAxes(FT_Face face, AxisDefinitions* axes);
82
83 private:
84 FT_Face openFace(SkStreamAsset* stream, int ttcIndex, FT_Stream ftStream) const;
85 FT_Library fLibrary;
86 mutable SkMutex fLibraryMutex;
87 };
88
89 /** Fetch units/EM from "head" table if needed (ie for bitmap fonts) */
90 static int GetUnitsPerEm(FT_Face face);
91protected:
92 SkTypeface_FreeType(const SkFontStyle& style, bool isFixedPitch)
93 : INHERITED(style, isFixedPitch)
94 {}
95
96 std::unique_ptr<SkFontData> cloneFontData(const SkFontArguments&) const;
97 virtual SkScalerContext* onCreateScalerContext(const SkScalerContextEffects&,
98 const SkDescriptor*) const override;
99 void onFilterRec(SkScalerContextRec*) const override;
100 void getGlyphToUnicodeMap(SkUnichar*) const override;
101 std::unique_ptr<SkAdvancedTypefaceMetrics> onGetAdvancedMetrics() const override;
102 void getPostScriptGlyphNames(SkString* dstArray) const override;
103 int onGetUPEM() const override;
104 bool onGetKerningPairAdjustments(const uint16_t glyphs[], int count,
105 int32_t adjustments[]) const override;
106 void onCharsToGlyphs(const SkUnichar uni[], int count, SkGlyphID glyphs[]) const override;
107 int onCountGlyphs() const override;
108
109 LocalizedStrings* onCreateFamilyNameIterator() const override;
110
111 int onGetVariationDesignPosition(SkFontArguments::VariationPosition::Coordinate coordinates[],
112 int coordinateCount) const override;
113 int onGetVariationDesignParameters(SkFontParameters::Variation::Axis parameters[],
114 int parameterCount) const override;
115 int onGetTableTags(SkFontTableTag tags[]) const override;
116 size_t onGetTableData(SkFontTableTag, size_t offset,
117 size_t length, void* data) const override;
118 sk_sp<SkData> onCopyTableData(SkFontTableTag) const override;
119
120private:
121 mutable SkMutex fC2GCacheMutex;
122 mutable SkCharToGlyphCache fC2GCache;
123
124 typedef SkTypeface INHERITED;
125};
126
127#endif // SKFONTHOST_FREETYPE_COMMON_H_
128