18e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project/*
28e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * Copyright (C) 2008 Alp Toker <alp@atoker.com>
3bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen * Copyright (C) 2010 Igalia S.L.
48e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *
58e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * This library is free software; you can redistribute it and/or
68e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * modify it under the terms of the GNU Library General Public
78e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * License as published by the Free Software Foundation; either
88e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * version 2 of the License, or (at your option) any later version.
98e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *
108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * This library is distributed in the hope that it will be useful,
118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * but WITHOUT ANY WARRANTY; without even the implied warranty of
128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * Library General Public License for more details.
148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *
158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * You should have received a copy of the GNU Library General Public License
168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * along with this library; see the file COPYING.LIB.  If not, write to
178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * Boston, MA 02110-1301, USA.
198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *
208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project */
218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "config.h"
238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "FontCustomPlatformData.h"
248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "FontPlatformData.h"
26db14019a23d96bc8a444b6576a5da8bd1cfbc8b0Steve Block#include "SharedBuffer.h"
27cad810f21b803229eb11403f9209855525a25d57Steve Block#include "WOFFFileFormat.h"
28bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen#include <cairo-ft.h>
29bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen#include <cairo.h>
308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectnamespace WebCore {
328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
33bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsenstatic void releaseCustomFontData(void* data)
34bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen{
35bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen    static_cast<SharedBuffer*>(data)->deref();
36bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen}
37bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen
38bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian MonsenFontCustomPlatformData::FontCustomPlatformData(FT_Face freeTypeFace, SharedBuffer* buffer)
39bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen    : m_freeTypeFace(freeTypeFace)
40bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen    , m_fontFace(cairo_ft_font_face_create_for_ft_face(freeTypeFace, 0))
41bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen{
42bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen    // FIXME Should we be setting some hinting options here?
43bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen
44bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen    buffer->ref(); // This is balanced by the buffer->deref() in releaseCustomFontData.
45bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen    static cairo_user_data_key_t bufferKey;
46bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen    cairo_font_face_set_user_data(m_fontFace, &bufferKey, buffer,
47bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen         static_cast<cairo_destroy_func_t>(releaseCustomFontData));
48bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen
49bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen    // Cairo doesn't do FreeType reference counting, so we need to ensure that when
50bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen    // this cairo_font_face_t is destroyed, it cleans up the FreeType face as well.
51bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen    static cairo_user_data_key_t freeTypeFaceKey;
52bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen    cairo_font_face_set_user_data(m_fontFace, &freeTypeFaceKey, freeTypeFace,
53bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen         reinterpret_cast<cairo_destroy_func_t>(FT_Done_Face));
54bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen}
55bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen
568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source ProjectFontCustomPlatformData::~FontCustomPlatformData()
578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
58bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen    // m_freeTypeFace will be destroyed along with m_fontFace. See the constructor.
598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    cairo_font_face_destroy(m_fontFace);
608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
622bde8e466a4451c7319e3a072d118917957d6554Steve BlockFontPlatformData FontCustomPlatformData::fontPlatformData(int size, bool bold, bool italic, FontOrientation, TextOrientation, FontWidthVariant, FontRenderingMode)
638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return FontPlatformData(m_fontFace, size, bold, italic);
658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
668e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source ProjectFontCustomPlatformData* createFontCustomPlatformData(SharedBuffer* buffer)
688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    ASSERT_ARG(buffer, buffer);
708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
71cad810f21b803229eb11403f9209855525a25d57Steve Block    RefPtr<SharedBuffer> sfntBuffer;
72cad810f21b803229eb11403f9209855525a25d57Steve Block    if (isWOFF(buffer)) {
73cad810f21b803229eb11403f9209855525a25d57Steve Block        Vector<char> sfnt;
74cad810f21b803229eb11403f9209855525a25d57Steve Block        if (!convertWOFFToSfnt(buffer, sfnt))
75cad810f21b803229eb11403f9209855525a25d57Steve Block            return 0;
76cad810f21b803229eb11403f9209855525a25d57Steve Block
77cad810f21b803229eb11403f9209855525a25d57Steve Block        sfntBuffer = SharedBuffer::adoptVector(sfnt);
78cad810f21b803229eb11403f9209855525a25d57Steve Block        buffer = sfntBuffer.get();
79cad810f21b803229eb11403f9209855525a25d57Steve Block    }
80cad810f21b803229eb11403f9209855525a25d57Steve Block
818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    static FT_Library library = 0;
82bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen    if (!library && FT_Init_FreeType(&library)) {
83bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen        library = 0;
84bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen        return 0;
858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
87bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen    FT_Face freeTypeFace;
88bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen    if (FT_New_Memory_Face(library, reinterpret_cast<const FT_Byte*>(buffer->data()), buffer->size(), 0, &freeTypeFace))
898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return 0;
90bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen    return new FontCustomPlatformData(freeTypeFace, buffer);
918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
93db14019a23d96bc8a444b6576a5da8bd1cfbc8b0Steve Blockbool FontCustomPlatformData::supportsFormat(const String& format)
94db14019a23d96bc8a444b6576a5da8bd1cfbc8b0Steve Block{
95cad810f21b803229eb11403f9209855525a25d57Steve Block    return equalIgnoringCase(format, "truetype") || equalIgnoringCase(format, "opentype") || equalIgnoringCase(format, "woff");
96db14019a23d96bc8a444b6576a5da8bd1cfbc8b0Steve Block}
97db14019a23d96bc8a444b6576a5da8bd1cfbc8b0Steve Block
988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
99