2 * Copyright (C) 2007 Apple Computer, Inc.
3 * Copyright (c) 2007, 2008, 2009, Google Inc. All rights reserved.
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are
9 * * Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * * Redistributions in binary form must reproduce the above
12 * copyright notice, this list of conditions and the following disclaimer
13 * in the documentation and/or other materials provided with the
15 * * Neither the name of Google Inc. nor the names of its
16 * contributors may be used to endorse or promote products derived from
17 * this software without specific prior written permission.
19 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
22 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
23 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
25 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33 #include "FontCustomPlatformData.h"
37 #include "ChromiumBridge.h"
38 #include "OpenTypeUtilities.h"
41 #include "FontPlatformData.h"
42 #include "NotImplemented.h"
43 #include "SharedBuffer.h"
48 #pragma comment(lib, "t2embed")
53 FontCustomPlatformData::~FontCustomPlatformData()
56 if (m_fontReference) {
57 if (m_name.isNull()) {
59 TTDeleteEmbeddedFont(m_fontReference, 0, &status);
61 RemoveFontMemResourceEx(m_fontReference);
66 FontPlatformData FontCustomPlatformData::fontPlatformData(int size, bool bold, bool italic, FontRenderingMode mode)
69 ASSERT(m_fontReference);
73 TTGetNewFontName(&m_fontReference, logFont.lfFaceName, LF_FACESIZE, 0, 0);
75 // m_name comes from createUniqueFontName, which, in turn, gets
76 // it from base64-encoded uuid (128-bit). So, m_name
77 // can never be longer than LF_FACESIZE (32).
78 if (m_name.length() + 1 >= LF_FACESIZE) {
80 return FontPlatformData();
82 memcpy(logFont.lfFaceName, m_name.charactersWithNullTermination(),
83 sizeof(logFont.lfFaceName[0]) * (1 + m_name.length()));
86 // FIXME: almost identical to FillLogFont in FontCacheWin.cpp.
88 logFont.lfHeight = -size;
90 logFont.lfEscapement = 0;
91 logFont.lfOrientation = 0;
92 logFont.lfUnderline = false;
93 logFont.lfStrikeOut = false;
94 logFont.lfCharSet = DEFAULT_CHARSET;
95 logFont.lfOutPrecision = OUT_TT_ONLY_PRECIS;
96 logFont.lfQuality = ChromiumBridge::layoutTestMode() ?
97 NONANTIALIASED_QUALITY :
98 DEFAULT_QUALITY; // Honor user's desktop settings.
99 logFont.lfPitchAndFamily = DEFAULT_PITCH | FF_DONTCARE;
100 logFont.lfItalic = italic;
101 logFont.lfWeight = bold ? 700 : 400;
103 HFONT hfont = CreateFontIndirect(&logFont);
104 return FontPlatformData(hfont, size);
107 return FontPlatformData();
112 // FIXME: EOTStream class and static functions in this #if block are
113 // duplicated from platform/graphics/win/FontCustomPlatformData.cpp
114 // and need to be shared.
116 // Streams the concatenation of a header and font data.
119 EOTStream(const Vector<uint8_t, 512>& eotHeader, const SharedBuffer* fontData, size_t overlayDst, size_t overlaySrc, size_t overlayLength)
120 : m_eotHeader(eotHeader)
121 , m_fontData(fontData)
122 , m_overlayDst(overlayDst)
123 , m_overlaySrc(overlaySrc)
124 , m_overlayLength(overlayLength)
130 size_t read(void* buffer, size_t count);
133 const Vector<uint8_t, 512>& m_eotHeader;
134 const SharedBuffer* m_fontData;
137 size_t m_overlayLength;
142 size_t EOTStream::read(void* buffer, size_t count)
144 size_t bytesToRead = count;
146 size_t bytesFromHeader = std::min(m_eotHeader.size() - m_offset, count);
147 memcpy(buffer, m_eotHeader.data() + m_offset, bytesFromHeader);
148 m_offset += bytesFromHeader;
149 bytesToRead -= bytesFromHeader;
150 if (m_offset == m_eotHeader.size()) {
155 if (bytesToRead && !m_inHeader) {
156 size_t bytesFromData = std::min(m_fontData->size() - m_offset, bytesToRead);
157 memcpy(buffer, m_fontData->data() + m_offset, bytesFromData);
158 if (m_offset < m_overlayDst + m_overlayLength && m_offset + bytesFromData >= m_overlayDst) {
159 size_t dstOffset = std::max<int>(m_overlayDst - m_offset, 0);
160 size_t srcOffset = std::max<int>(0, m_offset - m_overlayDst);
161 size_t bytesToCopy = std::min(bytesFromData - dstOffset, m_overlayLength - srcOffset);
162 memcpy(reinterpret_cast<char*>(buffer) + dstOffset, m_fontData->data() + m_overlaySrc + srcOffset, bytesToCopy);
164 m_offset += bytesFromData;
165 bytesToRead -= bytesFromData;
167 return count - bytesToRead;
170 static unsigned long WINAPIV readEmbedProc(void* stream, void* buffer, unsigned long length)
172 return static_cast<EOTStream*>(stream)->read(buffer, length);
175 // Creates a unique and unpredictable font name, in order to avoid collisions and to
176 // not allow access from CSS.
177 static String createUniqueFontName()
179 Vector<char> fontUuid(sizeof(GUID));
180 CoCreateGuid(reinterpret_cast<GUID*>(fontUuid.data()));
182 Vector<char> fontNameVector;
183 base64Encode(fontUuid, fontNameVector);
184 ASSERT(fontNameVector.size() < LF_FACESIZE);
185 return String(fontNameVector.data(), fontNameVector.size());
189 FontCustomPlatformData* createFontCustomPlatformData(SharedBuffer* buffer)
191 ASSERT_ARG(buffer, buffer);
194 // Introduce the font to GDI. AddFontMemResourceEx cannot be used, because it will pollute the process's
195 // font namespace (Windows has no API for creating an HFONT from data without exposing the font to the
196 // entire process first). TTLoadEmbeddedFont lets us override the font family name, so using a unique name
197 // we avoid namespace collisions.
199 String fontName = createUniqueFontName();
201 // TTLoadEmbeddedFont works only with Embedded OpenType (.eot) data,
202 // so we need to create an EOT header and prepend it to the font data.
203 Vector<uint8_t, 512> eotHeader;
206 size_t overlayLength;
208 if (!getEOTHeader(buffer, eotHeader, overlayDst, overlaySrc, overlayLength))
211 HANDLE fontReference;
214 EOTStream eotStream(eotHeader, buffer, overlayDst, overlaySrc, overlayLength);
216 LONG loadEmbeddedFontResult = TTLoadEmbeddedFont(&fontReference, TTLOAD_PRIVATE, &privStatus, LICENSE_PREVIEWPRINT, &status, readEmbedProc, &eotStream, const_cast<LPWSTR>(fontName.charactersWithNullTermination()), 0, 0);
217 if (loadEmbeddedFontResult == E_NONE)
220 fontReference = renameAndActivateFont(buffer, fontName);
225 return new FontCustomPlatformData(fontReference, fontName);