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 "FontPlatformData.h"
25 #include "OpenTypeSanitizer.h"
26 #include "SharedBuffer.h"
27 #include "WOFFFileFormat.h"
28 #include <ApplicationServices/ApplicationServices.h>
29
30 namespace WebCore {
31
~FontCustomPlatformData()32 FontCustomPlatformData::~FontCustomPlatformData()
33 {
34 #if defined(BUILDING_ON_TIGER) || defined(BUILDING_ON_LEOPARD)
35 if (m_atsContainer)
36 ATSFontDeactivate(m_atsContainer, NULL, kATSOptionFlagsDefault);
37 #endif
38 CGFontRelease(m_cgFont);
39 }
40
fontPlatformData(int size,bool bold,bool italic,FontOrientation orientation,TextOrientation textOrientation,FontWidthVariant widthVariant,FontRenderingMode)41 FontPlatformData FontCustomPlatformData::fontPlatformData(int size, bool bold, bool italic, FontOrientation orientation, TextOrientation textOrientation, FontWidthVariant widthVariant, FontRenderingMode)
42 {
43 return FontPlatformData(m_cgFont, size, bold, italic, orientation, textOrientation, widthVariant);
44 }
45
createFontCustomPlatformData(SharedBuffer * buffer)46 FontCustomPlatformData* createFontCustomPlatformData(SharedBuffer* buffer)
47 {
48 ASSERT_ARG(buffer, buffer);
49
50 #if ENABLE(OPENTYPE_SANITIZER)
51 OpenTypeSanitizer sanitizer(buffer);
52 RefPtr<SharedBuffer> transcodeBuffer = sanitizer.sanitize();
53 if (!transcodeBuffer)
54 return 0; // validation failed.
55 buffer = transcodeBuffer.get();
56 #else
57 RefPtr<SharedBuffer> sfntBuffer;
58 if (isWOFF(buffer)) {
59 Vector<char> sfnt;
60 if (!convertWOFFToSfnt(buffer, sfnt))
61 return 0;
62
63 sfntBuffer = SharedBuffer::adoptVector(sfnt);
64 buffer = sfntBuffer.get();
65 }
66 #endif
67
68 ATSFontContainerRef containerRef = 0;
69
70 RetainPtr<CGFontRef> cgFontRef;
71
72 #if !defined(BUILDING_ON_TIGER) && !defined(BUILDING_ON_LEOPARD)
73 RetainPtr<CFDataRef> bufferData(AdoptCF, buffer->createCFData());
74 RetainPtr<CGDataProviderRef> dataProvider(AdoptCF, CGDataProviderCreateWithCFData(bufferData.get()));
75
76 cgFontRef.adoptCF(CGFontCreateWithDataProvider(dataProvider.get()));
77 if (!cgFontRef)
78 return 0;
79 #else
80 // Use ATS to activate the font.
81
82 // The value "3" means that the font is private and can't be seen by anyone else.
83 ATSFontActivateFromMemory((void*)buffer->data(), buffer->size(), 3, kATSFontFormatUnspecified, NULL, kATSOptionFlagsDefault, &containerRef);
84 if (!containerRef)
85 return 0;
86 ItemCount fontCount;
87 ATSFontFindFromContainer(containerRef, kATSOptionFlagsDefault, 0, NULL, &fontCount);
88
89 // We just support the first font in the list.
90 if (fontCount == 0) {
91 ATSFontDeactivate(containerRef, NULL, kATSOptionFlagsDefault);
92 return 0;
93 }
94
95 ATSFontRef fontRef = 0;
96 ATSFontFindFromContainer(containerRef, kATSOptionFlagsDefault, 1, &fontRef, NULL);
97 if (!fontRef) {
98 ATSFontDeactivate(containerRef, NULL, kATSOptionFlagsDefault);
99 return 0;
100 }
101
102 cgFontRef.adoptCF(CGFontCreateWithPlatformFont(&fontRef));
103 #ifndef BUILDING_ON_TIGER
104 // Workaround for <rdar://problem/5675504>.
105 if (cgFontRef && !CGFontGetNumberOfGlyphs(cgFontRef.get()))
106 cgFontRef = 0;
107 #endif
108 if (!cgFontRef) {
109 ATSFontDeactivate(containerRef, NULL, kATSOptionFlagsDefault);
110 return 0;
111 }
112 #endif // !defined(BUILDING_ON_TIGER) && !defined(BUILDING_ON_LEOPARD)
113
114 return new FontCustomPlatformData(containerRef, cgFontRef.releaseRef());
115 }
116
supportsFormat(const String & format)117 bool FontCustomPlatformData::supportsFormat(const String& format)
118 {
119 return equalIgnoringCase(format, "truetype") || equalIgnoringCase(format, "opentype") || equalIgnoringCase(format, "woff");
120 }
121
122 }
123