1 /* 2 * Copyright (C) 2013 Google Inc. All rights reserved. 3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions are 6 * met: 7 * 8 * * Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * * Redistributions in binary form must reproduce the above 11 * copyright notice, this list of conditions and the following disclaimer 12 * in the documentation and/or other materials provided with the 13 * distribution. 14 * * Neither the name of Google Inc. nor the names of its 15 * contributors may be used to endorse or promote products derived from 16 * this software without specific prior written permission. 17 * 18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 21 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 22 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 23 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 24 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 */ 30 31 #include "config.h" 32 #include "core/platform/graphics/FontCustomPlatformData.h" 33 34 #include "core/platform/LayoutTestSupport.h" 35 #include "core/platform/NotImplemented.h" 36 #include "core/platform/SharedBuffer.h" 37 #include "core/platform/graphics/FontPlatformData.h" 38 #include "core/platform/graphics/opentype/OpenTypeSanitizer.h" 39 #include "core/platform/graphics/opentype/OpenTypeUtilities.h" 40 #include "wtf/PassOwnPtr.h" 41 #include "wtf/RefPtr.h" 42 #include "wtf/text/Base64.h" 43 44 #include <objbase.h> 45 46 namespace { 47 48 // Creates a unique and unpredictable font name, in order to avoid collisions and to 49 // not allow access from CSS. 50 String createUniqueFontName() 51 { 52 GUID fontUuid; 53 CoCreateGuid(&fontUuid); 54 55 String fontName = base64Encode(reinterpret_cast<char*>(&fontUuid), sizeof(fontUuid)); 56 ASSERT(fontName.length() < LF_FACESIZE); 57 return fontName; 58 } 59 60 } // namespace 61 62 namespace WebCore { 63 64 FontCustomPlatformData::FontCustomPlatformData(HANDLE fontReference, const String& name) 65 : m_fontReference(fontReference) 66 , m_name(name) 67 { 68 } 69 70 FontCustomPlatformData::~FontCustomPlatformData() 71 { 72 if (m_fontReference) 73 RemoveFontMemResourceEx(m_fontReference); 74 } 75 76 FontPlatformData FontCustomPlatformData::fontPlatformData(int size, bool bold, bool italic, FontOrientation orientation, FontWidthVariant) 77 { 78 ASSERT(m_fontReference); 79 80 LOGFONT logFont; 81 // m_name comes from createUniqueFontName, which, in turn, gets 82 // it from base64-encoded uuid (128-bit). So, m_name 83 // can never be longer than LF_FACESIZE (32). 84 if (m_name.length() + 1 >= LF_FACESIZE) { 85 ASSERT_NOT_REACHED(); 86 return FontPlatformData(); 87 } 88 unsigned len = m_name.copyTo(logFont.lfFaceName, 0, LF_FACESIZE - 1); 89 logFont.lfFaceName[len] = '\0'; 90 91 // FIXME: almost identical to FillLogFont in FontCacheWin.cpp. 92 // Need to refactor. 93 logFont.lfHeight = -size; 94 logFont.lfWidth = 0; 95 logFont.lfEscapement = 0; 96 logFont.lfOrientation = 0; 97 logFont.lfUnderline = false; 98 logFont.lfStrikeOut = false; 99 logFont.lfCharSet = DEFAULT_CHARSET; 100 logFont.lfOutPrecision = OUT_TT_ONLY_PRECIS; 101 logFont.lfQuality = isRunningLayoutTest() ? NONANTIALIASED_QUALITY : DEFAULT_QUALITY; // Honor user's desktop settings. 102 logFont.lfPitchAndFamily = DEFAULT_PITCH | FF_DONTCARE; 103 logFont.lfItalic = italic; 104 logFont.lfWeight = bold ? FW_BOLD : FW_DONTCARE; 105 106 HFONT hfont = CreateFontIndirect(&logFont); 107 return FontPlatformData(hfont, size, orientation); 108 } 109 110 PassOwnPtr<FontCustomPlatformData> FontCustomPlatformData::create(SharedBuffer* buffer) 111 { 112 ASSERT_ARG(buffer, buffer); 113 114 OpenTypeSanitizer sanitizer(buffer); 115 RefPtr<SharedBuffer> transcodeBuffer = sanitizer.sanitize(); 116 if (!transcodeBuffer) 117 return nullptr; // validation failed. 118 buffer = transcodeBuffer.get(); 119 120 // Introduce the font to GDI. AddFontMemResourceEx should be used with care, because it will pollute the process's 121 // font namespace (Windows has no API for creating an HFONT from data without exposing the font to the 122 // entire process first). 123 String fontName = createUniqueFontName(); 124 HANDLE fontReference = renameAndActivateFont(buffer, fontName); 125 if (!fontReference) 126 return nullptr; 127 128 return adoptPtr(new FontCustomPlatformData(fontReference, fontName)); 129 } 130 131 bool FontCustomPlatformData::supportsFormat(const String& format) 132 { 133 return equalIgnoringCase(format, "truetype") || equalIgnoringCase(format, "opentype") || OpenTypeSanitizer::supportsFormat(format); 134 } 135 136 } // namespace WebCore 137