[WTF] Add makeUnique<T>, which ensures T is fast-allocated, makeUnique / makeUniqueWi...
[WebKit-https.git] / Source / WebCore / platform / graphics / mac / FontCustomPlatformData.cpp
1 /*
2  * Copyright (C) 2007, 2008, 2010 Apple Inc. All rights reserved.
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Library General Public
6  * License as published by the Free Software Foundation; either
7  * version 2 of the License, or (at your option) any later version.
8  *
9  * This library is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  * Library General Public License for more details.
13  *
14  * You should have received a copy of the GNU Library General Public License
15  * along with this library; see the file COPYING.LIB.  If not, write to
16  * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
17  * Boston, MA 02110-1301, USA.
18  *
19  */
20
21 #include "config.h"
22 #include "FontCustomPlatformData.h"
23
24 #include "FontCache.h"
25 #include "FontCacheCoreText.h"
26 #include "FontDescription.h"
27 #include "FontPlatformData.h"
28 #include "SharedBuffer.h"
29 #include <CoreFoundation/CoreFoundation.h>
30 #include <CoreGraphics/CoreGraphics.h>
31 #include <CoreText/CoreText.h>
32 #include <pal/spi/cocoa/CoreTextSPI.h>
33
34 namespace WebCore {
35
36 FontCustomPlatformData::~FontCustomPlatformData() = default;
37
38 FontPlatformData FontCustomPlatformData::fontPlatformData(const FontDescription& fontDescription, bool bold, bool italic, const FontFeatureSettings& fontFaceFeatures, const FontVariantSettings& fontFaceVariantSettings, FontSelectionSpecifiedCapabilities fontFaceCapabilities)
39 {
40     auto attributes = adoptCF(CFDictionaryCreateMutable(kCFAllocatorDefault, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks));
41     addAttributesForWebFonts(attributes.get(), fontDescription.shouldAllowUserInstalledFonts());
42     auto modifiedFontDescriptor = adoptCF(CTFontDescriptorCreateCopyWithAttributes(m_fontDescriptor.get(), attributes.get()));
43     ASSERT(modifiedFontDescriptor);
44
45     int size = fontDescription.computedPixelSize();
46     FontOrientation orientation = fontDescription.orientation();
47     FontWidthVariant widthVariant = fontDescription.widthVariant();
48     RetainPtr<CTFontRef> font = adoptCF(CTFontCreateWithFontDescriptor(modifiedFontDescriptor.get(), size, nullptr));
49     font = preparePlatformFont(font.get(), fontDescription, &fontFaceFeatures, &fontFaceVariantSettings, fontFaceCapabilities);
50     ASSERT(font);
51     return FontPlatformData(font.get(), size, bold, italic, orientation, widthVariant, fontDescription.textRenderingMode());
52 }
53
54 std::unique_ptr<FontCustomPlatformData> createFontCustomPlatformData(SharedBuffer& buffer, const String& itemInCollection)
55 {
56     RetainPtr<CFDataRef> bufferData = buffer.createCFData();
57
58     RetainPtr<CTFontDescriptorRef> fontDescriptor;
59 #if PLATFORM(MAC) || (PLATFORM(IOS_FAMILY) && __IPHONE_OS_VERSION_MIN_REQUIRED >= 110000)
60     auto array = adoptCF(CTFontManagerCreateFontDescriptorsFromData(bufferData.get()));
61     if (!array)
62         return nullptr;
63     auto length = CFArrayGetCount(array.get());
64     if (length <= 0)
65         return nullptr;
66     if (!itemInCollection.isNull()) {
67         if (auto desiredName = itemInCollection.createCFString()) {
68             for (CFIndex i = 0; i < length; ++i) {
69                 auto candidate = static_cast<CTFontDescriptorRef>(CFArrayGetValueAtIndex(array.get(), i));
70                 auto postScriptName = adoptCF(static_cast<CFStringRef>(CTFontDescriptorCopyAttribute(candidate, kCTFontNameAttribute)));
71                 if (CFStringCompare(postScriptName.get(), desiredName.get(), 0) == kCFCompareEqualTo) {
72                     fontDescriptor = candidate;
73                     break;
74                 }
75             }
76         }
77     }
78     if (!fontDescriptor)
79         fontDescriptor = static_cast<CTFontDescriptorRef>(CFArrayGetValueAtIndex(array.get(), 0));
80 #else
81     UNUSED_PARAM(itemInCollection);
82     fontDescriptor = adoptCF(CTFontManagerCreateFontDescriptorFromData(bufferData.get()));
83     if (!fontDescriptor)
84         return nullptr;
85 #endif
86
87     return makeUnique<FontCustomPlatformData>(fontDescriptor.get());
88 }
89
90 bool FontCustomPlatformData::supportsFormat(const String& format)
91 {
92     return equalLettersIgnoringASCIICase(format, "truetype")
93         || equalLettersIgnoringASCIICase(format, "opentype")
94         || equalLettersIgnoringASCIICase(format, "woff2")
95 #if ENABLE(VARIATION_FONTS)
96         || equalLettersIgnoringASCIICase(format, "woff2-variations")
97 #endif
98 #if ENABLE(VARIATION_FONTS)
99         || equalLettersIgnoringASCIICase(format, "woff-variations")
100         || equalLettersIgnoringASCIICase(format, "truetype-variations")
101         || equalLettersIgnoringASCIICase(format, "opentype-variations")
102 #endif
103         || equalLettersIgnoringASCIICase(format, "woff");
104 }
105
106 }