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