2008-03-12 Xan Lopez <xan@gnome.org>
authoralp@webkit.org <alp@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 12 Mar 2008 15:03:17 +0000 (15:03 +0000)
committeralp@webkit.org <alp@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 12 Mar 2008 15:03:17 +0000 (15:03 +0000)
        Reviewed by Alp Toker.

        http://bugs.webkit.org/show_bug.cgi?id=15229

        Add Pango font backend.

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@30989 268f45cc-cd09-0410-ab3c-d52691b4dbfc

ChangeLog
WebCore/ChangeLog
WebCore/GNUmakefile.am
WebCore/platform/graphics/gtk/FontCacheGtk.cpp
WebCore/platform/graphics/gtk/FontCustomPlatformDataPango.cpp [new file with mode: 0644]
WebCore/platform/graphics/gtk/FontPlatformData.h
WebCore/platform/graphics/gtk/FontPlatformDataPango.cpp [new file with mode: 0644]
WebCore/platform/graphics/gtk/GlyphPageTreeNodePango.cpp [new file with mode: 0644]
WebCore/platform/graphics/gtk/SimpleFontDataPango.cpp [new file with mode: 0644]
configure.ac

index 1b9dfcb..0e2d026 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,14 @@
+2008-03-12  Xan Lopez  <xan@gnome.org>
+
+        Reviewed by Alp Toker.
+
+        http://bugs.webkit.org/show_bug.cgi?id=15229
+
+        Add optional font backend support with freetype and pango
+        backends. Default is freetype for now.
+
+        * configure.ac:
+
 2008-03-11  Xan Lopez  <xan@gnome.org>
 
         Reviewed by Alp Toker.
index 3e564f0..6a7f5af 100644 (file)
@@ -1,3 +1,41 @@
+2008-03-12  Xan Lopez  <xan@gnome.org>
+
+        Reviewed by Alp Toker.
+
+        http://bugs.webkit.org/show_bug.cgi?id=15229
+
+        Add Pango font backend.
+
+        * GNUmakefile.am:
+        * platform/graphics/gtk/FontCacheGtk.cpp:
+        (WebCore::FontCache::fontExists):
+        * platform/graphics/gtk/FontCustomPlatformDataPango.cpp: Added.
+        (WebCore::FontCustomPlatformData::~FontCustomPlatformData):
+        (WebCore::FontCustomPlatformData::fontPlatformData):
+        (WebCore::releaseData):
+        (WebCore::createFontCustomPlatformData):
+        * platform/graphics/gtk/FontPlatformData.h:
+        (WebCore::FontPlatformData::FontPlatformData):
+        (WebCore::FontPlatformData::hash):
+        * platform/graphics/gtk/FontPlatformDataPango.cpp: Added.
+        (WebCore::FontPlatformData::FontPlatformData):
+        (WebCore::FontPlatformData::init):
+        (WebCore::FontPlatformData::~FontPlatformData):
+        (WebCore::FontPlatformData::isFixedPitch):
+        (WebCore::FontPlatformData::setFont):
+        (WebCore::FontPlatformData::operator==):
+        * platform/graphics/gtk/GlyphPageTreeNodePango.cpp: Added.
+        (WebCore::pango_font_get_glyph):
+        (WebCore::GlyphPage::fill):
+        * platform/graphics/gtk/SimpleFontDataPango.cpp: Added.
+        (WebCore::SimpleFontData::platformInit):
+        (WebCore::SimpleFontData::platformDestroy):
+        (WebCore::SimpleFontData::smallCapsFontData):
+        (WebCore::SimpleFontData::containsCharacters):
+        (WebCore::SimpleFontData::determinePitch):
+        (WebCore::SimpleFontData::platformWidthForGlyph):
+        (WebCore::SimpleFontData::setFont):
+
 2008-03-12  Justin Garcia  <justin.garcia@apple.com>
 
         Reviewed by Oliver.
index a9dd37a..01b5061 100644 (file)
@@ -980,11 +980,7 @@ webkitgtk_sources += \
        WebCore/platform/gtk/FileChooserGtk.cpp \
        WebCore/platform/gtk/FileSystemGtk.cpp \
        WebCore/platform/graphics/gtk/FontCacheGtk.cpp \
