summaryrefslogtreecommitdiff
path: root/chromium/third_party/blink/renderer/platform/fonts/font.h
blob: 0c41798f0a2c09ffa97e3bc2ca651d25a891a4a6 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
/*
 * Copyright (C) 2000 Lars Knoll (knoll@kde.org)
 *           (C) 2000 Antti Koivisto (koivisto@kde.org)
 *           (C) 2000 Dirk Mueller (mueller@kde.org)
 * Copyright (C) 2003, 2006, 2007, 2010, 2011 Apple Inc. All rights reserved.
 * Copyright (C) 2008 Holger Hans Peter Freyther
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Library General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Library General Public License for more details.
 *
 * You should have received a copy of the GNU Library General Public License
 * along with this library; see the file COPYING.LIB.  If not, write to
 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
 * Boston, MA 02110-1301, USA.
 *
 */

#ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_FONTS_FONT_H_
#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_FONTS_FONT_H_

#include "cc/paint/node_id.h"
#include "third_party/blink/renderer/platform/fonts/font_description.h"
#include "third_party/blink/renderer/platform/fonts/font_fallback_iterator.h"
#include "third_party/blink/renderer/platform/fonts/font_fallback_list.h"
#include "third_party/blink/renderer/platform/fonts/font_fallback_priority.h"
#include "third_party/blink/renderer/platform/fonts/simple_font_data.h"
#include "third_party/blink/renderer/platform/geometry/layout_unit.h"
#include "third_party/blink/renderer/platform/platform_export.h"
#include "third_party/blink/renderer/platform/text/tab_size.h"
#include "third_party/blink/renderer/platform/text/text_direction.h"
#include "third_party/blink/renderer/platform/wtf/allocator/allocator.h"
#include "third_party/blink/renderer/platform/wtf/hash_map.h"
#include "third_party/blink/renderer/platform/wtf/hash_set.h"
#include "third_party/blink/renderer/platform/wtf/math_extras.h"
#include "third_party/blink/renderer/platform/wtf/text/character_names.h"

// To avoid conflicts with the CreateWindow macro from the Windows SDK...
#undef DrawText

namespace cc {
class PaintCanvas;
class PaintFlags;
}  // namespace cc

namespace blink {

struct CharacterRange;
class FloatPoint;
class FloatRect;
class FontSelector;
class ShapeCache;
class TextRun;
struct TextRunPaintInfo;
struct NGTextFragmentPaintInfo;

class PLATFORM_EXPORT Font {
  DISALLOW_NEW();

 public:
  Font();
  explicit Font(const FontDescription&);
  Font(const FontDescription&, FontSelector*);
  ~Font();

  Font(const Font&);
  Font& operator=(const Font&);

  bool operator==(const Font& other) const;
  bool operator!=(const Font& other) const { return !(*this == other); }

  const FontDescription& GetFontDescription() const {
    return font_description_;
  }

  enum CustomFontNotReadyAction {
    kDoNotPaintIfFontNotReady,
    kUseFallbackIfFontNotReady
  };

  // TODO(layout-dev): Once zoom-for-dsf launches on Mac the device_scale_factor
  // parameter can be removed from all of these methods.
  // https://crbug.com/716231
  void DrawText(cc::PaintCanvas*,
                const TextRunPaintInfo&,
                const FloatPoint&,
                float device_scale_factor,
                const cc::PaintFlags&) const;
  void DrawText(cc::PaintCanvas*,
                const TextRunPaintInfo&,
                const FloatPoint&,
                float device_scale_factor,
                cc::NodeId node_id,
                const cc::PaintFlags&) const;
  void DrawText(cc::PaintCanvas*,
                const NGTextFragmentPaintInfo&,
                const FloatPoint&,
                float device_scale_factor,
                cc::NodeId node_id,
                const cc::PaintFlags&) const;
  bool DrawBidiText(cc::PaintCanvas*,
                    const TextRunPaintInfo&,
                    const FloatPoint&,
                    CustomFontNotReadyAction,
                    float device_scale_factor,
                    const cc::PaintFlags&) const;
  void DrawEmphasisMarks(cc::PaintCanvas*,
                         const TextRunPaintInfo&,
                         const AtomicString& mark,
                         const FloatPoint&,
                         float device_scale_factor,
                         const cc::PaintFlags&) const;
  void DrawEmphasisMarks(cc::PaintCanvas*,
                         const NGTextFragmentPaintInfo&,
                         const AtomicString& mark,
                         const FloatPoint&,
                         float device_scale_factor,
                         const cc::PaintFlags&) const;

  FloatRect TextInkBounds(const NGTextFragmentPaintInfo&) const;

  struct TextIntercept {
    float begin_, end_;
  };

  // Compute the text intercepts along the axis of the advance and write them
  // into the specified Vector of TextIntercepts. The number of those is zero or
  // a multiple of two, and is at most the number of glyphs * 2 in the TextRun
  // part of TextRunPaintInfo. Specify bounds for the upper and lower extend of
  // a line crossing through the text, parallel to the baseline.
  // TODO(drott): crbug.com/655154 Fix this for upright in vertical.
  void GetTextIntercepts(const TextRunPaintInfo&,
                         float device_scale_factor,
                         const cc::PaintFlags&,
                         const std::tuple<float, float>& bounds,
                         Vector<TextIntercept>&) const;
  void GetTextIntercepts(const NGTextFragmentPaintInfo&,
                         float device_scale_factor,
                         const cc::PaintFlags&,
                         const std::tuple<float, float>& bounds,
                         Vector<TextIntercept>&) const;

