Author: fejj
Date: 2008-02-05 14:58:46 -0500 (Tue, 05 Feb 2008)
New Revision: 94935

Modified:
   trunk/moon/src/ChangeLog
   trunk/moon/src/font.cpp
   trunk/moon/src/font.h
Log:
2008-02-05  Jeffrey Stedfast  <[EMAIL PROTECTED]>

        * font.cpp: If a font is requested from a zip archive, extract the
        contents and try to figure out which font is the closest match to
        the one requested. Fixes bug #356044.



Modified: trunk/moon/src/ChangeLog
===================================================================
--- trunk/moon/src/ChangeLog    2008-02-05 19:50:41 UTC (rev 94934)
+++ trunk/moon/src/ChangeLog    2008-02-05 19:58:46 UTC (rev 94935)
@@ -1,3 +1,9 @@
+2008-02-05  Jeffrey Stedfast  <[EMAIL PROTECTED]>
+
+       * font.cpp: If a font is requested from a zip archive, extract the
+       contents and try to figure out which font is the closest match to
+       the one requested. Fixes bug #356044.
+
 2008-02-05  Chris Toshok  <[EMAIL PROTECTED]>
 
        * uielement.cpp (UIElement::FrontToBack): enable the rectangle

Modified: trunk/moon/src/font.cpp
===================================================================
--- trunk/moon/src/font.cpp     2008-02-05 19:50:41 UTC (rev 94934)
+++ trunk/moon/src/font.cpp     2008-02-05 19:58:46 UTC (rev 94935)
@@ -13,10 +13,18 @@
 #endif
 
 #include <glib.h>
+#include <glib/gstdio.h>
+
 #include <string.h>
 #include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <errno.h>
 
+#include "zip/unzip.h"
 #include "moon-path.h"
+#include "list.h"
 #include "font.h"
 
 #include FT_OUTLINE_H
@@ -34,13 +42,74 @@
        int top;
 };
 
+struct FontStyleInfo {
+       int weight;
+       int width;
+       int slant;
+};
 
+struct FontPackFile : public List::Node {
+       GPtrArray *faces;
+       char *path;
+       
+       FontPackFile (const char *path);
+       ~FontPackFile ();
+};
+
+struct FontPackFileFace {
+       FontPackFile *file;
+       FontStyleInfo style;
+       char *family_name;
+       int index;
+       
+       FontPackFileFace (FontPackFile *file, FT_Face face);
+       
+       ~FontPackFileFace ()
+       {
+               g_free (family_name);
+       }
+};
+
+struct FontPack {
+       List *fonts;
+       char *key;
+       char *dir;
+       
+       FontPack (const char *key)
+       {
+               this->key = g_strdup (key);
+               fonts = new List ();
+               dir = NULL;
+       }
+       
+       ~FontPack ()
+       {
+               delete fonts;
+               
+               if (dir != NULL) {
+                       g_rmdir (dir);
+                       g_free (dir);
+               }
+               
+               g_free (key);
+       }
+       
+       void CacheFileInfo (const char *filename, FT_Face face);
+};
+
 static GHashTable *font_cache = NULL;
+static GHashTable *fontpacks = NULL;
 static bool initialized = false;
 static FT_Library libft2;
 static double dpi;
 
 
+static void
+fontpack_delete (FontPack *pack)
+{
+       delete pack;
+}
+
 void
 font_init (void)
 {
@@ -56,6 +125,8 @@
        
        font_cache = g_hash_table_new ((GHashFunc) FcPatternHash, (GEqualFunc) 
FcPatternEqual);
        
+       fontpacks = g_hash_table_new_full (g_str_hash, g_str_equal, NULL, 
(GDestroyNotify) fontpack_delete);
+       
        pattern = FcPatternBuild (NULL, FC_FAMILY, FcTypeString, "Sans",
                                  FC_SIZE, FcTypeDouble, 10.0, NULL);
        
@@ -67,6 +138,20 @@
        initialized = true;
 }
 
+void
+font_shutdown (void)
+{
+       if (!initialized)
+               return;
+       
+       g_hash_table_destroy (font_cache);
+       g_hash_table_destroy (fontpacks);
+       
+       FT_Done_FreeType (libft2);
+       
+       initialized = false;
+}
+
 static int
 fc_weight (FontWeights weight)
 {
@@ -134,6 +219,129 @@
        }
 }
 