-       WebCore/platform/graphics/gtk/FontCustomPlatformData.cpp \
        WebCore/platform/graphics/gtk/FontGtk.cpp \
-       WebCore/platform/graphics/gtk/FontPlatformDataGtk.cpp \
-       WebCore/platform/graphics/gtk/GlyphPageTreeNodeGtk.cpp \
-       WebCore/platform/graphics/gtk/SimpleFontDataGtk.cpp \
        WebCore/platform/gtk/KeyEventGtk.cpp \
        WebCore/platform/gtk/Language.cpp \
        WebCore/platform/gtk/LocalizedStringsGtk.cpp \
@@ -1051,6 +1047,34 @@ webcore_sources += \
        WebCore/platform/network/soup/ResourceHandleSoup.cpp
 endif
 
+# ---
+# Freetype font backend
+# ---
+if USE_FREETYPE
+webkitgtk_cppflags += \
+       -DUSE_FREETYPE=1
+
+webkitgtk_sources += \
+       WebCore/platform/graphics/gtk/FontCustomPlatformData.cpp \
+       WebCore/platform/graphics/gtk/FontPlatformDataGtk.cpp \
+       WebCore/platform/graphics/gtk/GlyphPageTreeNodeGtk.cpp \
+       WebCore/platform/graphics/gtk/SimpleFontDataGtk.cpp
+endif # END USE_FREETYPE
+
+# ---
+# Pango font backend
+# ---
+if USE_PANGO
+webkitgtk_cppflags += \
+       -DUSE_PANGO=1
+
+webkitgtk_sources += \
+       WebCore/platform/graphics/gtk/FontCustomPlatformDataPango.cpp \
+       WebCore/platform/graphics/gtk/FontPlatformDataPango.cpp \
+       WebCore/platform/graphics/gtk/GlyphPageTreeNodePango.cpp \
+       WebCore/platform/graphics/gtk/SimpleFontDataPango.cpp
+endif # END USE_PANGO
+
 # ----
 # Cross-document messaging support
 # ----
