1 /*
2 * This file is part of the internal font implementation.
3 *
4 * Copyright (C) 2006, 2008, 2010 Apple Inc. All rights reserved.
5 * Copyright (C) 2007-2008 Torch Mobile, Inc.
6 *
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Library General Public
9 * License as published by the Free Software Foundation; either
10 * version 2 of the License, or (at your option) any later version.
11 *
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Library General Public License for more details.
16 *
17 * You should have received a copy of the GNU Library General Public License
18 * along with this library; see the file COPYING.LIB. If not, write to
19 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
20 * Boston, MA 02110-1301, USA.
21 *
22 */
23
24 #ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_FONTS_SIMPLE_FONT_DATA_H_
25 #define THIRD_PARTY_BLINK_RENDERER_PLATFORM_FONTS_SIMPLE_FONT_DATA_H_
26
27 #include <memory>
28 #include <utility>
29
30 #include "build/build_config.h"
31 #include "third_party/blink/renderer/platform/fonts/canvas_rotation_in_vertical.h"
32 #include "third_party/blink/renderer/platform/fonts/custom_font_data.h"
33 #include "third_party/blink/renderer/platform/fonts/font_baseline.h"
34 #include "third_party/blink/renderer/platform/fonts/font_data.h"
35 #include "third_party/blink/renderer/platform/fonts/font_metrics.h"
36 #include "third_party/blink/renderer/platform/fonts/font_metrics_override.h"
37 #include "third_party/blink/renderer/platform/fonts/font_platform_data.h"
38 #include "third_party/blink/renderer/platform/fonts/font_vertical_position_type.h"
39 #include "third_party/blink/renderer/platform/fonts/glyph.h"
40 #include "third_party/blink/renderer/platform/fonts/typesetting_features.h"
41 #include "third_party/blink/renderer/platform/geometry/float_rect.h"
42 #include "third_party/blink/renderer/platform/platform_export.h"
43 #include "third_party/blink/renderer/platform/wtf/casting.h"
44 #include "third_party/blink/renderer/platform/wtf/text/string_hash.h"
45 #include "third_party/skia/include/core/SkFont.h"
46
47 #if defined(OS_MAC)
48 #include "third_party/blink/renderer/platform/fonts/glyph_metrics_map.h"
49 #endif
50
51 namespace blink {
52
53 // Holds the glyph index and the corresponding SimpleFontData information for a
54 // given
55 // character.
56 struct GlyphData {
57 STACK_ALLOCATED();
58
59 public:
60 GlyphData(
61 Glyph g = 0,
62 const SimpleFontData* f = nullptr,
63 CanvasRotationInVertical rotation = CanvasRotationInVertical::kRegular)
glyphGlyphData64 : glyph(g), font_data(f), canvas_rotation(rotation) {}
65 Glyph glyph;
66 const SimpleFontData* font_data;
67 CanvasRotationInVertical canvas_rotation;
68 };
69
70 class FontDescription;
71
72 class PLATFORM_EXPORT SimpleFontData : public FontData {
73 public:
74 // Used to create platform fonts.
75 static scoped_refptr<SimpleFontData> Create(
76 const FontPlatformData& platform_data,
77 scoped_refptr<CustomFontData> custom_data = nullptr,
78 bool subpixel_ascent_descent = false) {
79 return base::AdoptRef(new SimpleFontData(
80 platform_data, std::move(custom_data), subpixel_ascent_descent));
81 }
82
PlatformData()83 const FontPlatformData& PlatformData() const { return platform_data_; }
84
85 scoped_refptr<SimpleFontData> SmallCapsFontData(const FontDescription&) const;
86 scoped_refptr<SimpleFontData> EmphasisMarkFontData(const FontDescription&) const;
87 scoped_refptr<SimpleFontData> MetricsOverriddenFontData(
88 const FontMetricsOverride&) const;
89
GetFontMetrics()90 FontMetrics& GetFontMetrics() { return font_metrics_; }
GetFontMetrics()91 const FontMetrics& GetFontMetrics() const { return font_metrics_; }
SizePerUnit()92 float SizePerUnit() const {
93 return PlatformData().size() /
94 (GetFontMetrics().UnitsPerEm() ? GetFontMetrics().UnitsPerEm() : 1);
95 }
InternalLeading()96 float InternalLeading() const {
97 return GetFontMetrics().FloatHeight() - PlatformData().size();
98 }
99
100 // |sTypoAscender| and |sTypoDescender| in |OS/2| table, normalized to 1em.
101 // This metrics can simulate ideographics em-box when the font doesn't have
102 // better ways to compute it.
103 // https://docs.microsoft.com/en-us/typography/opentype/spec/baselinetags#ideoembox
104 FontHeight NormalizedTypoAscentAndDescent(
105 FontBaseline baseline_type = kAlphabeticBaseline) const;
106 LayoutUnit NormalizedTypoAscent(FontBaseline = kAlphabeticBaseline) const;
107 LayoutUnit NormalizedTypoDescent(FontBaseline = kAlphabeticBaseline) const;
108
109 LayoutUnit VerticalPosition(FontVerticalPositionType, FontBaseline) const;
110
MaxCharWidth()111 float MaxCharWidth() const { return max_char_width_; }
SetMaxCharWidth(float max_char_width)112 void SetMaxCharWidth(float max_char_width) {
113 max_char_width_ = max_char_width;
114 }
115
AvgCharWidth()116 float AvgCharWidth() const { return avg_char_width_; }
SetAvgCharWidth(float avg_char_width)117 void SetAvgCharWidth(float avg_char_width) {
118 avg_char_width_ = avg_char_width;
119 }
120
121 FloatRect BoundsForGlyph(Glyph) const;
122 void BoundsForGlyphs(const Vector<Glyph, 256>&, Vector<SkRect, 256>*) const;
123 FloatRect PlatformBoundsForGlyph(Glyph) const;
124 float WidthForGlyph(Glyph) const;
125 float PlatformWidthForGlyph(Glyph) const;
126
SpaceWidth()127 float SpaceWidth() const { return space_width_; }
SetSpaceWidth(float space_width)128 void SetSpaceWidth(float space_width) { space_width_ = space_width; }
129
SpaceGlyph()130 Glyph SpaceGlyph() const { return space_glyph_; }
SetSpaceGlyph(Glyph space_glyph)131 void SetSpaceGlyph(Glyph space_glyph) { space_glyph_ = space_glyph; }
ZeroGlyph()132 Glyph ZeroGlyph() const { return zero_glyph_; }
SetZeroGlyph(Glyph zero_glyph)133 void SetZeroGlyph(Glyph zero_glyph) { zero_glyph_ = zero_glyph; }
134
135 const SimpleFontData* FontDataForCharacter(UChar32) const override;
136
137 Glyph GlyphForCharacter(UChar32) const;
138
IsCustomFont()139 bool IsCustomFont() const override { return custom_font_data_.get(); }
IsLoading()140 bool IsLoading() const override {
141 return custom_font_data_ ? custom_font_data_->IsLoading() : false;
142 }
IsLoadingFallback()143 bool IsLoadingFallback() const override {
144 return custom_font_data_ ? custom_font_data_->IsLoadingFallback() : false;
145 }
146 bool IsSegmented() const override;
ShouldSkipDrawing()147 bool ShouldSkipDrawing() const override {
148 return custom_font_data_ && custom_font_data_->ShouldSkipDrawing();
149 }
150
GetCustomFontData()151 CustomFontData* GetCustomFontData() const { return custom_font_data_.get(); }
152
VisualOverflowInflationForAscent()153 unsigned VisualOverflowInflationForAscent() const {
154 return visual_overflow_inflation_for_ascent_;
155 }
VisualOverflowInflationForDescent()156 unsigned VisualOverflowInflationForDescent() const {
157 return visual_overflow_inflation_for_descent_;
158 }
159
HasAdvanceOverride()160 bool HasAdvanceOverride() const override {
161 return advance_override_.has_value() ||
162 advance_proportional_override_.has_value();
163 }
164
GetAdvanceOverride()165 float GetAdvanceOverride() const { return advance_override_.value_or(0); }
GetAdvanceProportionalOverride()166 float GetAdvanceProportionalOverride() const {
167 return advance_proportional_override_.value_or(1);
168 }
169
170 protected:
171 SimpleFontData(
172 const FontPlatformData&,
173 scoped_refptr<CustomFontData> custom_data,
174 bool subpixel_ascent_descent = false,
175 const FontMetricsOverride& metrics_override = FontMetricsOverride());
176
177 private:
178 void PlatformInit(bool subpixel_ascent_descent, const FontMetricsOverride&);
179 void PlatformGlyphInit();
180
181 scoped_refptr<SimpleFontData> CreateScaledFontData(const FontDescription&,
182 float scale_factor) const;
183
184 void ComputeNormalizedTypoAscentAndDescent() const;
185 bool TrySetNormalizedTypoAscentAndDescent(float ascent, float descent) const;
186
187 FontMetrics font_metrics_;
188 float max_char_width_;
189 float avg_char_width_;
190
191 FontPlatformData platform_data_;
192 SkFont font_;
193
194 Glyph space_glyph_;
195 float space_width_;
196 Glyph zero_glyph_;
197
198 struct DerivedFontData {
199 USING_FAST_MALLOC(DerivedFontData);
200
201 public:
202 DerivedFontData() = default;
203
204 scoped_refptr<SimpleFontData> small_caps;
205 scoped_refptr<SimpleFontData> emphasis_mark;
206
207 DISALLOW_COPY_AND_ASSIGN(DerivedFontData);
208 };
209
210 mutable std::unique_ptr<DerivedFontData> derived_font_data_;
211
212 scoped_refptr<CustomFontData> custom_font_data_;
213
214 // These are set to non-zero when ascent or descent is rounded or shifted
215 // to be smaller than the actual ascent or descent. When calculating visual
216 // overflows, we should add the inflations.
217 unsigned visual_overflow_inflation_for_ascent_;
218 unsigned visual_overflow_inflation_for_descent_;
219
220 // The additional advance added to each letter as defined by the
221 // advance-override value in @font-face.
222 base::Optional<float> advance_override_;
223
224 // The multiplier to the advance of each letter as defined by the
225 // advance-proportional-override value in @font-face.
226 base::Optional<float> advance_proportional_override_;
227
228 mutable FontHeight normalized_typo_ascent_descent_;
229
230 // See discussion on crbug.com/631032 and Skiaissue
231 // https://bugs.chromium.org/p/skia/issues/detail?id=5328 :
232 // On Mac we're still using path based glyph metrics, and they seem to be
233 // too slow to be able to remove the caching layer we have here.
234 #if defined(OS_MAC)
235 mutable std::unique_ptr<GlyphMetricsMap<FloatRect>> glyph_to_bounds_map_;
236 mutable GlyphMetricsMap<float> glyph_to_width_map_;
237 #endif
238 };
239
BoundsForGlyph(Glyph glyph)240 ALWAYS_INLINE FloatRect SimpleFontData::BoundsForGlyph(Glyph glyph) const {
241 #if !defined(OS_MAC)
242 return PlatformBoundsForGlyph(glyph);
243 #else
244 FloatRect bounds_result;
245 if (glyph_to_bounds_map_) {
246 bounds_result = glyph_to_bounds_map_->MetricsForGlyph(glyph);
247 if (bounds_result.Width() != kCGlyphSizeUnknown)
248 return bounds_result;
249 }
250
251 bounds_result = PlatformBoundsForGlyph(glyph);
252 if (!glyph_to_bounds_map_)
253 glyph_to_bounds_map_ = std::make_unique<GlyphMetricsMap<FloatRect>>();
254 glyph_to_bounds_map_->SetMetricsForGlyph(glyph, bounds_result);
255
256 return bounds_result;
257 #endif
258 }
259
WidthForGlyph(Glyph glyph)260 ALWAYS_INLINE float SimpleFontData::WidthForGlyph(Glyph glyph) const {
261 #if !defined(OS_MAC)
262 return PlatformWidthForGlyph(glyph);
263 #else
264 float width = glyph_to_width_map_.MetricsForGlyph(glyph);
265 if (width != kCGlyphSizeUnknown)
266 return width;
267
268 width = PlatformWidthForGlyph(glyph);
269
270 glyph_to_width_map_.SetMetricsForGlyph(glyph, width);
271 return width;
272 #endif
273 }
274
275 template <>
276 struct DowncastTraits<SimpleFontData> {
277 static bool AllowFrom(const FontData& fontData) {
278 return !fontData.IsSegmented();
279 }
280 };
281
282 } // namespace blink
283 #endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_FONTS_SIMPLE_FONT_DATA_H_
284