  // Glyph bounds will be the minimum rect containing all glyph strokes, in
  // coordinates using (<text run x position>, <baseline position>) as the
  // origin.
  float Width(const TextRun&,
              HashSet<const SimpleFontData*>* fallback_fonts = nullptr,
              FloatRect* glyph_bounds = nullptr) const;

  int OffsetForPosition(const TextRun&,
                        float position,
                        IncludePartialGlyphsOption,
                        BreakGlyphsOption) const;
  FloatRect SelectionRectForText(const TextRun&,
                                 const FloatPoint&,
                                 float height,
                                 int from = 0,
                                 int to = -1) const;
  FloatRect BoundingBox(const TextRun&, int from = 0, int to = -1) const;
  CharacterRange GetCharacterRange(const TextRun&,
                                   unsigned from,
                                   unsigned to) const;
  Vector<CharacterRange> IndividualCharacterRanges(const TextRun&) const;

  // Returns a vector of same size as TextRun.length() with advances measured
  // in pixels from the left bounding box of the full TextRun to the left bound
  // of the glyph rendered by each character. Values should always be positive.
  Vector<double> IndividualCharacterAdvances(const TextRun&) const;

  void ExpandRangeToIncludePartialGlyphs(const TextRun&,
                                         int* from,
                                         int* to) const;

  // Metrics that we query the FontFallbackList for.
  float SpaceWidth() const {
    DCHECK(PrimaryFont());
    return (PrimaryFont() ? PrimaryFont()->SpaceWidth() : 0) +
           GetFontDescription().LetterSpacing();
  }

  // Compute the base tab width; the width when its position is zero.
  float TabWidth(const SimpleFontData*, const TabSize&) const;
  // Compute the tab width for the specified |position|.
  float TabWidth(const SimpleFontData*, const TabSize&, float position) const;
  float TabWidth(const TabSize& tab_size, float position) const {
    return TabWidth(PrimaryFont(), tab_size, position);
  }
  LayoutUnit TabWidth(const TabSize&, LayoutUnit position) const;

  int EmphasisMarkAscent(const AtomicString&) const;
  int EmphasisMarkDescent(const AtomicString&) const;
  int EmphasisMarkHeight(const AtomicString&) const;

  // This may fail and return a nullptr in case the last resort font cannot be
  // loaded. This *should* not happen but in reality it does ever now and then
  // when, for whatever reason, the last resort font cannot be loaded.
  const SimpleFontData* PrimaryFont() const;

  // Access the shape cache associated with this particular font object.
  // Should *not* be retained across layout calls as it may become invalid.
  ShapeCache* GetShapeCache() const;

  // Whether the font supports shaping word by word instead of shaping the
  // full run in one go. Allows better caching for fonts where space cannot
  // participate in kerning and/or ligatures.
  bool CanShapeWordByWord() const;

  void SetCanShapeWordByWordForTesting(bool b) {
    EnsureFontFallbackList()->SetCanShapeWordByWordForTesting(b);
  }

  void ReportNotDefGlyph() const;

 private:
  enum ForTextEmphasisOrNot { kNotForTextEmphasis, kForTextEmphasis };

  GlyphData GetEmphasisMarkGlyphData(const AtomicString&) const;

 public:
  FontSelector* GetFontSelector() const;
  FontFallbackIterator CreateFontFallbackIterator(
      FontFallbackPriority fallback_priority) const {
    EnsureFontFallbackList();
    return FontFallbackIterator(font_description_, font_fallback_list_,
                                fallback_priority);
  }

  void WillUseFontData(const String& text) const;

  bool LoadingCustomFonts() const;
  bool IsFallbackValid() const;

  bool ShouldSkipDrawing() const {
    return font_fallback_list_ && font_fallback_list_->ShouldSkipDrawing();
  }

 private:
  FontFallbackList* EnsureFontFallbackList() const;
  void RevalidateFontFallbackList() const;
  void ReleaseFontFallbackListRef() const;

  FontDescription font_description_;
  mutable scoped_refptr<FontFallbackList> font_fallback_list_;
};

inline const SimpleFontData* Font::PrimaryFont() const {
  return EnsureFontFallbackList()->PrimarySimpleFontData(font_description_);
}

inline FontSelector* Font::GetFontSelector() const {
  return font_fallback_list_ ? font_fallback_list_->GetFontSelector() : nullptr;
}

inline float Font::TabWidth(const SimpleFontData* font_data,
                            const TabSize& tab_size) const {
  if (!font_data)
    return GetFontDescription().LetterSpacing();
  float base_tab_width = tab_size.GetPixelSize(font_data->SpaceWidth());
  return base_tab_width ? base_tab_width : GetFontDescription().LetterSpacing();
}

}  // namespace blink

#endif