2007-12-19 Sven Herzberg <sven@imendio.com>
authoralp@webkit.org <alp@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 19 Dec 2007 18:00:23 +0000 (18:00 +0000)
committeralp@webkit.org <alp@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 19 Dec 2007 18:00:23 +0000 (18:00 +0000)
        Reviewed by Alp Toker.

        Replace the fontconfig/freetype based font management with a pango
        based one. Fixes:
        http://bugs.webkit.org/show_bug.cgi?id=15229

        * platform/gtk/FontDataGtk.cpp (FontData::platformDestroy()): updated
        the platform specific destroy code
        (FontData::containsCharacters()): implemented font coverage with pango
        * platform/gtk/FontPlatformData.h: replaced fontconfig specific
        members with pango-specific ones
        * platform/gtk/FontPlatformDataGtk.cpp: added static members for the
        FontPlatformData class
        (FontPlatformData::FontPlatformData()): implemented the font-matching
        with a PangoFontDescription instead of an FcPattern; initialize the
        scaled font by using the API for PangoCairoFont
        (FontPlatformData::init()): initialize the PangoFontMap and set up a
        hash table to translate the font family name into a font family
        (FontPlatformData::isFixedPitch()): implemented by querying the
        PangoFontFamily
        (FontPlatformData::operator==): compare the FontPlatformData by
        comparing the font pointers or the described fonts
        * platform/gtk/GlyphPageTreeNodeGtk.cpp (pango_font_get_glyph()):
        added a function to query a glyph from a PangoFont
        (GlyphPage::fill()): implemented the fill function with Pango instead
        of fontconfig/freetype

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

WebCore/ChangeLog
WebCore/platform/graphics/gtk/FontCacheGtk.cpp
WebCore/platform/graphics/gtk/FontDataGtk.cpp
WebCore/platform/graphics/gtk/FontPlatformData.h
WebCore/platform/graphics/gtk/FontPlatformDataGtk.cpp
WebCore/platform/graphics/gtk/GlyphPageTreeNodeGtk.cpp

index 1526d104db2585fef6ea67dfcfee41a8a12fcb49..6a90cd57897fdf67be51dfb2df22eacdb8e46153 100644 (file)
@@ -1,3 +1,32 @@
+2007-12-19  Sven Herzberg  <sven@imendio.com>
+
+        Reviewed by Alp Toker.
+
+        Replace the fontconfig/freetype based font management with a pango
+        based one. Fixes:
+        http://bugs.webkit.org/show_bug.cgi?id=15229
+
+        * platform/gtk/FontDataGtk.cpp (FontData::platformDestroy()): updated
+        the platform specific destroy code
+        (FontData::containsCharacters()): implemented font coverage with pango
+        * platform/gtk/FontPlatformData.h: replaced fontconfig specific
+        members with pango-specific ones
+        * platform/gtk/FontPlatformDataGtk.cpp: added static members for the
+        FontPlatformData class
+        (FontPlatformData::FontPlatformData()): implemented the font-matching
+        with a PangoFontDescription instead of an FcPattern; initialize the
+        scaled font by using the API for PangoCairoFont
+        (FontPlatformData::init()): initialize the PangoFontMap and set up a
+        hash table to translate the font family name into a font family
+        (FontPlatformData::isFixedPitch()): implemented by querying the
+        PangoFontFamily
+        (FontPlatformData::operator==): compare the FontPlatformData by
+        comparing the font pointers or the described fonts
+        * platform/gtk/GlyphPageTreeNodeGtk.cpp (pango_font_get_glyph()):
+        added a function to query a glyph from a PangoFont
+        (GlyphPage::fill()): implemented the fill function with Pango instead
+        of fontconfig/freetype
+
 2007-12-19  Alp Toker  <alp@atoker.com>
 
         Reviewed by Holger Freyther.
