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 <cairo-ft.h>
28#include <cairo.h>
29
30namespace WebCore {
31
32static void releaseCustomFontData(void* data)
33{
34    static_cast<SharedBuffer*>(data)->deref();
35}
36
37FontCustomPlatformData::FontCustomPlatformData(FT_Face freeTypeFace, SharedBuffer& buffer)
38    : m_freeTypeFace(freeTypeFace)
39    , m_fontFace(cairo_ft_font_face_create_for_ft_face(freeTypeFace, 0))
40{
41    // FIXME Should we be setting some hinting options here?
42
43    buffer.ref(); // This is balanced by the buffer->deref() in releaseCustomFontData.
44    static cairo_user_data_key_t bufferKey;
45    cairo_font_face_set_user_data(m_fontFace, &bufferKey, &buffer,
46         static_cast<cairo_destroy_func_t>(releaseCustomFontData));
47
48    // Cairo doesn't do FreeType reference counting, so we need to ensure that when
49    // this cairo_font_face_t is destroyed, it cleans up the FreeType face as well.
50    static cairo_user_data_key_t freeTypeFaceKey;
51    cairo_font_face_set_user_data(m_fontFace, &freeTypeFaceKey, freeTypeFace,
52         reinterpret_cast<cairo_destroy_func_t>(FT_Done_Face));
53}
54
55FontCustomPlatformData::~FontCustomPlatformData()
56{
57    // m_freeTypeFace will be destroyed along with m_fontFace. See the constructor.
58    cairo_font_face_destroy(m_fontFace);
59}
60
61FontPlatformData FontCustomPlatformData::fontPlatformData(int size, bool bold, bool italic, FontOrientation orientation, FontWidthVariant, FontRenderingMode)
62{
63    return FontPlatformData(m_fontFace, size, bold, italic, orientation);
64}
65
66std::unique_ptr<FontCustomPlatformData> createFontCustomPlatformData(SharedBuffer& buffer)
67{
68    static FT_Library library;
69    if (!library && FT_Init_FreeType(&library)) {
70        library = nullptr;
71        return nullptr;
72    }
73
74    FT_Face freeTypeFace;
75    if (FT_New_Memory_Face(library, reinterpret_cast<const FT_Byte*>(buffer.data()), buffer.size(), 0, &freeTypeFace))
76        return nullptr;
77    return std::make_unique<FontCustomPlatformData>(freeTypeFace, buffer);
78}
79
80bool FontCustomPlatformData::supportsFormat(const String& format)
81{
82    return equalIgnoringCase(format, "truetype") || equalIgnoringCase(format, "opentype") || equalIgnoringCase(format, "woff");
83}
84
85}
86