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