index 5caebc45a6f607f511e0e9b36673374b82632c38..98307b8372d010564bcd07d41d4b9bae3aad1ab4 100644 (file)
@@ -64,7 +64,7 @@ FontPlatformData* FontCache::getLastResortFallbackFont(const FontDescription& fo
 bool FontCache::fontExists(const FontDescription& fontDescription, const AtomicString& family)
 {
     FontPlatformData platformData(fontDescription, family);
-    return platformData.m_pattern != 0;
+    return platformData.m_font != 0;
 }
 
 FontPlatformData* FontCache::createFontPlatformData(const FontDescription& fontDescription, const AtomicString& family)
index 30b5e700c7cfc048ab221a057b21a621fda27637..2ae6591f1eb8617eda9c58b5396f7fee152372dc 100644 (file)
@@ -3,6 +3,7 @@
  * Copyright (C) 2006 Michael Emmel mike.emmel@gmail.com 
  * Copyright (C) 2007 Alp Toker <alp.toker@collabora.co.uk>
  * 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
@@ -62,8 +63,10 @@ void FontData::platformInit()
 
 void FontData::platformDestroy()
 {
-    if (m_font.m_pattern && ((FcPattern*)-1 != m_font.m_pattern))
-        FcPatternDestroy(m_font.m_pattern);
+    if (m_font.m_font && m_font.m_font != reinterpret_cast<PangoFont*>(-1))
+        g_object_unref(m_font.m_font);
+    if (m_font.m_context)
+        g_object_unref(m_font.m_context);
 
     if (m_font.m_scaledFont)
         cairo_scaled_font_destroy(m_font.m_scaledFont);
@@ -83,21 +86,23 @@ FontData* FontData::smallCapsFontData(const FontDescription& fontDescription) co
 
 bool FontData::containsCharacters(const UChar* characters, int length) const
 {
-    FT_Face face = cairo_ft_scaled_font_lock_face(m_font.m_scaledFont);
+    bool result = true;
 
-    if (!face)
-        return false;
+    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 (FcFreeTypeCharIndex(face, characters[i]) == 0) {
-            cairo_ft_scaled_font_unlock_face(m_font.m_scaledFont);
-            return false;
+        if (PANGO_COVERAGE_NONE == pango_coverage_get(requested, i)) {
+            result = false;
+            break;
         }
     }
 
-    cairo_ft_scaled_font_unlock_face(m_font.m_scaledFont);
+    pango_coverage_unref(available);
+    pango_coverage_unref(requested);
 
-    return true;
+    return result;
 }
 
 void FontData::determinePitch()
index 2855e759e6e66fed4c2e377865292463616da0fe..bd1621d2577a0d9f607d48a25906a5cd05c9b883 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
@@ -30,8 +31,7 @@
 #include "GlyphBuffer.h"
 #include "FontDescription.h"
 #include <cairo.h>
-#include <cairo-ft.h>
-#include <fontconfig/fcfreetype.h>
+#include <pango/pangocairo.h>
 
 namespace WebCore {
 
@@ -39,12 +39,14 @@ class FontPlatformData {
 public:
     class Deleted {};
     FontPlatformData(Deleted)
-        : m_pattern(reinterpret_cast<FcPattern*>(-1))
+        : m_context(0)
+        , m_font(reinterpret_cast<PangoFont*>(-1))
         , m_scaledFont(0)
         { }
 
     FontPlatformData()
-        : m_pattern(0)
+        : m_context(0)
+        , m_font(0)
         , m_scaledFont(0)
         { }
 
@@ -59,13 +61,17 @@ 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));
+        uintptr_t hashCodes[1] = {reinterpret_cast<uintptr_t>(m_scaledFont)};
+        return StringImpl::computeHash(reinterpret_cast<UChar*>(hashCodes), sizeof(hashCodes) / sizeof(UChar));
     }
 
     bool operator==(const FontPlatformData&) const;
 
-    FcPattern* m_pattern;
+    static PangoFontMap* m_fontMap;
+    static GHashTable  * m_hashTable;
+
+    PangoContext* m_context;
+    PangoFont* m_font;
     FontDescription m_fontDescription;
     cairo_scaled_font_t* m_scaledFont;
 };
index b542fac85454f3df9a068362ceb4dc50f7298d91..4a192b53d1dc14724ce98dfc224838f469c68820 100644 (file)
@@ -6,6 +6,7 @@
  * Copyright (C) 2006 Michael Emmel mike.emmel@gmail.com 
  * Copyright (C) 2007 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
 #include "CString.h"
 #include "PlatformString.h"
 #include "FontDescription.h"
-
-#include <cairo-ft.h>
 #include <cairo.h>
-#include <fontconfig/fcfreetype.h>
+#include <assert.h>
 
 namespace WebCore {
 
+PangoFontMap* FontPlatformData::m_fontMap = 0;
+GHashTable* FontPlatformData::m_hashTable = 0;
+
 FontPlatformData::FontPlatformData(const FontDescription& fontDescription, const AtomicString& familyName)
-    : m_pattern(0)
+    : m_context(0)
+    , m_font(0)
     , m_fontDescription(fontDescription)
     , m_scaledFont(0)
 {
     FontPlatformData::init();
 
-    CString familyNameString = familyName.domString().utf8();
-    const char* fcfamily = familyNameString.data();
-    int fcslant = FC_SLANT_ROMAN;
-    int fcweight = FC_WEIGHT_NORMAL;
-    float fcsize = fontDescription.computedSize();
-    if (fontDescription.italic())
-        fcslant = FC_SLANT_ITALIC;
-    if (fontDescription.bold())
-        fcweight = FC_WEIGHT_BOLD;
-
-    int type = fontDescription.genericFamily();
-
-    FcPattern* pattern = FcPatternCreate();
-    cairo_font_face_t* fontFace;
-    cairo_font_options_t* options;
-    cairo_matrix_t fontMatrix;
-
-    if (!FcPatternAddString(pattern, FC_FAMILY, reinterpret_cast<const FcChar8*>(fcfamily)))
-        goto freePattern;
-
-    switch (type) {
-        case FontDescription::SerifFamily:
-            fcfamily = "serif";
-            break;
-        case FontDescription::SansSerifFamily:
-            fcfamily = "sans-serif";
-            break;
-        case FontDescription::MonospaceFamily:
-            fcfamily = "monospace";
-            break;
-        case FontDescription::NoFamily:
-        case FontDescription::StandardFamily:
-        default:
-            fcfamily = "sans-serif";
+    CString  stored_family = familyName.domString().utf8();
+    gchar 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;
     }
 
-    if (!FcPatternAddString(pattern, FC_FAMILY, reinterpret_cast<const FcChar8*>(fcfamily)))
-        goto freePattern;
-    if (!FcPatternAddInteger(pattern, FC_SLANT, fcslant))
-        goto freePattern;
-    if (!FcPatternAddInteger(pattern, FC_WEIGHT, fcweight))
-        goto freePattern;
-    if (!FcPatternAddDouble(pattern, FC_PIXEL_SIZE, fcsize))
-        goto freePattern;
+    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);
 
-    FcConfigSubstitute(NULL, pattern, FcMatchPattern);
-    FcDefaultSubstitute(pattern);
+    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);
+    }
 