+
+static struct {
+       const char *name;
+       int value;
+} style_weights[] = {
+       { "Ultra Light", FC_WEIGHT_ULTRALIGHT },
+       { "Light",       FC_WEIGHT_LIGHT      },
+       { "Semi Bold",   FC_WEIGHT_DEMIBOLD   },
+       { "Ultra Bold",  FC_WEIGHT_ULTRABOLD  },
+       { "Medium",      FC_WEIGHT_MEDIUM     },
+       { "Bold",        FC_WEIGHT_BOLD       },
+       { "Black",       FC_WEIGHT_BLACK      }
+};
+
+static int
+style_weight_parse (const char *style)
+{
+       unsigned int i;
+       
+       if (style) {
+               for (i = 0; i < G_N_ELEMENTS (style_weights); i++) {
+                       if (strstr (style, style_weights[i].name))
+                               return style_weights[i].value;
+               }
+       }
+       
+       return FC_WEIGHT_NORMAL;
+}
+
+static struct {
+       const char *name;
+       int value;
+} style_widths[] = {
+       { "Ultra Condensed", FC_WIDTH_ULTRACONDENSED },
+       { "Extra Condensed", FC_WIDTH_EXTRACONDENSED },
+       { "Semi Condensed",  FC_WIDTH_SEMICONDENSED  },
+       { "Condensed",       FC_WIDTH_CONDENSED      },
+       { "Ultra Expanded",  FC_WIDTH_ULTRAEXPANDED  },
+       { "Extra Expanded",  FC_WIDTH_EXTRAEXPANDED  },
+       { "Semi Expanded",   FC_WIDTH_SEMIEXPANDED   },
+       { "Expanded",        FC_WIDTH_EXPANDED       }
+};
+
+static int
+style_width_parse (const char *style)
+{
+       unsigned int i;
+       
+       if (style) {
+               for (i = 0; i < G_N_ELEMENTS (style_widths); i++) {
+                       if (strstr (style, style_widths[i].name))
+                               return style_widths[i].value;
+               }
+       }
+       
+       return FC_WIDTH_NORMAL;
+}
+
+static struct {
+       const char *name;
+       int value;
+} style_slants[] = {
+       { "Oblique", FC_SLANT_OBLIQUE },
+       { "Italic",  FC_SLANT_ITALIC  }
+};
+
+static int
+style_slant_parse (const char *style)
+{
+       unsigned int i;
+       
+       if (style) {
+               for (i = 0; i < G_N_ELEMENTS (style_slants); i++) {
+                       if (strstr (style, style_slants[i].name))
+                               return style_slants[i].value;
+               }
+       }
+       
+       return FC_SLANT_ROMAN;
+}
+
+static void
+style_info_parse (const char *style, FontStyleInfo *info)
+{
+       info->weight = style_weight_parse (style);
+       info->width = style_width_parse (style);
+       info->slant = style_slant_parse (style);
+}
+
+static const char *
+style_name (FontStyleInfo *style, char *namebuf)
+{
+       char *p;
+       uint i;
+       
+       strcpy (namebuf, "Regular");
+       p = namebuf;
+       
+       for (i = 0; i < G_N_ELEMENTS (style_widths); i++) {
+               if (style_widths[i].value == style->width) {
+                       p = g_stpcpy (p, style_widths[i].name);
+                       break;
+               }
+       }
+       
+       for (i = 0; i < G_N_ELEMENTS (style_weights); i++) {
+               if (style_weights[i].value == style->weight) {
+                       p = g_stpcpy (p, style_weights[i].name);
+                       break;
+               }
+       }
+       
+       for (i = 0; i < G_N_ELEMENTS (style_slants); i++) {
+               if (style_slants[i].value == style->slant) {
+                       p = g_stpcpy (p, style_slants[i].name);
+                       break;
+               }
+       }
+       
+       return namebuf;
+}
+
+
 static const FT_Matrix invert_y = {
         65535, 0,
         0, -65535,
@@ -142,56 +350,432 @@
 
 #define LOAD_FLAGS (FT_LOAD_NO_BITMAP | FT_LOAD_TARGET_NORMAL)
 
-TextFont::TextFont (FcPattern *pattern, const char *name)
+static bool
+mktmpname (char *buf, size_t sz, const char *base)
 {
-       FcChar8 *filename = NULL;
-       FcPattern *matched, *sans;
-       bool retried = false;
+       char *outend = buf + (sz - 8);
+       const char *inptr = base;
+       char *outptr = buf;
+       
+       if (sz < 8)
+               return false;
+       
+       while (*inptr && outptr < outend)
+               *outptr++ = *inptr++;
+       
+       strcpy (outptr, ".XXXXXX");
+       
+       return true;
+}
+
+static bool
+ExtractFile (unzFile zip, int fd)
+{
+       int nwritten, nread;
+       char buf[4096];
+       ssize_t n;
+       
+       do {
+               n = 0;
+               if ((nread = unzReadCurrentFile (zip, buf, sizeof (buf))) > 0) {
+                       nwritten = 0;
+                       
+                       do {
+                               do {
+                                       n = write (fd, buf + nwritten, nread - 
nwritten);
+                               } while (n == -1 && errno == EINTR);
+                               
+                               if (n == -1)
+                                       break;
+                               
+                               nwritten += n;
+                       } while (nwritten < nread);
+                       
+                       if (n == -1)
+                               break;
+               }
+       } while (nread > 0);
+       
+       if (nread != 0 || n == -1 || fsync (fd) == -1) {
+               close (fd);
+               
+               return false;
+       }
+       
+       close (fd);
+       
+       return true;
+}
+
+static char *
+my_mkdtemp (char *tmpdir)
+{
+       char *path, *xxx;
+       size_t n;
+       
+       if ((n = strlen (tmpdir)) < 6)
+               return NULL;
+       
+       xxx = tmpdir + (n - 6);
+       if (strcmp (xxx, "XXXXXX") != 0)
+               return NULL;
+       
+       do {
+               if (!(path = mktemp (tmpdir)))
+                       return NULL;
+               
+               if (g_mkdir_with_parents (tmpdir, 0700) != -1)
+                       break;
+               
+               if (errno != EEXIST) {
+                       // don't bother trying again...
+                       return NULL;
+               }
+               
+               // that path already exists, try a new one...
+               strcpy (xxx, "XXXXXX");
+       } while (1);
+       
+       return tmpdir;
+}
+
+FontPackFileFace::FontPackFileFace (FontPackFile *file, FT_Face face)
+{
+       style_info_parse (face->style_name, &style);
+       family_name = g_strdup (face->family_name);
+       index = face->face_index;
+       this->file = file;
+}
+
+FontPackFile::FontPackFile (const char *path)
+{
+       this->path = g_strdup (path);
+       faces = NULL;
+}
+
+FontPackFile::~FontPackFile ()
+{
+       if (faces != NULL) {
+               FontPackFileFace *face;
+               
+               for (uint i = 0; i < faces->len; i++) {
+                       face = (FontPackFileFace *) faces->pdata[i];
+                       delete face;
+               }
+               
+               g_ptr_array_free (faces, true);
+       }
+       
+       unlink (path);
+}
+
+void
+FontPack::CacheFileInfo (const char *filename, FT_Face face)
+{
+       int i = 0, nfaces = face->num_faces;
+       FontPackFileFace *fface;
+       FontPackFile *file;
+       
+       file = new FontPackFile (filename);
+       file->faces = g_ptr_array_new ();
+       
+       do {
+               if (i > 0 && FT_New_Face (libft2, filename, i, &face) != 0)
+                       break;
+               
+               fface = new FontPackFileFace (file, face);
+               g_ptr_array_add (file->faces, fface);
+               
+               FT_Done_Face (face);
+               i++;
+       } while (i < nfaces);
+       
+       fonts->Append (file);
+}
+
+static FontPack *
+ExtractFontPack (const char *path)
+{
+       FontPack *pack = NULL;
+       char filename[256];
+       unz_file_info info;
+       GString *packdir;
+       const char *name;
+       FT_Face face;
+       unzFile zip;
+       size_t n;
+       int fd;
+       
+       if (!(zip = unzOpen (path))) {
+               // guess it's not a zip archive, afterall.
+               return NULL;
+       }
+       
+       if (unzGoToFirstFile (zip) != UNZ_OK) {
+               unzClose (zip);
+               return NULL;
+       }
+       
+       // get the zip file's base name
+       if (!(name = strrchr (path, '/')))
+               name = path;
+       else
+               name++;
+       
+       // create a tmpdir to extract the fonts to
+       packdir = g_string_new (g_get_tmp_dir ());
+       g_string_append_c (packdir, '/');
+       g_string_append (packdir, name);
+       g_string_append (packdir, ".XXXXXX");
+       
+       if (!my_mkdtemp (packdir->str)) {
+               g_string_free (packdir, true);
+               unzClose (zip);
+               return NULL;
+       }
+       
+       g_string_append_c (packdir, '/');
+       n = packdir->len;
+       
+       do {
+               if (unzOpenCurrentFile (zip) != UNZ_OK)
+                       break;
+               
+               unzGetCurrentFileInfo (zip, &info, filename, sizeof (filename),
+                                      NULL, 0, NULL, 0);
+               
+               d(fprintf (stderr, "\t\t* extracting %s...\n", filename));
+               
+               g_string_append (packdir, filename);
+               
+               // we first try using the file's original name...
+               fd = open (packdir->str, O_WRONLY | O_CREAT | O_EXCL, 0600);
+               if (fd == -1 && errno == EEXIST) {
+                       // there must be several files in the archive with the 
same name?
+                       g_string_append (packdir, ".XXXXXX");
+                       fd = g_mkstemp (packdir->str);
+               }
+               
+               if (fd != -1) {
+                       if (ExtractFile (zip, fd) && FT_New_Face (libft2, 
packdir->str, 0, &face) == 0) {
+                               // this is a valid font file...
+                               if (pack == NULL)
+                                       pack = new FontPack (path);
+                               
+                               // cache font info
+                               pack->CacheFileInfo (packdir->str, face);
+                       } else {
+                               // failed to extract or not a font file, delete 
it
+                               unlink (packdir->str);
+                       }
+               }
+               
+               g_string_truncate (packdir, n);
+               unzCloseCurrentFile (zip);
+       } while (unzGoToNextFile (zip) == UNZ_OK);
+       
+       unzClose (zip);
+       
+       if (pack == NULL) {
+               g_rmdir (packdir->str);
+               g_string_free (packdir, true);
+               return NULL;
+       }
+       
+       g_string_truncate (packdir, n);
+       pack->dir = packdir->str;
+       
+       g_string_free (packdir, false);
+       
+       return pack;
+}
+
+
+struct FontFaceSimilarity {
+       FontPackFileFace *face;
+       int weight;
+       int width;
+       int slant;
+};
+
+
+bool
+TextFont::OpenZipArchiveFont (FcPattern *pattern, const char *path)
+{
+       char stylebuf1[128], stylebuf2[128];
+       FontFaceSimilarity similar;
+       FontPackFileFace *fface;
+       FcChar8 *family_name;
+       FontStyleInfo style;
+       FontPackFile *file;
+       FontPack *pack;
+       uint i;
+       
+       if (FcPatternGetString (pattern, FC_FAMILY, 0, &family_name) != 
FcResultMatch)
+               return false;
+       
+       if (FcPatternGetInteger (pattern, FC_WEIGHT, 0, &style.weight) != 
FcResultMatch)
+               return false;
+       
+       if (FcPatternGetInteger (pattern, FC_WIDTH, 0, &style.width) != 
FcResultMatch)
+               return false;
+       
+       if (FcPatternGetInteger (pattern, FC_SLANT, 0, &style.slant) != 
FcResultMatch)
+               return false;
+       
+       if (!(pack = (FontPack *) g_hash_table_lookup (fontpacks, path))) {
+               d(fprintf (stderr, "\t* opening zip archive...\n"));
+               if (!(pack = ExtractFontPack (path)))
+                       return false;
+               
+               g_hash_table_insert (fontpacks, pack->key, pack);
+       } else {
+               d(fprintf (stderr, "\t* reusing an extracted zip 
archive...\n"));
+       }
+       
+       similar.weight = INT_MAX;
+       similar.width = INT_MAX;
+       similar.slant = INT_MAX;
+       similar.face = NULL;
+       
+       file = (FontPackFile *) pack->fonts->First ();
+       while (file != NULL) {
+               for (i = 0; i < file->faces->len; i++) {
+                       fface = (FontPackFileFace *) file->faces->pdata[i];
+                       if (!fface->family_name)
+                               continue;
+                       
+                       d(fprintf (stderr, "\t\t* checking if '%s' matches 
'%s'... ", fface->family_name, family_name));
+                       if (strcmp ((const char *) family_name, 
fface->family_name) != 0) {
+                               d(fprintf (stderr, "no\n"));
+                               continue;
+                       }
+                       
+                       d(fprintf (stderr, "yes\n\t\t* checking if '%s' matches 
'%s'... ",
+                                  style_name (&fface->style, stylebuf1), 
style_name (&style, stylebuf2)));
+                       
+                       if (fface->style.weight == style.weight &&
+                           fface->style.width == style.width &&
+                           fface->style.slant == style.slant) {
+                               // found an exact match
+                               d(fprintf (stderr, "yes\n"));
+                               goto found;
+                       }
+                       
+                       // not an exact match, but similar...
+                       if (abs (fface->style.weight - style.weight) < 
similar.weight &&
+                           abs (fface->style.width - style.width) < 
similar.width &&
+                           abs (fface->style.slant - style.slant) < 
similar.slant) {
+                               d(fprintf (stderr, "no, but is the closest 
match so far\n"));
+                               similar.weight = abs (fface->style.weight - 
style.weight);
+                               similar.width = abs (fface->style.width - 
style.width);
+                               similar.slant = abs (fface->style.slant - 
style.slant);
+                               similar.face = fface;
+                       } else {
+                               d(fprintf (stderr, "no\n"));
+                       }
+               }
+               
+               file = (FontPackFile *) file->next;
+       }
+       
+       // we were unable to find an exact match...
+       
+       if (similar.face == NULL) {
+               // no similar fonts, I guess we just fail?
+               return false;
+       }
+       
+       // use the closest match...
+       file = similar.face->file;
+       fface = similar.face;
+       
+found:
+       
+       d(fprintf (stderr, "\t\t* using font '%s, %s'\n", fface->family_name, 
style_name (&fface->style, stylebuf1)));
+       
+       return FT_New_Face (libft2, file->path, fface->index, &face) == 0;
+}
+
+TextFont::TextFont (FcPattern *pattern, bool fromFile, const char *name)
+{
+       const char *fallback_fonts[] = { "Lucida Sans Unicode", "Lucida Sans", 
"Sans" };
+       FcChar8 *family = NULL, *filename = NULL;
+       FcPattern *matched, *fallback;
+       uint attempt = 0;
        FcResult result;
+       FT_Error err;
        double size;
        int id;
        
-       d(fprintf (stderr, "Attempting to load %s\n", name));
+       d(fprintf (stderr, "\nAttempting to load %s\n", name));
        
        FcPatternGetDouble (pattern, FC_PIXEL_SIZE, 0, &size);
        FcPatternGetDouble (pattern, FC_SCALE, 0, &scale);
        FcPatternReference (pattern);
        matched = pattern;
        
-       while (true) {
+       do {
                if (FcPatternGetString (matched, FC_FILE, 0, &filename) != 
FcResultMatch)
                        goto fail;
                
-               d(fprintf (stderr, "\t* loading font from `%s'\n", filename));
-               
                if (FcPatternGetInteger (matched, FC_INDEX, 0, &id) != 
FcResultMatch)
                        goto fail;
                
-               d(fprintf (stderr, "\t* using font index=%d\n", id));
-               
-               if (FT_New_Face (libft2, (const char *) filename, id, &face) == 
0)
+               d(fprintf (stderr, "\t* loading font from `%s' (index=%d)... ", 
filename, id));
+               if ((err = FT_New_Face (libft2, (const char *) filename, id, 
&face)) == 0) {
+                       d(fprintf (stderr, "success!\n"));
                        break;
+               } else {
+                       d(fprintf (stderr, "failed :(\n"));
+               }
                
+               if (fromFile && err == FT_Err_Unknown_File_Format) {
+                       // fromFile indicates that an absolute path was given...
+                       // check if it is a zipped font collection.
+                       if (OpenZipArchiveFont (pattern, (const char *) 
filename)) {
+                               d(fprintf (stderr, "\t* success!\n"));
+                               break;
+                       }
+                       
+                       fromFile = false;
+                       
+                       // We couldn't find the font in the zip archive, but if 
the pattern
+                       // has a family specified then try checking if we have 
a font that
+                       // matches it on the system.
+                       if (FcPatternGetString (matched, FC_FAMILY, 0, &family) 
== FcResultMatch) {
+                               d(fprintf (stderr, "\t* falling back to 
specified family, %s...\n", family));
+                               fallback = FcPatternBuild (NULL, FC_FAMILY, 
FcTypeString, family,
+                                                          FC_PIXEL_SIZE, 
FcTypeDouble, size,
+                                                          FC_DPI, 
FcTypeDouble, dpi, NULL);
+                               
+                               FcPatternDestroy (matched);
+                               matched = FcFontMatch (NULL, fallback, &result);
+                               FcPatternDestroy (fallback);
+                               filename = NULL;
+                               continue;
+                       }
+               }
+               
        fail:
                d(fprintf (stderr, "\t* failed.\n"));
                
-               if (retried) {
-                       face = NULL;
-                       break;
+               if (attempt < G_N_ELEMENTS (fallback_fonts)) {
+                       d(fprintf (stderr, "\t* falling back to %s...\n", 
fallback_fonts[attempt]));
+                       
+                       fallback = FcPatternBuild (NULL, FC_FAMILY, 
FcTypeString, fallback_fonts[attempt],
+                                                  FC_PIXEL_SIZE, FcTypeDouble, 
size,
+                                                  FC_DPI, FcTypeDouble, dpi, 
NULL);
+                       
+                       FcPatternDestroy (matched);
+                       matched = FcFontMatch (NULL, fallback, &result);
+                       FcPatternDestroy (fallback);
+                       filename = NULL;
                }
                
-               d(fprintf (stderr, "\t* falling back to Sans...\n"));
-               
-               sans = FcPatternBuild (NULL, FC_FAMILY, FcTypeString, "sans",
-                                      FC_PIXEL_SIZE, FcTypeDouble, size,
-                                      FC_DPI, FcTypeDouble, dpi, NULL);
-               
-               FcPatternDestroy (matched);
-               matched = FcFontMatch (NULL, sans, &result);
-               FcPatternDestroy (sans);
-               filename = NULL;
-               retried = true;
-       }
+               face = NULL;
+               attempt++;
+       } while (attempt <= G_N_ELEMENTS (fallback_fonts));
        
        FcPatternDestroy (matched);
        
@@ -239,7 +823,7 @@
 }
 
 TextFont *
-TextFont::Load (FcPattern *pattern, const char *name)
+TextFont::Load (FcPattern *pattern, bool fromFile, const char *name)
 {
        TextFont *font;
        
@@ -248,7 +832,7 @@
                return font;
        }
        
-       return new TextFont (pattern, name);
+       return new TextFont (pattern, fromFile, name);
 }
 
 void
@@ -739,7 +1323,9 @@
        if (set & FontMaskFilename) {
                FcPatternAddString (pattern, FC_FILE, (FcChar8 *) filename);
                FcPatternAddInteger (pattern, FC_INDEX, index);
-       } else {
+       }
+       
+       if (!(set & FontMaskFilename) || (set & FontMaskFamily)) {
                families = g_strsplit (GetFamily (), ",", -1);
                for (i = 0; families[i]; i++)
                        FcPatternAddString (pattern, FC_FAMILY, (FcChar8 *) 
g_strstrip (families[i]));
@@ -779,7 +1365,7 @@
        if (font == NULL) {
                d(name = ToString ());
                pattern = CreatePattern ();
-               font = TextFont::Load (pattern, name);
+               font = TextFont::Load (pattern, (set & FontMaskFilename), name);
                FcPatternDestroy (pattern);
                d(g_free (name));
        }

Modified: trunk/moon/src/font.h
===================================================================
--- trunk/moon/src/font.h       2008-02-05 19:50:41 UTC (rev 94934)
+++ trunk/moon/src/font.h       2008-02-05 19:58:46 UTC (rev 94935)
@@ -118,8 +118,10 @@
        
        GlyphInfo *glyphs;
        
-       TextFont (FcPattern *pattern, const char *name);
+       TextFont (FcPattern *pattern, bool fromFile, const char *name);
        
+       bool OpenZipArchiveFont (FcPattern *pattern, const char *path);
+       
        void RenderGlyphPath (cairo_t *cr, GlyphInfo *glyph, double x, double 
y);
        void RenderGlyphBitmap (cairo_t *cr, GlyphInfo *glyph, double x, double 
y);
        
@@ -130,7 +132,7 @@
        void ref ();
        void unref ();
        
-       static TextFont *Load (FcPattern *pattern, const char *name);
+       static TextFont *Load (FcPattern *pattern, bool fromFile, const char 
*name);
        
        GlyphInfo *GetGlyphInfo (gunichar unichar);
        GlyphInfo *GetGlyphInfoByIndex (uint32_t index);

_______________________________________________
Mono-patches maillist  -  [email protected]
http://lists.ximian.com/mailman/listinfo/mono-patches

Reply via email to