| 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) |
| 49 | OBJC_CLASS NSFont; |
| 50 | #endif |
| 51 | |
| 52 | #if PLATFORM(COCOA) |
| 53 | typedef 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> |
| 62 | typedef struct HFONT__* HFONT; |
| 63 | interface IDWriteFont; |
| 64 | interface IDWriteFontFace; |
| 65 | #endif |
| 66 | |
| 67 | #if USE(DIRECT2D) |
| 68 | #include <dwrite.h> |
| 69 | #endif |
| 70 | |
| 71 | namespace WebCore { |
| 72 | |
| 73 | class FontDescription; |
| 74 | class SharedBuffer; |
| 75 | |
| 76 | // This class is conceptually immutable. Once created, no instances should ever change (in an observable way). |
| 77 | class FontPlatformData { |
| 78 | WTF_MAKE_FAST_ALLOCATED; |
| 79 | public: |
| 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 | |
| 216 | private: |
| 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. |
| 288 | inline CTFontRef toCTFont(NSFont *font) |
| 289 | { |
| 290 | return (__bridge CTFontRef)font; |
| 291 | } |
| 292 | |
| 293 | inline NSFont *toNSFont(CTFontRef font) |
| 294 | { |
| 295 | return (__bridge NSFont *)font; |
| 296 | } |
| 297 | |
| 298 | #endif |
| 299 | |
| 300 | #if USE(CG) |
| 301 | |
| 302 | class ScopedTextMatrix { |
| 303 | public: |
| 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 | |
| 321 | private: |
| 322 | CGContextRef m_context; |
| 323 | CGAffineTransform m_textMatrix; |
| 324 | }; |
| 325 | |
| 326 | #endif |
| 327 | |
| 328 | } // namespace WebCore |
| 329 | |