index aec5758..044c259 100644 (file)
@@ -64,7 +64,13 @@ FontPlatformData* FontCache::getLastResortFallbackFont(const FontDescription& fo
 bool FontCache::fontExists(const FontDescription& fontDescription, const AtomicString& family)
 {
     FontPlatformData platformData(fontDescription, family);
+#if defined(USE_PANGO)
+    return platformData.m_font != 0;
+#elif defined(USE_FREETYPE)
     return platformData.m_pattern != 0;
+#else
+#error "Must define a font backend"
+#endif
 }
 
 FontPlatformData* FontCache::createFontPlatformData(const FontDescription& fontDescription, const AtomicString& family)
diff --git a/WebCore/platform/graphics/gtk/FontCustomPlatformDataPango.cpp b/WebCore/platform/graphics/gtk/FontCustomPlatformDataPango.cpp
new file mode 100644 (file)
index 0000000..1eb1359
--- /dev/null
@@ -0,0 +1,49 @@
+/*
+ * Copyright (C) 2008 Alp Toker <alp@atoker.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB.  If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "config.h"
+#include "FontCustomPlatformData.h"
+
+#include "SharedBuffer.h"
+#include "FontPlatformData.h"
+
+namespace WebCore {
+
+FontCustomPlatformData::~FontCustomPlatformData()
+{
+}
+
+FontPlatformData FontCustomPlatformData::fontPlatformData(int size, bool bold, bool italic)
+{
+    return FontPlatformData(m_fontFace, size, bold, italic);
+}
+
+static void releaseData(void* data)
+{
+    static_cast<SharedBuffer*>(data)->deref();
+}
+
+FontCustomPlatformData* createFontCustomPlatformData(SharedBuffer* buffer)
+{
+    // FIXME: we need support in pango to read fonts from memory to implement this.y
+    return 0;
+}
+
+}
index 778d525..eca8c14 100644 (file)
@@ -5,6 +5,7 @@
  * Copyright (C) 2006 Apple Computer, Inc.
  * Copyright (C) 2006 Michael Emmel mike.emmel@gmail.com
  * Copyright (C) 2007 Holger Hans Peter Freyther
+ * Copyright (C) 2007 Pioneer Research Center USA, Inc.
  * All rights reserved.
  *
  * This library is free software; you can redistribute it and/or
 #include "GlyphBuffer.h"
 #include "FontDescription.h"
 #include <cairo.h>
+#if defined(USE_FREETYPE)
 #include <cairo-ft.h>
 #include <fontconfig/fcfreetype.h>
+#elif defined(USE_PANGO)
+#include <pango/pangocairo.h>
+#else
+#error "Must defined a font backend"
+#endif
 
 namespace WebCore {
 
@@ -39,12 +46,26 @@ class FontPlatformData {
 public:
     class Deleted {};
     FontPlatformData(Deleted)
+#if defined(USE_FREETYPE)
         : m_pattern(reinterpret_cast<FcPattern*>(-1))
+#elif defined(USE_PANGO)
+        : m_context(0)
+        , m_font(reinterpret_cast<PangoFont*>(-1))
+#else
+#error "Must defined a font backend"
+#endif
         , m_scaledFont(0)
         { }
 
     FontPlatformData()
+#if defined(USE_FREETYPE)
         : m_pattern(0)
+#elif defined(USE_PANGO)
+        : m_context(0)
+        , m_font(0)
+#else
+#error "Must defined a font backend"
+#endif
         , m_scaledFont(0)
         { }
 
@@ -65,12 +86,22 @@ public:
     unsigned hash() const
     {
         uintptr_t hashCodes[1] = { reinterpret_cast<uintptr_t>(m_scaledFont) };
-        return StringImpl::computeHash( reinterpret_cast<UChar*>(hashCodes), sizeof(hashCodes) / sizeof(UChar));
+        return StringImpl::computeHash(reinterpret_cast<UChar*>(hashCodes), sizeof(hashCodes) / sizeof(UChar));
     }
 
     bool operator==(const FontPlatformData&) const;
 
+#if defined(USE_FREETYPE)
     FcPattern* m_pattern;
+#elif defined(USE_PANGO)
+    static PangoFontMap* m_fontMap;
+    static GHashTable* m_hashTable;
+
+    PangoContext* m_context;
+    PangoFont* m_font;
+#else
+#error "Must defined a font backend"
+#endif
     FontDescription m_fontDescription;
     cairo_scaled_font_t* m_scaledFont;
 };
diff --git a/WebCore/platform/graphics/gtk/FontPlatformDataPango.cpp b/WebCore/platform/graphics/gtk/FontPlatformDataPango.cpp
new file mode 100644 (file)
index 0000000..57f1805
--- /dev/null
@@ -0,0 +1,220 @@
+/*
+ * Copyright (C) 2006 Apple Computer, Inc.
+ * Copyright (C) 2006 Michael Emmel mike.emmel@gmail.com
+ * Copyright (C) 2007, 2008 Alp Toker <alp@atoker.com>
+ * Copyright (C) 2007 Holger Hans Peter Freyther
+ * Copyright (C) 2007 Pioneer Research Center USA, Inc.
+ * All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB.  If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+#include "config.h"
+#include "FontPlatformData.h"
+
+#include "CString.h"
+#include "PlatformString.h"
+#include "FontDescription.h"
+#include <cairo.h>
+#include <assert.h>
+
+#include <pango/pango.h>
+#include <pango/pangocairo.h>
+
+// Use cairo-ft i a recent enough Pango version isn't available
+#if !PANGO_VERSION_CHECK(1,18,0)
+#include <cairo-ft.h>
+#include <pango/pangofc-fontmap.h>
+#endif
+#include <gtk/gtk.h>
+
+namespace WebCore {
+
+  PangoFontMap* FontPlatformData::m_fontMap = 0;
+  GHashTable* FontPlatformData::m_hashTable = 0;
+
+FontPlatformData::FontPlatformData(const FontDescription& fontDescription, const AtomicString& familyName)
+    : m_context(0)
+    , m_font(0)
+    , m_fontDescription(fontDescription)
+    , m_scaledFont(0)
+{
+    FontPlatformData::init();
+
+    CString stored_family = familyName.string().utf8();
+    char const* families[] = {
+      stored_family.data(),
+      NULL
+    };
+
+    switch (fontDescription.genericFamily()) {
+    case FontDescription::SerifFamily:
+        families[1] = "serif";
+        break;
+    case FontDescription::SansSerifFamily:
+        families[1] = "sans";
+        break;
+    case FontDescription::MonospaceFamily:
+        families[1] = "monospace";
+        break;
+    case FontDescription::NoFamily:
+    case FontDescription::StandardFamily:
+    default:
+        families[1] = "sans";
+        break;
+    }
+
+    PangoFontDescription* description = pango_font_description_new();
+    pango_font_description_set_absolute_size(description, fontDescription.computedSize() * PANGO_SCALE);
+
+    if (fontDescription.bold())
+        pango_font_description_set_weight(description, PANGO_WEIGHT_BOLD);
+    if (fontDescription.italic())
+        pango_font_description_set_style(description, PANGO_STYLE_ITALIC);
+
+    m_context = pango_cairo_font_map_create_context(PANGO_CAIRO_FONT_MAP(m_fontMap));
+    for (unsigned int i = 0; !m_font && i < G_N_ELEMENTS(families); i++) {
+        pango_font_description_set_family(description, families[i]);
+        m_font = pango_font_map_load_font(m_fontMap, m_context, description);
+    }
+
+#if PANGO_VERSION_CHECK(1,18,0)
+    if (m_font)
+        m_scaledFont = cairo_scaled_font_reference(pango_cairo_font_get_scaled_font(PANGO_CAIRO_FONT(m_font)));
+#else
+    // This compatibility code for older versions of Pango is not well-tested.
+    if (m_font) {
+        PangoFcFont* fcfont = PANGO_FC_FONT(m_font);
+        cairo_font_face_t* face = cairo_ft_font_face_create_for_pattern(fcfont->font_pattern);
+        double size;
+        if (FcPatternGetDouble(fcfont->font_pattern, FC_PIXEL_SIZE, 0, &size) != FcResultMatch)
+          size = 12.0;
+        cairo_matrix_t fontMatrix;
+        cairo_matrix_init_scale(&fontMatrix, size, size);
+        cairo_font_options_t* fontOptions;
+        if (pango_cairo_context_get_font_options(m_context))
+          fontOptions = cairo_font_options_copy(pango_cairo_context_get_font_options(m_context));
+        else
+          fontOptions = cairo_font_options_create();
+        cairo_matrix_t ctm;
+        cairo_matrix_init_identity(&ctm);
+        m_scaledFont = cairo_scaled_font_create(face, &fontMatrix, &ctm, fontOptions);
+        cairo_font_options_destroy(fontOptions);
+        cairo_font_face_destroy(face);
+    }
+#endif
+    pango_font_description_free(description);
+}
+
+FontPlatformData::FontPlatformData(float size, bool bold, bool italic)
+    : m_context(0)
+    , m_font(0)
+    , m_fontDescription()
+    , m_scaledFont(0)
+{
+    m_fontDescription.setSpecifiedSize(size);
+    m_fontDescription.setBold(bold);
+    m_fontDescription.setItalic(italic);
+}
+
+FontPlatformData::FontPlatformData(cairo_font_face_t* fontFace, int size, bool bold, bool italic)
+    : m_context(0)
+    , m_font(0)
+    , m_fontDescription()
+    , m_scaledFont(0)
+{
+    m_fontDescription.setSpecifiedSize(size);
+    m_fontDescription.setBold(bold);
+    m_fontDescription.setItalic(italic);
+
+    cairo_matrix_t fontMatrix;
+    cairo_matrix_init_scale(&fontMatrix, size, size);
+    cairo_matrix_t ctm;
+    cairo_matrix_init_identity(&ctm);
+    cairo_font_options_t* options = cairo_font_options_create();
+
+    // We force antialiasing and disable hinting to provide consistent
+    // typographic qualities for custom fonts on all platforms.
+    cairo_font_options_set_hint_style(options, CAIRO_HINT_STYLE_NONE);
+    cairo_font_options_set_antialias(options, CAIRO_ANTIALIAS_GRAY);
+
+    m_scaledFont = cairo_scaled_font_create(fontFace, &fontMatrix, &ctm, options);
+    cairo_font_options_destroy(options);
+}
+
+bool FontPlatformData::init()
+{
+    static bool initialized = false;
+    if (initialized)
+        return true;
+    initialized = true;
+
+    if (!m_fontMap)
+        m_fontMap = pango_cairo_font_map_get_default();
+    if (!m_hashTable) {
+        PangoFontFamily** families = 0;
+        int n_families = 0;
+
+        m_hashTable = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, g_object_unref);
+
+        pango_font_map_list_families(m_fontMap, &families, &n_families);
+
+        for (int family = 0; family < n_families; family++)
+                g_hash_table_insert(m_hashTable,
+                                    g_strdup(pango_font_family_get_name(families[family])),
+                                    g_object_ref(families[family]));
+
+        g_free(families);
+    }
+
+    return true;
+}
+
+FontPlatformData::~FontPlatformData()
+{
+    // Destroy takes place in FontData::platformDestroy().
+}
+
+bool FontPlatformData::isFixedPitch()
+{
+    PangoFontDescription* description = pango_font_describe_with_absolute_size(m_font);
+    PangoFontFamily* family = reinterpret_cast<PangoFontFamily*>(g_hash_table_lookup(m_hashTable, pango_font_description_get_family(description)));
+    pango_font_description_free(description);
+    return pango_font_family_is_monospace(family);
+}
+
+void FontPlatformData::setFont(cairo_t* cr) const
+{
+    ASSERT(m_scaledFont);
+
+    cairo_set_scaled_font(cr, m_scaledFont);
+}
+
+bool FontPlatformData::operator==(const FontPlatformData& other) const
+{
+    if (m_font == other.m_font)
+        return true;
+    if (m_font == 0 || m_font == reinterpret_cast<PangoFont*>(-1)
+        || other.m_font == 0 || other.m_font == reinterpret_cast<PangoFont*>(-1))
+        return false;
+    PangoFontDescription* thisDesc = pango_font_describe(m_font);
+    PangoFontDescription* otherDesc = pango_font_describe(other.m_font);
+    bool result = pango_font_description_equal(thisDesc, otherDesc);
+    pango_font_description_free(otherDesc);
+    pango_font_description_free(thisDesc);
+    return result;
+}
+
+}
diff --git a/WebCore/platform/graphics/gtk/GlyphPageTreeNodePango.cpp b/WebCore/platform/graphics/gtk/GlyphPageTreeNodePango.cpp
new file mode 100644 (file)
index 0000000..429c131
--- /dev/null
@@ -0,0 +1,93 @@
+/*
+ * Copyright (C) 2006, 2007 Apple Inc. All rights reserved.
+ * Copyright (C) 2006 Michael Emmel mike.emmel@gmail.com
+ * Copyright (C) 2007 Alp Toker <alp.toker@collabora.co.uk>
+ * Copyright (C) 2007 Pioneer Research Center USA, Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1.  Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ * 2.  Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ * 3.  Neither the name of Apple Computer, Inc. ("Apple") nor the names of
+ *     its contributors may be used to endorse or promote products derived
+ *     from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "GlyphPageTreeNode.h"
+
+#include "SimpleFontData.h"
+#include <pango/pango-font.h>
+
+namespace WebCore {
+
+static PangoGlyph pango_font_get_glyph(PangoFont* font, PangoContext* context, gunichar wc)
+{
+    PangoGlyph result = 0;
+    gchar buffer[7];
+
+    gint  length = g_unichar_to_utf8(wc, buffer);
+    g_return_val_if_fail(length, 0);
+
+    GList* items = pango_itemize(context, buffer, 0, length, NULL, NULL);
+
+    if (g_list_length(items) == 1) {
+        PangoGlyphString* glyphs = pango_glyph_string_new();
+
+        pango_shape(buffer, length, &((PangoItem*)items->data)->analysis, glyphs);
+
+        if (glyphs->num_glyphs == 1)
+            result = glyphs->glyphs[0].glyph;
+        else
+            g_warning("didn't get 1 glyph but %d", glyphs->num_glyphs);
+
+        pango_glyph_string_free(glyphs);
+    }
+
+    g_list_foreach(items, (GFunc)pango_item_free, NULL);
+    g_list_free(items);
+
+    return result;
+}
+
+bool GlyphPage::fill(unsigned offset, unsigned length, UChar* buffer, unsigned bufferLength, const SimpleFontData* fontData)
+{
+    // The bufferLength will be greater than the glyph page size if the buffer has Unicode supplementary characters.
+    // We won't support this for now.
+    if (bufferLength > GlyphPage::size)
+        return false;
+
+    if (!fontData->m_font.m_font || fontData->m_font.m_font == reinterpret_cast<PangoFont*>(-1))
+        return false;
+
+    bool haveGlyphs = false;
+    for (unsigned i = 0; i < length; i++) {
+        Glyph glyph = pango_font_get_glyph(fontData->m_font.m_font, fontData->m_font.m_context, buffer[i]);
+        if (!glyph)
+            setGlyphDataForIndex(offset + i, 0, 0);
+        else {
+            setGlyphDataForIndex(offset + i, glyph, fontData);
+            haveGlyphs = true;
+        }
+    }
+
+    return haveGlyphs;
+}
+
+}
diff --git a/WebCore/platform/graphics/gtk/SimpleFontDataPango.cpp b/WebCore/platform/graphics/gtk/SimpleFontDataPango.cpp
new file mode 100644 (file)
index 0000000..37bb734
--- /dev/null
@@ -0,0 +1,144 @@
+/*
+ * Copyright (C) 2006 Apple Computer, Inc.  All rights reserved.
+ * Copyright (C) 2006 Michael Emmel mike.emmel@gmail.com
+ * Copyright (C) 2007, 2008 Alp Toker <alp@atoker.com>
+ * Copyright (C) 2007 Holger Hans Peter Freyther
+ * Copyright (C) 2007 Pioneer Research Center USA, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1.  Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ * 2.  Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ * 3.  Neither the name of Apple Computer, Inc. ("Apple") nor the names of
+ *     its contributors may be used to endorse or promote products derived
+ *     from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "SimpleFontData.h"
+
+#include "FloatRect.h"
+#include "Font.h"
+#include "FontCache.h"
+#include "FontDescription.h"
+#include "GlyphBuffer.h"
+#include <cairo.h>
+#include <unicode/uchar.h>
+#include <unicode/unorm.h>
+#include <wtf/MathExtras.h>
+
+namespace WebCore {
+
+void SimpleFontData::platformInit()
+{
+    cairo_font_extents_t font_extents;
+    cairo_text_extents_t text_extents;
+    cairo_scaled_font_extents(m_font.m_scaledFont, &font_extents);
+    m_ascent = static_cast<int>(font_extents.ascent);
+    m_descent = static_cast<int>(font_extents.descent);
+    m_lineSpacing = static_cast<int>(font_extents.height);
+    cairo_scaled_font_text_extents(m_font.m_scaledFont, "x", &text_extents);
+    m_xHeight = text_extents.height;
+    cairo_scaled_font_text_extents(m_font.m_scaledFont, " ", &text_extents);
+    m_spaceWidth =  static_cast<int>(text_extents.x_advance);
+    m_lineGap = m_lineSpacing - m_ascent - m_descent;
+}
+
+void SimpleFontData::platformDestroy()
+{
+    if (!isCustomFont()) {
+
+        if (m_font.m_font && m_font.m_font != reinterpret_cast<PangoFont*>(-1)) {
+            g_object_unref(m_font.m_font);
+            m_font.m_font = 0;
+        }
+
+        if (m_font.m_context) {
+            g_object_unref (m_font.m_context);
+            m_font.m_context = 0;
+        }
+
+        if (m_font.m_scaledFont) {
+            cairo_scaled_font_destroy(m_font.m_scaledFont);
+            m_font.m_scaledFont = 0;
+        }
+    }
+
+    delete m_smallCapsFontData;
+}
+
+SimpleFontData* SimpleFontData::smallCapsFontData(const FontDescription& fontDescription) const
+{
+    if (!m_smallCapsFontData) {
+        FontDescription desc = FontDescription(fontDescription);
+        desc.setSpecifiedSize(0.70f*fontDescription.computedSize());
+        const FontPlatformData* pdata = new FontPlatformData(desc, desc.family().family());
+        m_smallCapsFontData = new SimpleFontData(*pdata);
+    }
+    return m_smallCapsFontData;
+}
+
+bool SimpleFontData::containsCharacters(const UChar* characters, int length) const
+{
+    bool result = true;
+
+    PangoCoverage* requested = pango_coverage_from_bytes((guchar*)characters, length);
+    PangoCoverage* available = pango_font_get_coverage(m_font.m_font, pango_language_get_default());
+    pango_coverage_max(requested, available);
+
+    for (unsigned i = 0; i < length; i++) {
+        if (PANGO_COVERAGE_NONE == pango_coverage_get(requested, i)) {
+            result = false;
+            break;
+        }
+    }
+
+    pango_coverage_unref(requested);
+    pango_coverage_unref(available);
+
+    return result;
+}
+
+void SimpleFontData::determinePitch()
+{
+    m_treatAsFixedPitch = m_font.isFixedPitch();
+}
+
+float SimpleFontData::platformWidthForGlyph(Glyph glyph) const
+{
+    ASSERT(m_font.m_scaledFont);
+
+    cairo_glyph_t cglyph = { glyph, 0, 0 };
+    cairo_text_extents_t extents;
+    cairo_scaled_font_glyph_extents(m_font.m_scaledFont, &cglyph, 1, &extents);
+
+    float w = (float)m_spaceWidth;
+    if (cairo_scaled_font_status(m_font.m_scaledFont) == CAIRO_STATUS_SUCCESS && extents.x_advance != 0)
+        w = (float)extents.x_advance;
+    return w;
+}
+
+void SimpleFontData::setFont(cairo_t* cr) const
+{
+    ASSERT(cr);
+    m_font.setFont(cr);
+}
+
+}
index 872eb0e..64f32dc 100644 (file)
@@ -394,6 +394,19 @@ AC_ARG_ENABLE(fast_malloc,
               [],[if test "$enable_debug" = "yes"; then enable_fast_malloc="no"; else enable_fast_malloc="yes"; fi])
 AC_MSG_RESULT([$enable_fast_malloc])
 
+# determine the font backend
+AC_MSG_CHECKING([the font backend to use])
+AC_ARG_WITH(font_backend,
+            AC_HELP_STRING([--with-font-backend=@<:@freetype/pango@:>@],
+                           [Select font backend [default=freetype]]),
+            [],[with_font_backend="freetype"])
+
+case "$with_font_backend" in
+     freetype|pango) ;;
+     *) AC_MSG_ERROR([Invalid font backend: must be freetype or pango.]) ;;
+esac
+AC_MSG_RESULT([$with_font_backend])
+
 # Add '-g' flag to gcc if it's debug build
 if test "$enable_debug" = "yes"; then
    CXXFLAGS="$CXXFLAGS -g"
@@ -478,6 +491,10 @@ AM_CONDITIONAL([TARGET_DIRECTFB], [test "$with_target" = "directfb"])
 AM_CONDITIONAL([USE_CURL], [test "$with_http_backend" = "curl"])
 AM_CONDITIONAL([USE_SOUP], [test "$with_http_backend" = "soup"])
 
+# Font backend conditionals
+AM_CONDITIONAL([USE_FREETYPE], [test "$with_font_backend" = "freetype"])
+AM_CONDITIONAL([USE_PANGO], [test "$with_font_backend" = "pango"])
+
 # WebKit feature conditionals
 AM_CONDITIONAL([ENABLE_DEBUG],[test "$enable_debug" = "yes"])
 AM_CONDITIONAL([ENABLE_CROSS_DOCUMENT_MESSAGING],[test "$enable_cross_document_messaging" = "yes"])
@@ -513,6 +530,7 @@ Build configuration:
  Code coverage support             : $enable_coverage
  Unicode backend                   : $unicode_backend
  HTTP backend                      : $with_http_backend
+ Font backend                      : $with_font_backend
  Optimized memory allocator        : $enable_fast_malloc
 Features:
  HTML5 cross-document messaging    : $enable_cross_document_messaging