1 /*
2 * Copyright (C) 2008 Alp Toker <alp@atoker.com>
3 * Copyright (C) 2010 Igalia S.L.
4 *
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Library General Public
7 * License as published by the Free Software Foundation; either
8 * version 2 of the License, or (at your option) any later version.
9 *
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Library General Public License for more details.
14 *
15 * You should have received a copy of the GNU Library General Public License
16 * along with this library; see the file COPYING.LIB. If not, write to
17 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
18 * Boston, MA 02110-1301, USA.
19 *
20 */
21
22 #include "config.h"
23 #include "FontCustomPlatformData.h"
24
25 #include "FontPlatformData.h"
26 #include "SharedBuffer.h"
27 #include "WOFFFileFormat.h"
28 #include <cairo-ft.h>
29 #include <cairo.h>
30
31 namespace WebCore {
32
releaseCustomFontData(void * data)33 static void releaseCustomFontData(void* data)
34 {
35 static_cast<SharedBuffer*>(data)->deref();
36 }
37
FontCustomPlatformData(FT_Face freeTypeFace,SharedBuffer * buffer)38 FontCustomPlatformData::FontCustomPlatformData(FT_Face freeTypeFace, SharedBuffer* buffer)
39 : m_freeTypeFace(freeTypeFace)
40 , m_fontFace(cairo_ft_font_face_create_for_ft_face(freeTypeFace, 0))
41 {
42 // FIXME Should we be setting some hinting options here?
43
44 buffer->ref(); // This is balanced by the buffer->deref() in releaseCustomFontData.
45 static cairo_user_data_key_t bufferKey;
46 cairo_font_face_set_user_data(m_fontFace, &bufferKey, buffer,
47 static_cast<cairo_destroy_func_t>(releaseCustomFontData));
48
49 // Cairo doesn't do FreeType reference counting, so we need to ensure that when
50 // this cairo_font_face_t is destroyed, it cleans up the FreeType face as well.
51 static cairo_user_data_key_t freeTypeFaceKey;
52 cairo_font_face_set_user_data(m_fontFace, &freeTypeFaceKey, freeTypeFace,
53 reinterpret_cast<cairo_destroy_func_t>(FT_Done_Face));
54 }
55
~FontCustomPlatformData()56 FontCustomPlatformData::~FontCustomPlatformData()
57 {
58 // m_freeTypeFace will be destroyed along with m_fontFace. See the constructor.
59 cairo_font_face_destroy(m_fontFace);
60 }
61
fontPlatformData(int size,bool bold,bool italic,FontOrientation,TextOrientation,FontWidthVariant,FontRenderingMode)62 FontPlatformData FontCustomPlatformData::fontPlatformData(int size, bool bold, bool italic, FontOrientation, TextOrientation, FontWidthVariant, FontRenderingMode)
63 {
64 return FontPlatformData(m_fontFace, size, bold, italic);
65 }
66
createFontCustomPlatformData(SharedBuffer * buffer)67 FontCustomPlatformData* createFontCustomPlatformData(SharedBuffer* buffer)
68 {
69 ASSERT_ARG(buffer, buffer);
70
71 RefPtr<SharedBuffer> sfntBuffer;
72 if (isWOFF(buffer)) {
73 Vector<char> sfnt;
74 if (!convertWOFFToSfnt(buffer, sfnt))
75 return 0;
76
77 sfntBuffer = SharedBuffer::adoptVector(sfnt);
78 buffer = sfntBuffer.get();
79 }
80
81 static FT_Library library = 0;
82 if (!library && FT_Init_FreeType(&library)) {
83 library = 0;
84 return 0;
85 }
86
87 FT_Face freeTypeFace;
88 if (FT_New_Memory_Face(library, reinterpret_cast<const FT_Byte*>(buffer->data()), buffer->size(), 0, &freeTypeFace))
89 return 0;
90 return new FontCustomPlatformData(freeTypeFace, buffer);
91 }
92
supportsFormat(const String & format)93 bool FontCustomPlatformData::supportsFormat(const String& format)
94 {
95 return equalIgnoringCase(format, "truetype") || equalIgnoringCase(format, "opentype") || equalIgnoringCase(format, "woff");
96 }
97
98 }
99