-    FcResult fcresult;
-    m_pattern = FcFontMatch(NULL, pattern, &fcresult);
     // FIXME: should we set some default font?
-    if (!m_pattern)
-        goto freePattern;
-    fontFace = cairo_ft_font_face_create_for_pattern(m_pattern);
-    cairo_matrix_t ctm;
-    cairo_matrix_init_scale(&fontMatrix, m_fontDescription.computedSize(), m_fontDescription.computedSize());
-    cairo_matrix_init_identity(&ctm);
-    options = cairo_font_options_create();
-    m_scaledFont = cairo_scaled_font_create(fontFace, &fontMatrix, &ctm, options);
-    cairo_font_face_destroy(fontFace);
-    cairo_font_options_destroy(options);
-
-freePattern:
-    FcPatternDestroy(pattern);
+    if (m_font)
+        m_scaledFont = pango_cairo_font_get_scaled_font(PANGO_CAIRO_FONT(m_font));
+
+    pango_font_description_free(description);
 }
 
 bool FontPlatformData::init()
@@ -117,10 +99,25 @@ bool FontPlatformData::init()
     if (initialized)
         return true;
     initialized = true;
-    if (!FcInit()) {
-        fprintf(stderr, "Can't init font config library\n");
-        return false;
+
+    if (!m_fontMap)
+        m_fontMap = pango_cairo_font_map_new();
+    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;
 }
 
@@ -130,10 +127,11 @@ FontPlatformData::~FontPlatformData()
 
 bool FontPlatformData::isFixedPitch()
 {
-    int spacing;
-    if (FcPatternGetInteger(m_pattern, FC_SPACING, 0, &spacing) == FcResultMatch)
-        return spacing == FC_MONO;
-    return false;
+    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
@@ -145,12 +143,18 @@ void FontPlatformData::setFont(cairo_t* cr) const
 
 bool FontPlatformData::operator==(const FontPlatformData& other) const
 {
-    if (m_pattern == other.m_pattern)
+    if (m_font == other.m_font)
         return true;
-    if (m_pattern == 0 || m_pattern == reinterpret_cast<FcPattern*>(-1)
-            || other.m_pattern == 0 || other.m_pattern == reinterpret_cast<FcPattern*>(-1))
+    if (m_font == 0 || m_font == reinterpret_cast<PangoFont*>(-1)
+            || other.m_font == 0 || other.m_font == reinterpret_cast<PangoFont*>(-1))
         return false;
-    return FcPatternEqual(m_pattern, other.m_pattern);
+
+    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;
 }
 
 }
index c0bcfa487915d2b1d44127b230f86d9849591ae7..6663cd407e81f87fed8276db3fba8e513e442db6 100644 (file)
@@ -2,6 +2,7 @@
  * 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
 #include "GlyphPageTreeNode.h"
 
 #include "FontData.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(UChar* buffer, unsigned bufferLength, const FontData* fontData)
 {
     // The bufferLength will be greater than the glyph page size if the buffer has Unicode supplementary characters.
@@ -42,13 +73,12 @@ bool GlyphPage::fill(UChar* buffer, unsigned bufferLength, const FontData* fontD
     if (bufferLength > GlyphPage::size)
         return false;
 
-    FT_Face face = cairo_ft_scaled_font_lock_face(fontData->m_font.m_scaledFont);
-    if (!face)
+    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 < GlyphPage::size; i++) {
-        Glyph glyph = FcFreeTypeCharIndex(face, buffer[i]);
+        Glyph glyph = pango_font_get_glyph(fontData->m_font.m_font, fontData->m_font.m_context, buffer[i]);
         if (!glyph)
             setGlyphDataForIndex(i, 0, 0);
         else {
@@ -57,8 +87,6 @@ bool GlyphPage::fill(UChar* buffer, unsigned bufferLength, const FontData* fontD
         }
     }
 
-    cairo_ft_scaled_font_unlock_face(fontData->m_font.m_scaledFont);
-
     return haveGlyphs;
 }