OLD | NEW |
---|---|
1 /* | 1 /* |
2 * Copyright (C) 2007 Apple Computer, Inc. | 2 * Copyright (C) 2007 Apple Computer, Inc. |
3 * | 3 * |
4 * This library is free software; you can redistribute it and/or | 4 * This library is free software; you can redistribute it and/or |
5 * modify it under the terms of the GNU Library General Public | 5 * modify it under the terms of the GNU Library General Public |
6 * License as published by the Free Software Foundation; either | 6 * License as published by the Free Software Foundation; either |
7 * version 2 of the License, or (at your option) any later version. | 7 * version 2 of the License, or (at your option) any later version. |
8 * | 8 * |
9 * This library is distributed in the hope that it will be useful, | 9 * This library is distributed in the hope that it will be useful, |
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of | 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of |
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
12 * Library General Public License for more details. | 12 * Library General Public License for more details. |
13 * | 13 * |
14 * You should have received a copy of the GNU Library General Public License | 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 | 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, | 16 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, |
17 * Boston, MA 02110-1301, USA. | 17 * Boston, MA 02110-1301, USA. |
18 * | 18 * |
19 */ | 19 */ |
20 | 20 |
21 #include "config.h" | 21 #include "config.h" |
22 #include "FontCustomPlatformData.h" | 22 #include "FontCustomPlatformData.h" |
23 | 23 |
24 #include "SharedBuffer.h" | 24 #if PLATFORM(WIN_OS) |
25 #include "Base64.h" | |
26 #include "ChromiumBridge.h" | |
27 #include "OpenTypeUtilities.h" | |
28 #endif | |
29 | |
25 #include "FontPlatformData.h" | 30 #include "FontPlatformData.h" |
26 #include "NotImplemented.h" | 31 #include "NotImplemented.h" |
32 #include "SharedBuffer.h" | |
33 | |
34 #if PLATFORM(WIN_OS) | |
35 #include <objbase.h> | |
36 #include <t2embapi.h> | |
37 #pragma comment(lib, "t2embed") | |
38 #endif | |
27 | 39 |
28 namespace WebCore { | 40 namespace WebCore { |
29 | 41 |
30 FontCustomPlatformData::~FontCustomPlatformData() | 42 FontCustomPlatformData::~FontCustomPlatformData() |
31 { | 43 { |
32 // FIXME: Release the HFONT ref? | 44 #if PLATFORM(WIN_OS) |
33 } | 45 if (m_fontReference) { |
34 | 46 if (m_name.isNull()) { |
35 FontPlatformData FontCustomPlatformData::fontPlatformData(int size, bool bold, b ool italic) | 47 ULONG status; |
36 { | 48 TTDeleteEmbeddedFont(m_fontReference, 0, &status); |
37 return FontPlatformData(m_font, size); | 49 } else |
38 } | 50 RemoveFontMemResourceEx(m_fontReference); |
39 | 51 } |
40 FontCustomPlatformData* createFontCustomPlatformData(SharedBuffer* buffer) | 52 #endif |
41 { | 53 } |
42 ASSERT_ARG(buffer, buffer); | 54 |
43 | 55 FontPlatformData FontCustomPlatformData::fontPlatformData(int size, |
44 #if PLATFORM(WIN_OS) | 56 bool bold, |
45 HFONT font = 0; | 57 bool italic, |
46 // FIXME: Figure out some way to get Windows to give us back a font object. | 58 FontRenderingMode mode ) |
47 if (!font) | 59 { |
48 return 0; | 60 #if PLATFORM(WIN_OS) |
49 return new FontCustomPlatformData(font); | 61 ASSERT(m_fontReference); |
62 | |
63 LOGFONT logFont; | |
64 if (m_name.isNull()) | |
65 TTGetNewFontName(&m_fontReference, logFont.lfFaceName, | |
66 LF_FACESIZE, 0, 0); | |
67 else { | |
68 // m_name comes from createUniqueFontName, which, in turn, gets | |
69 // it from base64-encoded uuid (128-bit). So, m_name | |
70 // can never be longer than LF_FACESIZE (32). | |
71 if (m_name.length() >= LF_FACESIZE) { | |
eroman
2009/01/06 02:17:05
I think this check should be against m_name.length
| |
72 ASSERT_NOT_REACHED(); | |
73 return FontPlatformData(); | |
74 } | |
75 memcpy(logFont.lfFaceName, m_name.charactersWithNullTermination(), | |
76 sizeof(logFont.lfFaceName[0]) * (1 + m_name.length())); | |
77 } | |
78 | |
79 // FIXME: almost identical to FillLogFont in FontCacheWin.cpp. | |
80 // Need to refactor. | |
81 logFont.lfHeight = -size; | |
82 logFont.lfWidth = 0; | |
83 logFont.lfEscapement = 0; | |
84 logFont.lfOrientation = 0; | |
85 logFont.lfUnderline = false; | |
86 logFont.lfStrikeOut = false; | |
87 logFont.lfCharSet = DEFAULT_CHARSET; | |
88 logFont.lfOutPrecision = OUT_TT_ONLY_PRECIS; | |
89 logFont.lfQuality = ChromiumBridge::layoutTestMode() ? | |
90 NONANTIALIASED_QUALITY : | |
91 DEFAULT_QUALITY; // Honor user's desktop settings. | |
92 logFont.lfPitchAndFamily = DEFAULT_PITCH | FF_DONTCARE; | |
93 logFont.lfItalic = italic; | |
94 logFont.lfWeight = bold ? 700 : 400; | |
95 | |
96 HFONT hfont = CreateFontIndirect(&logFont); | |
97 return FontPlatformData(hfont, size); | |
50 #else | 98 #else |
51 notImplemented(); | 99 notImplemented(); |
52 #endif | 100 return FontPlatformData(); |
53 } | 101 #endif |
54 | 102 } |
103 | |
104 #if PLATFORM(WIN_OS) | |
105 // FIXME: EOTStream class and static functions in this #if block are | |
106 // duplicated from platform/graphics/win/FontCustomplatformData.cpp | |
107 // and need to be shared. | |
108 | |
109 // Streams the concatenation of a header and font data. | |
110 class EOTStream { | |
111 public: | |
112 EOTStream(const Vector<UInt8, 512>& eotHeader, const SharedBuffer* fontData, size_t overlayDst, size_t overlaySrc, size_t overlayLength) | |
113 : m_eotHeader(eotHeader) | |
114 , m_fontData(fontData) | |
115 , m_overlayDst(overlayDst) | |
116 , m_overlaySrc(overlaySrc) | |
117 , m_overlayLength(overlayLength) | |
118 , m_offset(0) | |
119 , m_inHeader(true) | |
120 { | |
121 } | |
122 | |
123 size_t read(void* buffer, size_t count); | |
124 | |
125 private: | |
126 const Vector<UInt8, 512>& m_eotHeader; | |
127 const SharedBuffer* m_fontData; | |
128 size_t m_overlayDst; | |
129 size_t m_overlaySrc; | |
130 size_t m_overlayLength; | |
131 size_t m_offset; | |
132 bool m_inHeader; | |
133 }; | |
134 | |
135 size_t EOTStream::read(void* buffer, size_t count) | |
136 { | |
137 size_t bytesToRead = count; | |
138 if (m_inHeader) { | |
139 size_t bytesFromHeader = std::min(m_eotHeader.size() - m_offset, count); | |
140 memcpy(buffer, m_eotHeader.data() + m_offset, bytesFromHeader); | |
141 m_offset += bytesFromHeader; | |
142 bytesToRead -= bytesFromHeader; | |
143 if (m_offset == m_eotHeader.size()) { | |
144 m_inHeader = false; | |
145 m_offset = 0; | |
146 } | |
147 } | |
148 if (bytesToRead && !m_inHeader) { | |
149 size_t bytesFromData = std::min(m_fontData->size() - m_offset, bytesToRe ad); | |
150 memcpy(buffer, m_fontData->data() + m_offset, bytesFromData); | |
151 if (m_offset < m_overlayDst + m_overlayLength && m_offset + bytesFromDat a >= m_overlayDst) { | |
152 size_t dstOffset = std::max<int>(m_overlayDst - m_offset, 0); | |
153 size_t srcOffset = std::max<int>(0, m_offset - m_overlayDst); | |
154 size_t bytesToCopy = std::min(bytesFromData - dstOffset, m_overlayLe ngth - srcOffset); | |
155 memcpy(reinterpret_cast<char*>(buffer) + dstOffset, m_fontData->data () + m_overlaySrc + srcOffset, bytesToCopy); | |
156 } | |
157 m_offset += bytesFromData; | |
158 bytesToRead -= bytesFromData; | |
159 } | |
160 return count - bytesToRead; | |
161 } | |
162 | |
163 static unsigned long WINAPIV readEmbedProc(void* stream, void* buffer, unsigned long length) | |
164 { | |
165 return static_cast<EOTStream*>(stream)->read(buffer, length); | |
166 } | |
167 | |
168 // Creates a unique and unpredictable font name, in order to avoid collisions an d to | |
169 // not allow access from CSS. | |
170 static String createUniqueFontName() | |
171 { | |
172 Vector<char> fontUuid(sizeof(GUID)); | |
173 CoCreateGuid(reinterpret_cast<GUID*>(fontUuid.data())); | |
174 | |
175 Vector<char> fontNameVector; | |
176 base64Encode(fontUuid, fontNameVector); | |
177 ASSERT(fontNameVector.size() < LF_FACESIZE); | |
178 return String(fontNameVector.data(), fontNameVector.size()); | |
179 } | |
180 #endif | |
181 | |
182 FontCustomPlatformData* createFontCustomPlatformData(SharedBuffer* buffer) | |
183 { | |
184 ASSERT_ARG(buffer, buffer); | |
185 | |
186 #if PLATFORM(WIN_OS) | |
187 // Introduce the font to GDI. AddFontMemResourceEx cannot be used, because i t will pollute the process's | |
188 // font namespace (Windows has no API for creating an HFONT from data withou t exposing the font to the | |
189 // entire process first). TTLoadEmbeddedFont lets us override the font famil y name, so using a unique name | |
190 // we avoid namespace collisions. | |
191 | |
192 String fontName = createUniqueFontName(); | |
193 | |
194 // TTLoadEmbeddedFont works only with Embedded OpenType (.eot) data, | |
195 // so we need to create an EOT header and prepend it to the font data. | |
196 Vector<UInt8, 512> eotHeader; | |
197 size_t overlayDst; | |
198 size_t overlaySrc; | |
199 size_t overlayLength; | |
200 | |
201 if (!getEOTHeader(buffer, eotHeader, overlayDst, overlaySrc, overlayLength)) | |
202 return 0; | |
203 | |
204 HANDLE fontReference; | |
205 ULONG privStatus; | |
206 ULONG status; | |
207 EOTStream eotStream(eotHeader, buffer, overlayDst, overlaySrc, overlayLength ); | |
208 | |
209 LONG loadEmbeddedFontResult = TTLoadEmbeddedFont(&fontReference, TTLOAD_PRIV ATE, &privStatus, LICENSE_PREVIEWPRINT, &status, readEmbedProc, &eotStream, cons t_cast<LPWSTR>(fontName.charactersWithNullTermination()), 0, 0); | |
210 if (loadEmbeddedFontResult == E_NONE) | |
211 fontName = String(); | |
212 else { | |
213 fontReference = renameAndActivateFont(buffer, fontName); | |
214 if (!fontReference) { | |
215 return 0; | |
216 } | |
217 } | |
218 | |
219 return new FontCustomPlatformData(fontReference, fontName); | |
220 #else | |
221 notImplemented();; | |
222 return 0; | |
223 #endif | |
224 } | |
225 | |
55 } | 226 } |
OLD | NEW |