Embedding font data
- From: Martin Kretzschmar <m_kretzschmar gmx net>
- To: Gnome Print <gnome-print-list gnome org>
- Subject: Embedding font data
- Date: Fri Mar 14 12:05:06 2003
Hi,
As I said in December, I need methods to download font data (i.e. font
files in memory) to gnome-print. Attached is a patch to implement this.
I have tested it with the print-preview in gpdf and I've written a test
program using the print job (and hence print-meta) with ps and pdf
printers.
Comments?
Thanks,
Martin
? OOBR
? cscope.files
? cscope.out
? tests/NimbusRomNo9L-ReguItal.pfb
? tests/font-embedding
? tests/font-embedding.c
cvs server: Diffing .
Index: ChangeLog
===================================================================
RCS file: /cvs/gnome/libgnomeprint/ChangeLog,v
retrieving revision 1.312
diff -u -r1.312 ChangeLog
--- ChangeLog 13 Mar 2003 21:50:03 -0000 1.312
+++ ChangeLog 14 Mar 2003 16:46:06 -0000
@@ -1,3 +1,37 @@
+2003-03-14 Martin Kretzschmar <m_kretzschmar gmx net>
+
+ * libgnomeprint/gnome-font-private.h: add fields to GnomeFontFace
+ for storing font data
+
+ * libgnomeprint/gnome-font-face.c (gnome_font_face_finalize)
+ (gnome_font_face_download, gff_unlink_temp_file)
+ (gff_write_temp_data_file, gff_font_entry_type_from_data):
+ implement font embedding
+ (gff_entry_fill_in_face, gnome_font_face_find)
+ (gnome_font_face_find_closest): rename gff_face_from_entry to
+ gff_entry_fill_in_face which is what it does
+
+ * libgnomeprint/gnome-font-face.h: add prototype for
+ gnome_font_face_download guarded by _UNSTABLE_API
+
+ * libgnomeprint/gnome-print-meta.c (METAFILE_SIGNATURE): bump to
+ 3.1
+ (GnomeMetaType): add FONT_DATA pseudo opcode
+ (GnomeMetaFontType, GnomeMetaEmbeddedFace)
+ (gnome_print_meta_init, meta_showpage, meta_glyphlist)
+ (meta_close, gpm_skip_string, gpm_render, embedded_face_destroy)
+ (gpm_font_face_use_fill_slot, gpm_font_face_download_real)
+ (gpm_queue_font_face_download, gpm_encode_downloaded_font_face)
+ (gpm_encode_font, download_font, decode_font): implement
+ serialization of downloaded font data in a meta file
+
+ * tests/font-embedding.c: test font embedding
+
+ * tests/Makefile.am: built font-embedding test program
+
+ * tests/generate.c (parse_command_line),
+ * libgnomeprint/gnome-print-job.c (gnome_print_job_print): fix typo
+
2003-03-13 Christian Rose <menthos menthos com>
* configure.in: Added "ml" to ALL_LINGUAS.
cvs server: Diffing data
cvs server: Diffing data/models
cvs server: Diffing data/printers
cvs server: Diffing doc
cvs server: Diffing doc/reference
cvs server: Diffing doc/reference/tmpl
cvs server: Diffing fonts
cvs server: Diffing installer
cvs server: Diffing libgnomeprint
Index: libgnomeprint/gnome-font-face.c
===================================================================
RCS file: /cvs/gnome/libgnomeprint/libgnomeprint/gnome-font-face.c,v
retrieving revision 1.69
diff -u -r1.69 gnome-font-face.c
--- libgnomeprint/gnome-font-face.c 2 Feb 2003 21:20:53 -0000 1.69
+++ libgnomeprint/gnome-font-face.c 14 Mar 2003 16:46:10 -0000
@@ -33,9 +33,12 @@
#include <string.h>
#include <stdarg.h>
#include <locale.h>
+#include <unistd.h>
#include <freetype/ftoutln.h>
+#define GNOME_PRINT_UNSTABLE_API
+
#include <libgnomeprint/gnome-print-private.h>
#include <libgnomeprint/gnome-font-private.h>
#include <libgnomeprint/gnome-print-i18n.h>
@@ -186,6 +189,11 @@
face->psname = NULL;
}
+ if (face->font_data) {
+ g_free (face->font_data);
+ face->font_data = NULL;
+ }
+
/* Fonts should reference us */
g_assert (face->fonts == NULL);
@@ -494,7 +502,7 @@
* Creates new face and creates link with FontEntry
*/
static void
-gff_face_from_entry (GPFontEntry *e)
+gff_entry_fill_in_face (GPFontEntry *e)
{
GnomeFontFace *face;
@@ -527,7 +535,7 @@
return e->face;
}
- gff_face_from_entry (e);
+ gff_entry_fill_in_face (e);
gp_fontmap_release (map);
@@ -559,7 +567,7 @@
if (e->face) {
gnome_font_face_ref (e->face);
} else {
- gff_face_from_entry (e);
+ gff_entry_fill_in_face (e);
}
face = e->face;
}
@@ -674,6 +682,100 @@
family_name = pango_font_description_get_family (desc);
return gnome_font_face_find_closest_from_weight_slant (family_name, weight, italic);
+}
+
+/* from /usr/share/misc/magic of debian's file 3.40 */
+#define TRUETYPE_MAGIC "\000\001\000\000\000"
+#define TRUETYPE_MAGIC_LENGTH 5
+#define TYPE1_MAGIC "%!PS-AdobeFont-1."
+#define TYPE1_MAGIC_LENGTH 17
+
+static GPFontEntryType
+gff_font_entry_type_from_data (const guchar *font_data, gsize length)
+{
+ if (length > TYPE1_MAGIC_LENGTH + 6
+ && !memcmp (font_data + 6, TYPE1_MAGIC, TYPE1_MAGIC_LENGTH))
+ return GP_FONT_ENTRY_TYPE1; /* PFB */
+ else if (length > TYPE1_MAGIC_LENGTH
+ && !memcmp (font_data, TYPE1_MAGIC, TYPE1_MAGIC_LENGTH))
+ return GP_FONT_ENTRY_TYPE1; /* PFA */
+ else if (length > TRUETYPE_MAGIC_LENGTH
+ && !memcmp (font_data, TRUETYPE_MAGIC, TRUETYPE_MAGIC_LENGTH))
+ return GP_FONT_ENTRY_TRUETYPE;
+ else
+ return GP_FONT_ENTRY_UNKNOWN;
+}
+
+static gchar*
+gff_write_temp_data_file (const guchar *font_data, gsize length)
+{
+ gint fd;
+ gchar *temp_name;
+ FILE *file;
+ size_t written;
+
+ fd = g_file_open_tmp ("gnome-print-XXXXXX", &temp_name, NULL);
+ if (fd <= -1)
+ return NULL;
+
+ file = fdopen (fd, "wb");
+ written = fwrite (font_data, length, 1, file);
+ fclose (file);
+ if (written != 1) {
+ unlink (temp_name);
+ return NULL;
+ }
+
+ return temp_name;
+}
+
+static void
+gff_unlink_temp_file (gpointer data, GObject *object)
+{
+ unlink ((gchar *)data);
+}
+
+GnomeFontFace *gnome_font_face_download (const guchar *family, const guchar *species, GnomeFontWeight weight, gboolean italic, const guchar *font_data, gsize length)
+{
+ GPFontEntry *entry;
+ gchar *temp_fname;
+ GnomeFontFace *face;
+
+ g_return_val_if_fail (family != NULL, NULL);
+ g_return_val_if_fail (font_data != NULL, NULL);
+ g_return_val_if_fail (length > 0, NULL);
+
+ temp_fname = gff_write_temp_data_file (font_data, length);
+ if (temp_fname == NULL) {
+ g_warning ("Could not create temporary file for embedded font");
+ return NULL;
+ }
+
+ entry = g_new0 (GPFontEntry, 1);
+ entry->type = gff_font_entry_type_from_data (font_data, length);
+ entry->file = temp_fname;
+ entry->refcount = 1;
+ entry->face = NULL;
+ entry->speciesname = g_strdup (species
+ ? species
+ : (const guchar *)"Regular");
+ entry->weight = entry->speciesname; /* FIXME here and in fcpattern_to_gp_font_entry */
+ entry->Weight = weight;
+ entry->familyname = g_strdup (family);
+ entry->name = g_strconcat (family, " ", entry->speciesname, NULL);
+ entry->italic_angle = italic ? -15 : 0;
+ entry->is_alias = FALSE;
+
+ gff_entry_fill_in_face (entry);
+ face = entry->face;
+
+ face->is_downloaded = TRUE;
+ face->font_data = g_memdup (font_data, length);
+ face->data_length = length;
+
+ g_object_weak_ref (G_OBJECT (face), gff_unlink_temp_file, temp_fname);
+
+ return face;
}
/* This returns GList of (guchar *) */
Index: libgnomeprint/gnome-font-face.h
===================================================================
RCS file: /cvs/gnome/libgnomeprint/libgnomeprint/gnome-font-face.h,v
retrieving revision 1.18
diff -u -r1.18 gnome-font-face.h
--- libgnomeprint/gnome-font-face.h 6 Jan 2003 19:06:04 -0000 1.18
+++ libgnomeprint/gnome-font-face.h 14 Mar 2003 16:46:11 -0000
@@ -59,6 +59,10 @@
GnomeFontFace *gnome_font_face_find_closest_from_pango_description (const PangoFontDescription *desc);
GnomeFontFace *gnome_font_face_find_from_family_and_style (const guchar *family, const guchar *style);
+#ifdef GNOME_PRINT_UNSTABLE_API
+GnomeFontFace *gnome_font_face_download (const guchar *family, const guchar *species, GnomeFontWeight weight, gboolean italic, const guchar *font_data, gsize length);
+#endif
+
/*
* Create font
*
Index: libgnomeprint/gnome-font-private.h
===================================================================
RCS file: /cvs/gnome/libgnomeprint/libgnomeprint/gnome-font-private.h,v
retrieving revision 1.32
diff -u -r1.32 gnome-font-private.h
--- libgnomeprint/gnome-font-private.h 2 Feb 2003 21:20:53 -0000 1.32
+++ libgnomeprint/gnome-font-private.h 14 Mar 2003 16:46:11 -0000
@@ -57,15 +57,19 @@
struct _GnomeFontFace {
GObject object;
- GPFontEntry * entry; /* Pointer to our fontmap entry */
- gint num_glyphs; /* Glyph storage */
+ GPFontEntry * entry; /* Pointer to our fontmap entry */
+ gint num_glyphs; /* Glyph storage */
GFFGlyphInfo * glyphs;
- gdouble ft2ps; /* FT -> PostScript scaling coefficent */
- ArtDRect bbox; /* Face bounding box */
- FT_Face ft_face; /* FreeType stuff */
- GSList *fonts; /* Our fonts */
- gchar *psname; /* The postscript name of the font */
+ gdouble ft2ps; /* FT -> PostScript scaling coefficent */
+ ArtDRect bbox; /* Face bounding box */
+ FT_Face ft_face; /* FreeType stuff */
+ GSList *fonts; /* Our fonts */
+ gchar *psname; /* The postscript name of the font */
+
+ gboolean is_downloaded;
+ guchar *font_data;
+ gsize data_length;
};
struct _GnomeFontFaceClass {
@@ -123,6 +127,7 @@
#define GFF_LOADED(f) ((f)->ft_face || gff_load ((GnomeFontFace *) f))
+#define GNOME_FONT_IS_DOWNLOADED(f) (f->face->is_downloaded)
/*
* Returns PostScript name for glyph
Index: libgnomeprint/gnome-print-job.c
===================================================================
RCS file: /cvs/gnome/libgnomeprint/libgnomeprint/gnome-print-job.c,v
retrieving revision 1.59
diff -u -r1.59 gnome-print-job.c
--- libgnomeprint/gnome-print-job.c 12 Mar 2003 19:29:31 -0000 1.59
+++ libgnomeprint/gnome-print-job.c 14 Mar 2003 16:46:13 -0000
@@ -433,7 +433,7 @@
* @job: A closed GnomePrintJob.
*
* Print the pages stored in the GnomePrintJob to
- * the phyisical printing device.
+ * the physical printing device.
*
* Return value: GNOME_PRINT_OK on success GNOME_PRINT_ERROR_UNKNOWN otherwise
**/
Index: libgnomeprint/gnome-print-meta.c
===================================================================
RCS file: /cvs/gnome/libgnomeprint/libgnomeprint/gnome-print-meta.c,v
retrieving revision 1.61
diff -u -r1.61 gnome-print-meta.c
--- libgnomeprint/gnome-print-meta.c 6 Jan 2003 19:06:05 -0000 1.61
+++ libgnomeprint/gnome-print-meta.c 14 Mar 2003 16:46:18 -0000
@@ -25,10 +25,14 @@
* Copyright (C) 1999-2003 Ximian Inc. and authors
*/
+#define GNOME_PRINT_UNSTABLE_API
+
#include <config.h>
#include <math.h>
#include <string.h>
+#include <libgnomeprint/gnome-font-face.h>
+#include <libgnomeprint/gnome-font-private.h>
#include <libgnomeprint/gnome-glyphlist-private.h>
#include <libgnomeprint/gnome-print-private.h>
#include <libgnomeprint/gnome-print-meta.h>
@@ -43,6 +47,9 @@
gint page; /* Start of current page */
gint pagenum; /* Number of current page, or -1 */
+
+ GHashTable *embedded_faces;
+ GHashTable *queued_faces;
};
typedef struct _GnomePrintMetaClass GnomePrintMetaClass;
@@ -54,7 +61,7 @@
/* Note: this must continue to be the same length as "GNOME_METAFILE-0.0" */
-#define METAFILE_SIGNATURE "GNOME_METAFILE-3.0"
+#define METAFILE_SIGNATURE "GNOME_METAFILE-3.1"
#define METAFILE_SIGNATURE_SIZE 18
#define METAFILE_HEADER_SIZE (METAFILE_SIGNATURE_SIZE + 4)
#define PAGE_SIGNATURE "PAGE"
@@ -75,6 +82,7 @@
GNOME_META_COLOR,
GNOME_META_LINE,
GNOME_META_DASH,
+ GNOME_META_FONT_DATA,
} GnomeMetaType;
typedef enum {
@@ -83,6 +91,18 @@
GNOME_META_DOUBLE_I386 /* IEEE-xxxx little endian. */
} GnomeMetaDoubleType;
+typedef enum {
+ GNOME_META_FONT_FONTMAP, /* A font from the fontmap */
+ GNOME_META_FONT_EMBEDDED, /* A font embedded in the meta file */
+} GnomeMetaFontType;
+
+typedef struct {
+ GnomePrintMeta *meta;
+ GnomeFontFace *face;
+ gint offset;
+ GSList *uses;
+} GnomeMetaEmbeddedFace;
+
#define GPM_ENSURE_SPACE(m,s) (((m)->b_length + (s) <= (m)->b_size) || gpm_ensure_space (m, s))
static void gnome_print_meta_class_init (GnomePrintMetaClass *klass);
@@ -114,8 +134,17 @@
static void gpm_encode_bpath (GnomePrintContext *pc, const ArtBpath *bpath);
static const char *gpm_decode_bpath (const char *data, ArtBpath **bpath);
+static const guchar *gpm_skip_string (const guchar *data);
static const guchar *gpm_decode_string (const guchar *data, guchar **dest);
+static void embedded_face_destroy (GnomeMetaEmbeddedFace *eface);
+static void gpm_font_face_use_fill_slot (gpointer data, gpointer user_data);
+static gboolean gpm_font_face_download_real (gpointer key, gpointer value, gpointer user_data);
+static void gpm_queue_font_face_download (GnomePrintContext *pc, GnomeFontFace *face, gint32 use);
+static void gpm_encode_downloaded_font_face (GnomePrintContext *pc, GnomeFontFace *face);
+static void gpm_encode_font (GnomePrintContext *pc, GnomeFont *font);
+static const guchar *decode_font (GnomePrintContext *pc, const guchar *data, const guchar *data_start, GnomeFont **dest);
+
/* Encoding and decoding of header data */
static void gpm_encode_int_header (GnomePrintContext *pc, gint32 value);
static const guchar *gpm_decode_int_header (const guchar *data, gint32 *dest);
@@ -180,6 +209,9 @@
meta->page = 0;
meta->pagenum = -1;
+
+ meta->embedded_faces = g_hash_table_new_full (NULL, NULL, NULL, (GDestroyNotify)embedded_face_destroy);
+ meta->queued_faces = g_hash_table_new (NULL, NULL);
}
static void
@@ -231,6 +263,11 @@
/* Encode showpage */
gpm_encode_int (ctx, GNOME_META_SHOWPAGE);
+ /* Encode font data */
+ g_hash_table_foreach_remove (meta->queued_faces,
+ gpm_font_face_download_real,
+ meta);
+
/* Save page length */
len = g_htonl (meta->b_length - meta->page - PAGE_HEADER_SIZE);
memcpy (meta->buf + meta->page + PAGE_SIGNATURE_SIZE, &len, 4);
@@ -351,8 +388,7 @@
gpm_encode_double (pc, gl->rules[i].value.dval);
break;
case GGL_FONT:
- gpm_encode_double (pc, gnome_font_get_size (gl->rules[i].value.font));
- gpm_encode_string (pc, gnome_font_get_name (gl->rules[i].value.font));
+ gpm_encode_font (pc, gl->rules[i].value.font);
break;
default:
break;
@@ -374,6 +410,9 @@
memcpy (meta->buf + METAFILE_SIGNATURE_SIZE, &len, 4);
+ g_hash_table_destroy (meta->embedded_faces);
+ g_hash_table_destroy (meta->queued_faces);
+
return GNOME_PRINT_OK;
}
@@ -532,6 +571,14 @@
}
static const guchar *
+gpm_skip_string (const guchar *data)
+{
+ gint32 len;
+ data = decode_int (data, &len);
+ return data + len;
+}
+
+static const guchar *
gpm_decode_string (const guchar *data, guchar **dest)
{
gint32 len;
@@ -545,8 +592,10 @@
static gint
gpm_render (GnomePrintContext *dest, const guchar *data, gint pos, gint len, gboolean pageops)
{
+ const guchar *data_start;
const guchar *end;
+ data_start = data;
data = data + pos;
end = data + len;
@@ -661,13 +710,8 @@
break;
case GGL_FONT: {
GnomeFont *font;
- guchar *name;
- data = decode_double (data, &dval);
- data = gpm_decode_string (data, &name);
- font = gnome_font_find (name, dval);
- if (font == NULL)
- g_warning ("Cannot find font: %s\n", name);
- g_free (name);
+
+ data = decode_font (dest, data, data_start, &font);
gl->rules[i].value.font = font;
break;
}
@@ -715,6 +759,17 @@
g_free (values);
break;
}
+ case GNOME_META_FONT_DATA: {
+ gint32 data_len;
+
+ data = gpm_skip_string (data);
+ data = gpm_skip_string (data);
+ data = decode_int (data, &ival);
+ data = decode_int (data, &ival);
+ data = decode_int (data, &data_len);
+ data += data_len;
+ break;
+ }
default:
g_warning ("Serious print meta data corruption %d", opcode);
break;
@@ -826,7 +881,7 @@
retval = gnome_print_buffer_mmap (&b, filename);
if (retval != GNOME_PRINT_OK)
return retval;
-
+
retval = gnome_print_meta_render_data (ctx, b.buf, b.buf_size);
gnome_print_buffer_munmap (&b);
@@ -858,7 +913,7 @@
retval = gnome_print_buffer_mmap (&b, filename);
if (retval != GNOME_PRINT_OK)
return retval;
-
+
retval = gnome_print_meta_render_data_page (ctx, b.buf, b.buf_size, page, pageops);
gnome_print_buffer_munmap (&b);
@@ -1057,8 +1112,208 @@
return data;
}
+static void
+embedded_face_destroy (GnomeMetaEmbeddedFace *eface)
+{
+ g_object_unref (G_OBJECT (eface->meta));
+ g_object_unref (G_OBJECT (eface->face));
+ g_free (eface);
+}
+
+static void
+gpm_font_face_use_fill_slot (gpointer data, gpointer user_data)
+{
+ gint32 font_face_use;
+ GnomeMetaEmbeddedFace *eface;
+ gint32 noffset;
+
+ font_face_use = GPOINTER_TO_INT (data);
+ eface = (GnomeMetaEmbeddedFace *)user_data;
+ noffset = g_htonl (eface->offset);
+
+ memcpy (eface->meta->buf + font_face_use, &noffset, sizeof (gint32));
+}
+
+static gboolean
+gpm_font_face_download_real (gpointer key, gpointer value, gpointer user_data)
+{
+ GnomePrintContext *pc;
+ GnomePrintMeta *meta;
+ GnomeMetaEmbeddedFace *eface;
+
+ pc = GNOME_PRINT_CONTEXT (user_data);
+ meta = GNOME_PRINT_META (pc);
+ eface = (GnomeMetaEmbeddedFace *)value;
+ eface->offset = meta->b_length;
+
+ gpm_encode_int (pc, GNOME_META_FONT_DATA);
+ gpm_encode_string (pc, gnome_font_face_get_family_name (eface->face));
+ gpm_encode_string (pc, gnome_font_face_get_species_name (eface->face));
+ gpm_encode_int (pc, gnome_font_face_get_weight_code (eface->face));
+ gpm_encode_int (pc, gnome_font_face_is_italic (eface->face));
+ gpm_encode_int (pc, eface->face->data_length);
+ gpm_encode_block (pc, eface->face->font_data, eface->face->data_length);
+ g_slist_foreach (eface->uses,
+ gpm_font_face_use_fill_slot,
+ eface);
+
+ g_slist_free (eface->uses);
+ eface->uses = NULL;
+
+ g_hash_table_insert (meta->embedded_faces, eface->face, eface);
+
+ return TRUE;
+}
+
+static void
+gpm_queue_font_face_download (GnomePrintContext *pc, GnomeFontFace *face, gint32 use)
+{
+ GnomePrintMeta *meta;
+ GnomeMetaEmbeddedFace *eface;
+
+ meta = GNOME_PRINT_META (pc);
+
+ eface = g_hash_table_lookup (meta->queued_faces, face);
+ if (!eface) {
+ eface = g_new0 (GnomeMetaEmbeddedFace, 1);
+ eface->meta = meta;
+ g_object_ref (G_OBJECT (meta));
+ eface->face = face;
+ g_object_ref (G_OBJECT (face));
+ g_hash_table_insert (meta->queued_faces, face, eface);
+ }
+ eface->uses = g_slist_prepend (eface->uses, GINT_TO_POINTER (use));
+}
+
+static void
+gpm_encode_downloaded_font_face (GnomePrintContext *pc, GnomeFontFace *face)
+{
+ GnomePrintMeta *meta;
+ GnomeMetaEmbeddedFace *eface;
+ gint32 offset;
+
+ meta = GNOME_PRINT_META (pc);
+
+ eface = g_hash_table_lookup (meta->embedded_faces, face);
+ if (eface) {
+ offset = eface->offset;
+ } else {
+ gpm_queue_font_face_download (pc, face, meta->b_length);
+
+ offset = -1;
+ }
+
+ gpm_encode_int_header (pc, offset);
+}
+
+static void
+gpm_encode_font (GnomePrintContext *pc, GnomeFont *font)
+{
+ if (!GNOME_FONT_IS_DOWNLOADED (font)) {
+ gpm_encode_int (pc, GNOME_META_FONT_FONTMAP);
+ gpm_encode_double (pc, gnome_font_get_size (font));
+ gpm_encode_string (pc, gnome_font_get_name (font));
+ } else {
+ gpm_encode_int (pc, GNOME_META_FONT_EMBEDDED);
+ gpm_encode_double (pc, gnome_font_get_size (font));
+ gpm_encode_downloaded_font_face (pc, gnome_font_get_face (font));
+ }
+}
+
+static GnomeFont *
+download_font (GnomePrintContext *dest, const guchar *data, gdouble size)
+{
+ GHashTable *hash;
+ gpointer hash_key;
+ GnomeFontFace *face;
+ GnomeFont *font;
+
+ hash = g_object_get_data (G_OBJECT (dest), "meta-replay-fonts");
+ if (hash == NULL) {
+ hash = g_hash_table_new_full (NULL, NULL, NULL, (GDestroyNotify)g_object_unref);
+ g_object_set_data_full (G_OBJECT (dest), "meta-replay-fonts", hash, (GDestroyNotify)g_hash_table_destroy);
+ }
+
+ hash_key = (gpointer)data;
+ face = g_hash_table_lookup (hash, hash_key);
+ if (face == NULL) {
+ gint32 ival;
+
+ data = decode_int (data, &ival);
+ if (ival != GNOME_META_FONT_DATA) {
+ g_warning ("Serious print meta data corruption (embedded font)");
+ face = gnome_font_face_find ("Serif");
+ } else {
+ guchar *family;
+ guchar *species;
+ GnomeFontWeight weight;
+ gboolean italic;
+ gint32 ival;
+ gsize len;
+
+ data = gpm_decode_string (data, &family);
+ data = gpm_decode_string (data, &species);
+ data = decode_int (data, &ival);
+ weight = (GnomeFontWeight)ival;
+ data = decode_int (data, &ival);
+ italic = (gboolean)ival;
+ data = decode_int (data, &ival);
+ len = (gsize)ival;
+
+ face = gnome_font_face_download (family, species, weight,
+ italic, data, len);
+
+ g_free (family);
+ g_free (species);
+ }
+
+ g_hash_table_insert (hash, hash_key, face);
+ }
+
+ font = gnome_font_face_get_font_default (face, size);
+
+ return font;
+}
+
+static const guchar *
+decode_font (GnomePrintContext *pc, const guchar *data, const guchar *data_start, GnomeFont **dest)
+{
+ gint32 font_type;
+ gdouble size;
+ GnomeFont *font;
+ guchar *name;
+ gint32 offset;
+
+ data = decode_int (data, &font_type);
+
+ switch ((GnomeMetaFontType) font_type) {
+ case GNOME_META_FONT_FONTMAP:
+ data = decode_double (data, &size);
+ data = gpm_decode_string (data, &name);
+ font = gnome_font_find (name, size);
+ if (font == NULL)
+ g_warning ("Cannot find font: %s\n", name);
+ g_free (name);
+ *dest = font;
+ break;
+ case GNOME_META_FONT_EMBEDDED:
+ data = decode_double (data, &size);
+ data = gpm_decode_int_header (data, &offset);
+ font = download_font (pc, data_start + offset, size);
+ if (font == NULL)
+ g_warning ("Cannot process embedded font.\n");
+ *dest = font;
+ break;
+ default:
+ g_warning ("Serious print meta data corruption: font type %d", font_type);
+ break;
+ }
+
+ return data;
+}
+
/*
- * Less compact, but gauranteed size (just makes things easier to encode
+ * Less compact, but guaranteed size (just makes things easier to encode
* fixed size data like headers)
*/
@@ -1082,4 +1337,3 @@
return data + sizeof (gint32);
}
-
cvs server: Diffing libgnomeprint/drivers
cvs server: Diffing libgnomeprint/gpa
cvs server: Diffing libgnomeprint/modules
cvs server: Diffing libgnomeprint/modules/cups
cvs server: Diffing libgnomeprint/transports
cvs server: Diffing po
cvs server: Diffing tests
Index: tests/Makefile.am
===================================================================
RCS file: /cvs/gnome/libgnomeprint/tests/Makefile.am,v
retrieving revision 1.31
diff -u -r1.31 Makefile.am
--- tests/Makefile.am 2 Feb 2003 21:20:53 -0000 1.31
+++ tests/Makefile.am 14 Mar 2003 16:46:19 -0000
@@ -2,7 +2,7 @@
CFLAGS=$(WARN_CFLAGS)
-noinst_PROGRAMS = generate gpa-test fonts simple
+noinst_PROGRAMS = generate gpa-test fonts simple font-embedding
INCLUDES = \
-I$(top_srcdir) \
@@ -32,3 +32,7 @@
fonts_SOURCES = fonts.c
fonts_LDFLAGS =
fonts_LDADD = $(print_libs)
+
+font_embedding_SOURCES = font-embedding.c
+font_embedding_LDFLAGS =
+font_embedding_LDADD = $(print_libs)
Index: tests/generate.c
===================================================================
RCS file: /cvs/gnome/libgnomeprint/tests/generate.c,v
retrieving revision 1.19
diff -u -r1.19 generate.c
--- tests/generate.c 11 Mar 2003 08:36:07 -0000 1.19
+++ tests/generate.c 14 Mar 2003 16:46:20 -0000
@@ -615,7 +615,7 @@
*backend = BACKEND_UNKNOWN;
if (*backend == BACKEND_UNKNOWN)
- usage ("Backend not specicied or invalid.");
+ usage ("Backend not specified or invalid.");
if (replay_str && replay_str[0] != '\0') {
FILE *file;
cvs server: Diffing tests/files
cvs server: Diffing tests/output
cvs server: Diffing tests/tools
/*
* Test embedding of font faces as chunks of memory
*
* derived from Chema's simple.c template
*/
#define GNOME_PRINT_UNSTABLE_API
#include <string.h>
#include <libgnomeprint/gnome-print.h>
#include <libgnomeprint/gnome-print-job.h>
#include <libgnomeprint/gnome-font.h>
#include <libgnomeprint/gnome-font-face.h>
/* for testing FontEntryType */
#include <libgnomeprint/gnome-font-private.h>
#include <libgnomeprint/gnome-fontmap.h>
#define TEXT "The quick brown fox jumps over the lazy dog."
/* FIXME before check in */
#define SAMPLE_PFB_FILE "/usr/share/texmf/fonts/type1/urw/palatino/uplb8a.pfb"
#define SAMPLE_TTF_FILE "/home/martin/.fonts/tt2001gn.ttf"
static void
my_draw (GnomePrintContext *gpc, GnomeFontFace *gff, GnomeFontFace *gff2)
{
GnomeFont *font, *font2, *font3;
font = gnome_font_face_get_font_default (gff, 12);
font2 = gnome_font_face_get_font_default (gff2, 20);
font3 = gnome_font_face_get_font_default (gff2, 10);
gnome_print_beginpage (gpc, "1");
gnome_print_setfont (gpc, font);
gnome_print_moveto (gpc, 100, 180);
gnome_print_show (gpc, TEXT);
gnome_print_showpage (gpc);
gnome_print_beginpage (gpc, "2");
gnome_print_setfont (gpc, font);
gnome_print_moveto (gpc, 100, 180);
gnome_print_show (gpc, TEXT);
gnome_print_setfont (gpc, font2);
gnome_print_moveto (gpc, 100, 360);
gnome_print_show (gpc, TEXT);
gnome_print_showpage (gpc);
gnome_print_beginpage (gpc, "2");
gnome_print_setfont (gpc, font3);
gnome_print_moveto (gpc, 100, 180);
gnome_print_show (gpc, TEXT);
gnome_print_showpage (gpc);
g_object_unref (G_OBJECT (font));
g_object_unref (G_OBJECT (font2));
g_object_unref (G_OBJECT (font3));
}
static void
my_test (GnomePrintContext *gpc)
{
gchar *font_data;
gsize font_length;
GnomeFontFace *gff, *gff2;
if (g_file_get_contents (SAMPLE_PFB_FILE, &font_data, &font_length,
NULL) == FALSE)
g_assert_not_reached ();
gff = gnome_font_face_download ("FontFamilyName", "Italic",
GNOME_FONT_REGULAR, TRUE,
(const guchar *)font_data,
font_length);
g_free (font_data);
/* check if parameters end up in the right attributes */
g_assert (gff != NULL);
g_assert (GNOME_IS_FONT_FACE (gff));
g_assert (strcmp (gnome_font_face_get_name (gff),
"FontFamilyName Italic") == 0);
g_assert (strcmp (gnome_font_face_get_family_name (gff),
"FontFamilyName") == 0);
g_assert (strcmp (gnome_font_face_get_species_name (gff),
"Italic") == 0);
g_assert (gff->entry->type == GP_FONT_ENTRY_TYPE1);
/* the following calls require successful loading of the font data */
g_assert (gnome_font_face_lookup_default (gff, (gint)'A') == 133);
g_assert (strcmp (gnome_font_face_get_glyph_ps_name (gff, 133),
"A") == 0);
if (g_file_get_contents (SAMPLE_TTF_FILE, &font_data, &font_length,
NULL) == FALSE)
g_assert_not_reached ();
gff2 = gnome_font_face_download ("AnotherFontFamilyName", "Italic",
GNOME_FONT_REGULAR, TRUE,
(const guchar *)font_data,
font_length);
g_free (font_data);
g_assert (gff2->entry->type == GP_FONT_ENTRY_TRUETYPE);
my_draw (gpc, gff, gff2);
g_object_unref (gff);
g_object_unref (gff2);
}
static void
my_print (void)
{
GnomePrintJob *job;
GnomePrintContext *gpc;
GnomePrintConfig *config;
job = gnome_print_job_new (NULL);
gpc = gnome_print_job_get_context (job);
config = gnome_print_job_get_config (job);
gnome_print_config_set (config, "Printer", "GENERIC");
gnome_print_job_print_to_file (job, "o.ps");
#if 0
gnome_print_config_set (config, "Printer", "PDF");
gnome_print_job_print_to_file (job, "o.pdf");
#endif
gnome_print_config_set (config, GNOME_PRINT_KEY_PAPER_SIZE, "USLetter");
my_test (gpc);
gnome_print_job_close (job);
gnome_print_job_print (job);
g_object_unref (G_OBJECT (config));
g_object_unref (G_OBJECT (gpc));
g_object_unref (G_OBJECT (job));
}
int
main (int argc, char * argv[])
{
g_type_init ();
my_print ();
g_print ("Done...\n");
return 0;
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]