1/*
2 * Copyright (C) 2006-2018 Apple Inc. All rights reserved.
3 * Copyright (C) 2006 Michael Emmel mike.emmel@gmail.com
4 * Copyright (C) 2007 Holger Hans Peter Freyther
5 * Copyright (C) 2007 Pioneer Research Center USA, Inc.
6 * Copyright (C) 2010, 2011 Brent Fulgham <bfulgham@webkit.org>
7 *
8 * This library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Library General Public
10 * License as published by the Free Software Foundation; either
11 * version 2 of the License, or (at your option) any later version.
12 *
13 * This library is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Library General Public License for more details.
17 *
18 * You should have received a copy of the GNU Library General Public License
19 * along with this library; see the file COPYING.LIB. If not, write to
20 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
21 * Boston, MA 02110-1301, USA.
22 *
23 */
24
25#pragma once
26
27#include "TextFlags.h"
28#include <wtf/Forward.h>
29#include <wtf/RetainPtr.h>
30
31
32#if PLATFORM(WIN)
33#include "COMPtr.h"
34#include "SharedGDIObject.h"
35#endif
36
37#if USE(CAIRO)
38#include "RefPtrCairo.h"
39#endif
40
41#if USE(FREETYPE)
42#include "FcUniquePtr.h"
43#include "HbUniquePtr.h"
44#include "RefPtrFontconfig.h"
45#include <memory>
46#endif
47
48#if USE(APPKIT)
49OBJC_CLASS NSFont;
50#endif
51
52#if PLATFORM(COCOA)
53typedef const struct __CTFont* CTFontRef;
54#endif
55
56#if USE(CG)
57#include <CoreGraphics/CoreGraphics.h>
58#endif
59
60#if PLATFORM(WIN)
61#include <wtf/win/GDIObject.h>
62typedef struct HFONT__* HFONT;
63interface IDWriteFont;
64interface IDWriteFontFace;
65#endif
66
67#if USE(DIRECT2D)
68#include <dwrite.h>
69#endif
70
71namespace WebCore {
72
73class FontDescription;
74class SharedBuffer;
75
76// This class is conceptually immutable. Once created, no instances should ever change (in an observable way).
77class FontPlatformData {
78 WTF_MAKE_FAST_ALLOCATED;
79public:
80 FontPlatformData(WTF::HashTableDeletedValueType);
81 FontPlatformData();
82
83 FontPlatformData(const FontDescription&, const AtomicString& family);
84 FontPlatformData(float size, bool syntheticBold, bool syntheticOblique, FontOrientation = FontOrientation::Horizontal, FontWidthVariant = FontWidthVariant::RegularWidth, TextRenderingMode = TextRenderingMode::AutoTextRendering);
85
86#if PLATFORM(COCOA)
87 WEBCORE_EXPORT FontPlatformData(CTFontRef, float size, bool syntheticBold = false, bool syntheticOblique = false, FontOrientation = FontOrientation::Horizontal, FontWidthVariant = FontWidthVariant::RegularWidth, TextRenderingMode = TextRenderingMode::AutoTextRendering);
88#endif
89
90 static FontPlatformData cloneWithOrientation(const FontPlatformData&, FontOrientation);
91 static FontPlatformData cloneWithSyntheticOblique(const FontPlatformData&, bool);
92 static FontPlatformData cloneWithSize(const FontPlatformData&, float);
93
94#if USE(CG) && PLATFORM(WIN)
95 FontPlatformData(CGFontRef, float size, bool syntheticBold, bool syntheticOblique, FontOrientation, FontWidthVariant, TextRenderingMode);
96#endif
97
98#if PLATFORM(WIN)
99 FontPlatformData(GDIObject<HFONT>, float size, bool syntheticBold, bool syntheticOblique, bool useGDI);
100#endif
101
102#if PLATFORM(WIN) && USE(CG)
103 FontPlatformData(GDIObject<HFONT>, CGFontRef, float size, bool syntheticBold, bool syntheticOblique, bool useGDI);
104#endif
105
106#if PLATFORM(WIN) && USE(DIRECT2D)
107 FontPlatformData(GDIObject<HFONT>, IDWriteFont*, float size, bool syntheticBold, bool syntheticOblique, bool useGDI);
108#endif
109
110#if PLATFORM(WIN) && USE(CAIRO)
111 FontPlatformData(GDIObject<HFONT>, cairo_font_face_t*, float size, bool bold, bool italic);
112#endif
113
114#if USE(FREETYPE)
115 FontPlatformData(cairo_font_face_t*, FcPattern*, float size, bool fixedWidth, bool syntheticBold, bool syntheticOblique, FontOrientation);
116 FontPlatformData(const FontPlatformData&);
117 FontPlatformData(FontPlatformData&&) = default;
118 FontPlatformData& operator=(const FontPlatformData&);
119 FontPlatformData& operator=(FontPlatformData&&) = default;
120 ~FontPlatformData();
121#endif
122
123#if PLATFORM(WIN)
124 HFONT hfont() const { return m_font ? m_font->get() : 0; }
125 bool useGDI() const { return m_useGDI; }
126#endif
127
128#if PLATFORM(COCOA)
129 CTFontRef font() const { return m_font.get(); }
130 WEBCORE_EXPORT CTFontRef registeredFont() const; // Returns nullptr iff the font is not registered, such as web fonts (otherwise returns font()).
131
132 CTFontRef ctFont() const;
133 static RetainPtr<CFTypeRef> objectForEqualityCheck(CTFontRef);
134 RetainPtr<CFTypeRef> objectForEqualityCheck() const;
135
136 bool hasCustomTracking() const { return isSystemFont(); }
137#endif
138
139#if PLATFORM(WIN) || PLATFORM(COCOA)
140 bool isSystemFont() const { return m_isSystemFont; }
141#endif
142
143 bool hasVariations() const { return m_hasVariations; }
144
145#if USE(CG) && PLATFORM(WIN)
146 CGFontRef cgFont() const { return m_cgFont.get(); }
147#endif
148
149#if USE(DIRECT2D)
150 IDWriteFont* dwFont() const { return m_dwFont.get(); }
151 IDWriteFontFace* dwFontFace() const { return m_dwFontFace.get(); }
152
153 static HRESULT createFallbackFont(const LOGFONT&, IDWriteFont**);
154#endif
155
156 bool isFixedPitch() const;
157 float size() const { return m_size; }
158 bool syntheticBold() const { return m_syntheticBold; }
159 bool syntheticOblique() const { return m_syntheticOblique; }
160 bool isColorBitmapFont() const { return m_isColorBitmapFont; }
161 FontOrientation orientation() const { return m_orientation; }
162 FontWidthVariant widthVariant() const { return m_widthVariant; }
163 TextRenderingMode textRenderingMode() const { return m_textRenderingMode; }
164 bool isForTextCombine() const { return widthVariant() != FontWidthVariant::RegularWidth; } // Keep in sync with callers of FontDescription::setWidthVariant().
165
166#if USE(CAIRO)
167 cairo_scaled_font_t* scaledFont() const { return m_scaledFont.get(); }
168#endif
169
170#if USE(FREETYPE)
171#if USE(HARFBUZZ) && !ENABLE(OPENTYPE_MATH)
172 HbUniquePtr<hb_font_t> createOpenTypeMathHarfBuzzFont() const;
173#endif
174 bool hasCompatibleCharmap() const;
175 FcPattern* fcPattern() const;
176 bool isFixedWidth() const { return m_fixedWidth; }
177#endif
178
179 unsigned hash() const;
180
181 bool operator==(const FontPlatformData& other) const
182 {
183 return platformIsEqual(other)
184 && m_isHashTableDeletedValue == other.m_isHashTableDeletedValue
185 && m_size == other.m_size
186 && m_syntheticBold == other.m_syntheticBold
187 && m_syntheticOblique == other.m_syntheticOblique
188 && m_isColorBitmapFont == other.m_isColorBitmapFont
189 && m_orientation == other.m_orientation
190 && m_widthVariant == other.m_widthVariant
191 && m_textRenderingMode == other.m_textRenderingMode;
192 }
193
194 bool isHashTableDeletedValue() const
195 {
196 return m_isHashTableDeletedValue;
197 }
198
199 bool isEmoji() const
200 {
201#if PLATFORM(IOS_FAMILY)
202 return m_isEmoji;
203#else
204 return false;
205#endif
206 }
207
208#if PLATFORM(COCOA) || PLATFORM(WIN) || USE(FREETYPE)
209 RefPtr<SharedBuffer> openTypeTable(uint32_t table) const;
210#endif
211
212#if !LOG_DISABLED
213 String description() const;
214#endif
215
216private:
217 bool platformIsEqual(const FontPlatformData&) const;
218
219#if PLATFORM(COCOA)
220 CGFloat ctFontSize() const;
221#endif
222
223#if PLATFORM(WIN)
224 void platformDataInit(HFONT, float size, HDC, WCHAR* faceName);
225#endif
226
227#if USE(FREETYPE)
228 void buildScaledFont(cairo_font_face_t*);
229#endif
230
231#if PLATFORM(COCOA)
232 // FIXME: Get rid of one of these. These two fonts are subtly different, and it is not obvious which one to use where.
233 RetainPtr<CTFontRef> m_font;
234 mutable RetainPtr<CTFontRef> m_ctFont;
235#elif PLATFORM(WIN)
236 RefPtr<SharedGDIObject<HFONT>> m_font;
237#endif
238
239#if USE(CG) && PLATFORM(WIN)
240 RetainPtr<CGFontRef> m_cgFont;
241#endif
242
243#if USE(DIRECT2D)
244 COMPtr<IDWriteFont> m_dwFont;
245 COMPtr<IDWriteFontFace> m_dwFontFace;
246#endif
247
248#if USE(CAIRO)
249 RefPtr<cairo_scaled_font_t> m_scaledFont;
250#endif
251
252#if USE(FREETYPE)
253 RefPtr<FcPattern> m_pattern;
254#endif
255
256 // The values below are common to all ports
257 // FIXME: If they're common to all ports, they should move to Font
258 float m_size { 0 };
259
260 FontOrientation m_orientation { FontOrientation::Horizontal };
261 FontWidthVariant m_widthVariant { FontWidthVariant::RegularWidth };
262 TextRenderingMode m_textRenderingMode { TextRenderingMode::AutoTextRendering };
263
264 bool m_syntheticBold { false };
265 bool m_syntheticOblique { false };
266 bool m_isColorBitmapFont { false };
267 bool m_isHashTableDeletedValue { false };
268 bool m_isSystemFont { false };
269 bool m_hasVariations { false };
270 // The values above are common to all ports
271
272#if PLATFORM(IOS_FAMILY)
273 bool m_isEmoji { false };
274#endif
275
276#if PLATFORM(WIN)
277 bool m_useGDI { false };
278#endif
279
280#if USE(FREETYPE)
281 bool m_fixedWidth { false };
282#endif
283};
284
285#if USE(APPKIT) && defined(__OBJC__)
286
287// NSFonts and CTFontRefs are toll-free-bridged.
288inline CTFontRef toCTFont(NSFont *font)
289{
290 return (__bridge CTFontRef)font;
291}
292
293inline NSFont *toNSFont(CTFontRef font)
294{
295 return (__bridge NSFont *)font;
296}
297
298#endif
299
300#if USE(CG)
301
302class ScopedTextMatrix {
303public:
304 ScopedTextMatrix(CGAffineTransform newMatrix, CGContextRef context)
305 : m_context(context)
306 , m_textMatrix(CGContextGetTextMatrix(context))
307 {
308 CGContextSetTextMatrix(m_context, newMatrix);
309 }
310
311 ~ScopedTextMatrix()
312 {
313 CGContextSetTextMatrix(m_context, m_textMatrix);
314 }
315
316 CGAffineTransform savedMatrix() const
317 {
318 return m_textMatrix;
319 }
320
321private:
322 CGContextRef m_context;
323 CGAffineTransform m_textMatrix;
324};
325
326#endif
327
328} // namespace WebCore
329