[cairo-commit]
cairo/src cairo-atsui.h, 1.1, 1.2 cairo-ft-private.h,
NONE, 1.1 cairo-ft.h, 1.1, 1.2 cairo-glitz.h, 1.1,
1.2 cairo-pdf.h, 1.1, 1.2 cairo-png.h, 1.1, 1.2 cairo-ps.h,
1.1, 1.2 cairo-quartz.h, 1.2, 1.3 cairo-xcb.h, 1.1,
1.2 cairo-xlib.h, 1.6, 1.7 cairo.h, 1.67, 1.68 cairo_cache.c,
1.6, 1.7 cairo_font.c, 1.30, 1.31 cairo_ft_font.c, 1.32,
1.33 cairo_gstate.c, 1.72, 1.73 cairo_pdf_surface.c, 1.7,
1.8 cairo_quartz_surface.c, 1.2, 1.3 cairo_xlib_surface.c,
1.37, 1.38 cairoint.h, 1.85, 1.86
Owen Taylor
commit at pdx.freedesktop.org
Fri Jan 21 14:33:50 PST 2005
- Previous message: [cairo-commit] cairo/doc/reference/xml cairo_current_font.xml, 1.2,
1.3 cairo_font_glyph_extents.xml, NONE, 1.1 cairo_font_t.xml,
NONE, 1.1 cairo_ft_font_create.xml, NONE,
1.1 cairo_ft_font_create_for_ft_face.xml, NONE,
1.1 cairo_ft_font_get_pattern.xml, NONE,
1.1 cairo_ft_font_lock_face.xml, NONE,
1.1 cairo_ft_font_unlock_face.xml, NONE, 1.1 cairo_glyph_t.xml,
NONE, 1.1 cairo_matrix_t.xml, 1.1, 1.2 cairo_set_font.xml, 1.2,
1.3 cairo_show_glyphs.xml, 1.2, 1.3 cairo_text_extents_t.xml,
1.1, 1.2
- Next message: [cairo-commit] cairo ChangeLog,1.319,1.320
- Messages sorted by:
[ date ]
[ thread ]
[ subject ]
[ author ]
Committed by: otaylor
Update of /cvs/cairo/cairo/src
In directory gabe:/tmp/cvs-serv3974/src
Modified Files:
cairo-atsui.h cairo-ft.h cairo-glitz.h cairo-pdf.h cairo-png.h
cairo-ps.h cairo-quartz.h cairo-xcb.h cairo-xlib.h cairo.h
cairo_cache.c cairo_font.c cairo_ft_font.c cairo_gstate.c
cairo_pdf_surface.c cairo_quartz_surface.c
cairo_xlib_surface.c cairoint.h
Added Files:
cairo-ft-private.h
Log Message:
2005-01-16 Owen Taylor <otaylor at redhat.com>
Change cairo_font_t to refer to a font scaled to a particular
output device resolution.
* src/cairoint.h src/cairo_font.c src/cairo_ft_font.c
src/cairo_xlib_surface.c src/cairo_pdf_surface.c src/cairo_gstate.c
src/cairo.c: Switch many internal methods from handling
cairo_unscaled_font_t and cairo_font_scale_t pairs to handling
cairo_font_t.
* src/cairo-ft-private.h src/cairo_ft_fontc: Add some internal
interfaces for use by the FreeType backend.
* src/cairo_gstate.c: Clear the gstate's current font when
the transform or target surface changes.
* src/cairo.h src/cairo_ft_font.c: Rename cairo_ft_font_pattern
to cairo_ft_font_get_pattern().
* src/cairo.h src/cairo_ft_font.c: Make cairo_ft_font_create()
and cairo_ft_font_create_for_ft_face() take a font scale;
make the latter take load_flags for FT_Load_Glyph() as well.
Change cairo_ft_font_face() to Xft-style cairo_ft_font_lock_face,
cairo_ft_font_unlock_face.
* src/cairo_font.c: Remove the name/slant/weight=>unscaled font
cache, it didn't work with the new cairo_font_t setup. If it turns
out to be needed, it can be added back in some other form.
* src/cairoint.h src/cairo_font.c: Add a 'flags' field
to cairo_glyph_cache_key_t, we use it for load flags with
freetype backend.
* src/cairo_ft_font.c: Switch the caching to be from
resolved fontconfig pattern => file; keep only a fixed number
of FT_Face objects open at once, similar to FreeType.
* src/cairo_font.c (cairo_font_glyph_extents) src/cairo_gstate.c
src/cairoint.h: Add public cairo_font_glyph_extents, use it
to implement _cairo_gstate_glyph_extents().
* src/cairo_xlib_surface.c (_glyphset_cache_entry_reference):
Add refcounting for glyph cache elements; there was an
bug where elements got ejected from the cache and freed before
they could be used.
* src/cairoint.h src/cairo_cache.c (_cairo_cache_random_entry())
New function to return a random entry in the cache matching a predicate;
reuse the internals for the previous _random_live_entry().
* src/cairoint.h src/cairo_cache.c (_cairo_cache_lookup()): Add an
optional created_entry return value.
* src/cairo_ft_font.c src/cairo_xlib_surface.c: Adapt to
_cairo_cache_lookup() change.
* src/cairo_cache.c (_cairo_cache_lookup()): Support max_memory == 0
to indicate an unbounded cache.
* src/cairoint.h src/cairo_cache.c (_cairo_cache_remove()): Add a
function to manually remove entries from the cache.
* doc/reference: Update for changes, document cairo_matrix_t,
cairo_glyph_t, etc.
* src/cairo.h src/cairo-atsui.h src/cairo-ft.h src/cairo-glitz.h
src/cairo-pdf.h src/cairo-png.h src/cairo-ps.h src/cairo-quartz.h
src/cairo-xcb.h src/cairo-xlib.h: Add CAIRO_BEGIN/END_DECLS for
extern "C", use it on all public headers. Move header guards
outermost.
* src/cairo_quartz_surface.c: Fix encoding.
Index: cairo-atsui.h
===================================================================
RCS file: /cvs/cairo/cairo/src/cairo-atsui.h,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -d -r1.1 -r1.2
--- cairo-atsui.h 21 Jan 2005 04:36:25 -0000 1.1
+++ cairo-atsui.h 21 Jan 2005 22:33:48 -0000 1.2
@@ -33,18 +33,23 @@
* Calum Robinson <calumr at mac.com>
*/
-#include <cairo.h>
-
#ifndef CAIRO_ATSUI_H
#define CAIRO_ATSUI_H
+
+#include <cairo.h>
+
#ifdef CAIRO_HAS_ATSUI_FONT
/* ATSUI platform-specific font interface */
#include <Carbon/Carbon.h>
+CAIRO_BEGIN_DECLS
+
cairo_font_t *
cairo_atsui_font_create(ATSUStyle style);
+CAIRO_END_DECLS
+
#endif /* CAIRO_HAS_ATSUI_FONT */
#endif /* CAIRO_ATSUI_H */
--- NEW FILE: cairo-ft-private.h ---
(This appears to be a binary file; contents omitted.)
Index: cairo-ft.h
===================================================================
RCS file: /cvs/cairo/cairo/src/cairo-ft.h,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -d -r1.1 -r1.2
--- cairo-ft.h 20 Jan 2005 16:28:54 -0000 1.1
+++ cairo-ft.h 21 Jan 2005 22:33:48 -0000 1.2
@@ -1,6 +1,6 @@
/* cairo - a vector graphics library with display and print output
*
- * Copyright © 2002 University of Southern California
+ * Copyright © 2005 Red Hat, Inc
*
* This library is free software; you can redistribute it and/or
* modify it either under the terms of the GNU Lesser General Public
@@ -27,17 +27,18 @@
*
* The Original Code is the cairo graphics library.
*
- * The Initial Developer of the Original Code is University of Southern
- * California.
+ * The Initial Developer of the Original Code is Red Hat, Inc.
*
* Contributor(s):
- * Carl D. Worth <cworth at isi.edu>
+ * Graydon Hoare <graydon at redhat.com>
+ * Owen Taylor <otaylor at redhat.com>
*/
-#include <cairo.h>
-
#ifndef CAIRO_FT_H
#define CAIRO_FT_H
+
+#include <cairo.h>
+
#ifdef CAIRO_HAS_FT_FONT
/* Fontconfig/Freetype platform-specific font interface */
@@ -46,17 +47,27 @@
#include <ft2build.h>
#include FT_FREETYPE_H
+CAIRO_BEGIN_DECLS
+
cairo_font_t *
-cairo_ft_font_create (FT_Library ft_library, FcPattern *pattern);
+cairo_ft_font_create (FcPattern *pattern,
+ cairo_matrix_t *scale);
cairo_font_t *
-cairo_ft_font_create_for_ft_face (FT_Face face);
+cairo_ft_font_create_for_ft_face (FT_Face face,
+ int load_flags,
+ cairo_matrix_t *scale);
FT_Face
-cairo_ft_font_face (cairo_font_t *ft_font);
+cairo_ft_font_lock_face (cairo_font_t *ft_font);
+
+void
+cairo_ft_font_unlock_face (cairo_font_t *ft_font);
FcPattern *
-cairo_ft_font_pattern (cairo_font_t *ft_font);
+cairo_ft_font_get_pattern (cairo_font_t *ft_font);
+
+CAIRO_END_DECLS
#endif /* CAIRO_HAS_FT_FONT */
#endif /* CAIRO_FT_H */
Index: cairo-glitz.h
===================================================================
RCS file: /cvs/cairo/cairo/src/cairo-glitz.h,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -d -r1.1 -r1.2
--- cairo-glitz.h 20 Jan 2005 16:28:54 -0000 1.1
+++ cairo-glitz.h 21 Jan 2005 22:33:48 -0000 1.2
@@ -34,14 +34,17 @@
* Carl D. Worth <cworth at isi.edu>
*/
-#include <cairo.h>
-
#ifndef CAIRO_GLITZ_H
#define CAIRO_GLITZ_H
+
+#include <cairo.h>
+
#ifdef CAIRO_HAS_GLITZ_SURFACE
#include <glitz.h>
+CAIRO_BEGIN_DECLS
+
void
cairo_set_target_glitz (cairo_t *cr,
glitz_surface_t *surface);
@@ -49,5 +52,7 @@
cairo_surface_t *
cairo_glitz_surface_create (glitz_surface_t *surface);
+CAIRO_END_DECLS
+
#endif /* CAIRO_HAS_GLITZ_SURFACE */
#endif /* CAIRO_GLITZ_H */
Index: cairo-pdf.h
===================================================================
RCS file: /cvs/cairo/cairo/src/cairo-pdf.h,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -d -r1.1 -r1.2
--- cairo-pdf.h 20 Jan 2005 16:28:54 -0000 1.1
+++ cairo-pdf.h 21 Jan 2005 22:33:48 -0000 1.2
@@ -34,14 +34,17 @@
* Carl D. Worth <cworth at isi.edu>
*/
-#include <cairo.h>
-
#ifndef CAIRO_PDF_H
#define CAIRO_PDF_H
+
+#include <cairo.h>
+
#ifdef CAIRO_HAS_PDF_SURFACE
#include <stdio.h>
+CAIRO_BEGIN_DECLS
+
void
cairo_set_target_pdf (cairo_t *cr,
FILE *file,
@@ -58,5 +61,7 @@
double x_pixels_per_inch,
double y_pixels_per_inch);
+CAIRO_END_DECLS
+
#endif /* CAIRO_HAS_PDF_SURFACE */
#endif /* CAIRO_PDF_H */
Index: cairo-png.h
===================================================================
RCS file: /cvs/cairo/cairo/src/cairo-png.h,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -d -r1.1 -r1.2
--- cairo-png.h 20 Jan 2005 16:28:54 -0000 1.1
+++ cairo-png.h 21 Jan 2005 22:33:48 -0000 1.2
@@ -34,14 +34,17 @@
* Carl D. Worth <cworth at isi.edu>
*/
-#include <cairo.h>
-
#ifndef CAIRO_PNG_H
#define CAIRO_PNG_H
-#ifdef CAIRO_HAS_PNG_SURFACE
+
+#include <cairo.h>
+
+#ifdef CAIRO_HAS_PNG_SURFACE
#include <stdio.h>
+CAIRO_BEGIN_DECLS
+
void
cairo_set_target_png (cairo_t *cr,
FILE *file,
@@ -55,5 +58,7 @@
int width,
int height);
+CAIRO_END_DECLS
+
#endif /* CAIRO_HAS_PNG_SURFACE */
#endif /* CAIRO_PNG_H */
Index: cairo-ps.h
===================================================================
RCS file: /cvs/cairo/cairo/src/cairo-ps.h,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -d -r1.1 -r1.2
--- cairo-ps.h 20 Jan 2005 16:28:54 -0000 1.1
+++ cairo-ps.h 21 Jan 2005 22:33:48 -0000 1.2
@@ -34,14 +34,17 @@
* Carl D. Worth <cworth at isi.edu>
*/
-#include <cairo.h>
-
#ifndef CAIRO_PS_H
#define CAIRO_PS_H
+
+#include <cairo.h>
+
#ifdef CAIRO_HAS_PS_SURFACE
#include <stdio.h>
+CAIRO_BEGIN_DECLS
+
void
cairo_set_target_ps (cairo_t *cr,
FILE *file,
@@ -59,5 +62,7 @@
double x_pixels_per_inch,
double y_pixels_per_inch);
+CAIRO_END_DECLS
+
#endif /* CAIRO_HAS_PS_SURFACE */
#endif /* CAIRO_PS_H */
Index: cairo-quartz.h
===================================================================
RCS file: /cvs/cairo/cairo/src/cairo-quartz.h,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -d -r1.2 -r1.3
--- cairo-quartz.h 21 Jan 2005 04:36:25 -0000 1.2
+++ cairo-quartz.h 21 Jan 2005 22:33:48 -0000 1.3
@@ -34,14 +34,17 @@
* Carl D. Worth <cworth at isi.edu>
*/
-#include <cairo.h>
-
#ifndef CAIRO_QUARTZ_H
#define CAIRO_QUARTZ_H
+
+#include <cairo.h>
+
#ifdef CAIRO_HAS_QUARTZ_SURFACE
#include <Carbon/Carbon.h>
+CAIRO_BEGIN_DECLS
+
void
cairo_set_target_quartz_context( cairo_t *cr,
CGContextRef context,
@@ -53,6 +56,8 @@
int width,
int height);
+CAIRO_END_DECLS
+
#endif /* CAIRO_HAS_QUARTZ_SURFACE */
#endif /* CAIRO_QUARTZ_H */
Index: cairo-xcb.h
===================================================================
RCS file: /cvs/cairo/cairo/src/cairo-xcb.h,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -d -r1.1 -r1.2
--- cairo-xcb.h 20 Jan 2005 16:28:54 -0000 1.1
+++ cairo-xcb.h 21 Jan 2005 22:33:48 -0000 1.2
@@ -34,15 +34,18 @@
* Carl D. Worth <cworth at isi.edu>
*/
-#include <cairo.h>
-
#ifndef CAIRO_XCB_H
#define CAIRO_XCB_H
+
+#include <cairo.h>
+
#ifdef CAIRO_HAS_XCB_SURFACE
#include <X11/XCB/xcb.h>
#include <X11/XCB/render.h>
+CAIRO_BEGIN_DECLS
+
void
cairo_set_target_xcb (cairo_t *cr,
XCBConnection *dpy,
@@ -50,5 +53,7 @@
XCBVISUALTYPE *visual,
cairo_format_t format);
+CAIRO_END_DECLS
+
#endif /* CAIRO_HAS_XCB_SURFACE */
#endif /* CAIRO_XCB_H */
Index: cairo-xlib.h
===================================================================
RCS file: /cvs/cairo/cairo/src/cairo-xlib.h,v
retrieving revision 1.6
retrieving revision 1.7
diff -u -d -r1.6 -r1.7
--- cairo-xlib.h 20 Jan 2005 16:28:54 -0000 1.6
+++ cairo-xlib.h 21 Jan 2005 22:33:48 -0000 1.7
@@ -34,14 +34,17 @@
* Carl D. Worth <cworth at isi.edu>
*/
-#include <cairo.h>
-
#ifndef CAIRO_XLIB_H
#define CAIRO_XLIB_H
+
+#include <cairo.h>
+
#ifdef CAIRO_HAS_XLIB_SURFACE
#include <X11/extensions/Xrender.h>
+CAIRO_BEGIN_DECLS
+
/* XXX: This shold be renamed to cairo_set_target_xlib to match the
* other backends */
void
@@ -66,6 +69,8 @@
cairo_xlib_surface_set_size (cairo_surface_t *surface, int width, int height);
*/
+CAIRO_END_DECLS
+
#endif /* CAIRO_HAS_XLIB_SURFACE */
#endif /* CAIRO_XLIB_H */
Index: cairo.h
===================================================================
RCS file: /cvs/cairo/cairo/src/cairo.h,v
retrieving revision 1.67
retrieving revision 1.68
diff -u -d -r1.67 -r1.68
--- cairo.h 20 Jan 2005 16:28:54 -0000 1.67
+++ cairo.h 21 Jan 2005 22:33:48 -0000 1.68
@@ -37,18 +37,24 @@
#ifndef CAIRO_H
#define CAIRO_H
+#ifdef __cplusplus
+# define CAIRO_BEGIN_DECLS extern "C" {
+# define CAIRO_END_DECLS }
+#else
+# define CAIRO_BEGIN_DECLS
+# define CAIRO_END_DECLS
+#endif
+
#include <cairo-features.h>
#include <pixman.h>
+CAIRO_BEGIN_DECLS
+
typedef struct _cairo cairo_t;
typedef struct _cairo_surface cairo_surface_t;
typedef struct _cairo_matrix cairo_matrix_t;
typedef struct _cairo_pattern cairo_pattern_t;
-#ifdef __cplusplus
-extern "C" {
-#endif
-
/* Functions for manipulating state objects */
cairo_t *
cairo_create (void);
@@ -423,12 +429,11 @@
cairo_font_destroy (cairo_font_t *font);
void
-cairo_font_set_transform (cairo_font_t *font,
- cairo_matrix_t *matrix);
-
-void
-cairo_font_current_transform (cairo_font_t *font,
- cairo_matrix_t *matrix);
+cairo_font_glyph_extents (cairo_font_t *font,
+ cairo_matrix_t *font_matrix,
+ cairo_glyph_t *glyphs,
+ int num_glyphs,
+ cairo_text_extents_t *extents);
/* Image functions */
@@ -724,8 +729,6 @@
#define cairo_get_status_string cairo_get_status_string_DEPRECATED_BY_cairo_status_string
#endif
-#ifdef __cplusplus
-}
-#endif
+CAIRO_END_DECLS
#endif /* CAIRO_H */
Index: cairo_cache.c
===================================================================
RCS file: /cvs/cairo/cairo/src/cairo_cache.c,v
retrieving revision 1.6
retrieving revision 1.7
diff -u -d -r1.6 -r1.7
--- cairo_cache.c 11 Jan 2005 18:03:01 -0000 1.6
+++ cairo_cache.c 21 Jan 2005 22:33:48 -0000 1.7
@@ -94,9 +94,9 @@
* a mostly-dead table.
*
* Generally you do not need to worry about freeing cache entries; the
- * cache will expire entries randomly as it experiences memory pressure.
- * There is currently no explicit entry-removing call, though one can be
- * added easily.
+ * cache will expire entries randomly as it experiences memory pressure.
+ * If max_memory is set, entries are not expired, and must be explicitely
+ * removed.
*
* This table is open-addressed with double hashing. Each table size is a
* prime chosen to be a little more than double the high water mark for a
@@ -282,17 +282,51 @@
}
#endif
-static unsigned long
-_random_live_entry (cairo_cache_t *cache)
-{
- unsigned long idx;
- assert(cache != NULL);
- do {
- idx = rand () % cache->arrangement->size;
- } while (! LIVE_ENTRY_P(cache, idx));
- return idx;
-}
+/* Find a random in the cache matching the given predicate. We use the
+ * same algorithm as the probing algorithm to walk over the entries in
+ * the hash table in a pseudo-random order. Walking linearly would
+ * favor entries following gaps in the hash table. We could also
+ * call rand() repeatedly, which works well for almost-full tables,
+ * but degrades when the table is almost empty, or predicate
+ * returns false for most entries.
+ */
+static cairo_cache_entry_base_t **
+_random_entry (cairo_cache_t *cache,
+ int (*predicate)(void*))
+{
+ cairo_cache_entry_base_t **probe;
+ unsigned long hash;
+ unsigned long table_size, i, idx, step;
+
+ _cache_sane_state (cache);
+
+ table_size = cache->arrangement->size;
+ hash = rand ();
+ idx = hash % table_size;
+ step = 0;
+
+ for (i = 0; i < table_size; ++i)
+ {
+ assert(idx < table_size);
+ probe = cache->entries + idx;
+
+ if (LIVE_ENTRY_P(cache, idx)
+ && (!predicate || predicate (*probe)))
+ return probe;
+
+ if (step == 0) {
+ step = hash % cache->arrangement->rehash;
+ if (step == 0)
+ step = 1;
+ }
+ idx += step;
+ if (idx >= table_size)
+ idx -= table_size;
+ }
+
+ return NULL;
+}
/* public API follows */
@@ -356,8 +390,9 @@
cairo_status_t
_cairo_cache_lookup (cairo_cache_t *cache,
- void *key,
- void **entry_return)
+ void *key,
+ void **entry_return,
+ int *created_entry)
{
unsigned long idx;
@@ -392,6 +427,8 @@
cache->hits++;
#endif
*entry_return = *slot;
+ if (created_entry)
+ *created_entry = 0;
return status;
}
@@ -401,19 +438,18 @@
/* Build the new entry. */
status = cache->backend->create_entry (cache, key,
- entry_return);
+ (void **)&new_entry);
if (status != CAIRO_STATUS_SUCCESS)
return status;
- new_entry = (cairo_cache_entry_base_t *) (*entry_return);
-
/* Store the hash value in case the backend forgot. */
new_entry->hashcode = cache->backend->hash (cache, key);
/* Make some entries die if we're under memory pressure. */
while (cache->live_entries > 0 &&
+ cache->max_memory > 0 &&
((cache->max_memory - cache->used_memory) < new_entry->memory)) {
- idx = _random_live_entry (cache);
+ idx = _random_entry (cache, NULL) - cache->entries;
assert (idx < cache->arrangement->size);
_entry_destroy (cache, idx);
}
@@ -425,7 +461,6 @@
status = _resize_cache (cache, cache->live_entries + 1);
if (status != CAIRO_STATUS_SUCCESS) {
cache->backend->destroy_entry (cache, new_entry);
- *entry_return = NULL;
return status;
}
@@ -439,9 +474,38 @@
_cache_sane_state (cache);
+ *entry_return = new_entry;
+ if (created_entry)
+ *created_entry = 1;
+
return status;
}
+cairo_status_t
+_cairo_cache_remove (cairo_cache_t *cache,
+ void *key)
+{
+ cairo_cache_entry_base_t **slot;
+
+ _cache_sane_state (cache);
+
+ /* See if we have an entry in the table already. */
+ slot = _find_exact_live_entry_for (cache, key);
+ if (slot != NULL)
+ _entry_destroy (cache, slot - cache->entries);
+
+ return CAIRO_STATUS_SUCCESS;
+}
+
+void *
+_cairo_cache_random_entry (cairo_cache_t *cache,
+ int (*predicate)(void*))
+{
+ cairo_cache_entry_base_t **slot = _random_entry (cache, predicate);
+
+ return *slot;
+}
+
unsigned long
_cairo_hash_string (const char *c)
{
Index: cairo_font.c
===================================================================
RCS file: /cvs/cairo/cairo/src/cairo_font.c,v
retrieving revision 1.30
retrieving revision 1.31
diff -u -d -r1.30 -r1.31
--- cairo_font.c 13 Jan 2005 14:50:23 -0000 1.30
+++ cairo_font.c 21 Jan 2005 22:33:48 -0000 1.31
@@ -1,6 +1,7 @@
/* cairo - a vector graphics library with display and print output
*
* Copyright © 2002 University of Southern California
+ * Copyright © 2005 Red Hat Inc.
*
* This library is free software; you can redistribute it and/or
* modify it either under the terms of the GNU Lesser General Public
@@ -32,264 +33,85 @@
*
* Contributor(s):
* Carl D. Worth <cworth at isi.edu>
+ * Graydon Hoare <graydon at redhat.com>
+ * Owen Taylor <otaylor at redhat.com>
*/
#include "cairoint.h"
-/* First we implement a global font cache for named fonts. */
-
-typedef struct {
- cairo_cache_entry_base_t base;
- const char *family;
- cairo_font_slant_t slant;
- cairo_font_weight_t weight;
-} cairo_font_cache_key_t;
-
-typedef struct {
- cairo_font_cache_key_t key;
- cairo_unscaled_font_t *unscaled;
-} cairo_font_cache_entry_t;
-
-static unsigned long
-_font_cache_hash (void *cache, void *key)
-{
- unsigned long hash;
- cairo_font_cache_key_t *in;
- in = (cairo_font_cache_key_t *) key;
-
- /* 1607 and 1451 are just a couple random primes. */
- hash = _cairo_hash_string (in->family);
- hash += ((unsigned long) in->slant) * 1607;
- hash += ((unsigned long) in->weight) * 1451;
- return hash;
-}
-
-
-static int
-_font_cache_keys_equal (void *cache,
- void *k1,
- void *k2)
-{
- cairo_font_cache_key_t *a, *b;
- a = (cairo_font_cache_key_t *) k1;
- b = (cairo_font_cache_key_t *) k2;
-
- return (strcmp (a->family, b->family) == 0)
- && (a->weight == b->weight)
- && (a->slant == b->slant);
-}
-
-
-static cairo_status_t
-_font_cache_create_entry (void *cache,
- void *key,
- void **return_value)
-{
- const cairo_font_backend_t *backend = CAIRO_FONT_BACKEND_DEFAULT;
- cairo_font_cache_key_t *k;
- cairo_font_cache_entry_t *entry;
- k = (cairo_font_cache_key_t *) key;
-
- /* XXX: The current freetype backend may return NULL, (for example
- * if no fonts are installed), but I would like to guarantee that
- * the toy API always returns at least *some* font, so I would
- * like to build in some sort fo font here, (even a really lame,
- * ugly one if necessary). */
-
- entry = malloc (sizeof (cairo_font_cache_entry_t));
- if (entry == NULL)
- goto FAIL;
-
- entry->key.slant = k->slant;
- entry->key.weight = k->weight;
- entry->key.family = strdup(k->family);
- if (entry->key.family == NULL)
- goto FREE_ENTRY;
-
- entry->unscaled = backend->create (k->family, k->slant, k->weight);
- if (entry->unscaled == NULL)
- goto FREE_FAMILY;
-
- /* Not sure how to measure backend font mem; use a simple count for now.*/
- entry->key.base.memory = 1;
- *return_value = entry;
- return CAIRO_STATUS_SUCCESS;
-
- FREE_FAMILY:
- free ((void *) entry->key.family);
-
- FREE_ENTRY:
- free (entry);
-
- FAIL:
- return CAIRO_STATUS_NO_MEMORY;
-}
-
-static void
-_font_cache_destroy_entry (void *cache,
- void *entry)
-{
- cairo_font_cache_entry_t *e;
-
- e = (cairo_font_cache_entry_t *) entry;
- _cairo_unscaled_font_destroy (e->unscaled);
- free ((void *) e->key.family);
- free (e);
-}
-
-static void
-_font_cache_destroy_cache (void *cache)
-{
- free (cache);
-}
-
-static const cairo_cache_backend_t cairo_font_cache_backend = {
- _font_cache_hash,
- _font_cache_keys_equal,
- _font_cache_create_entry,
- _font_cache_destroy_entry,
- _font_cache_destroy_cache
-};
-
-static void
-_lock_global_font_cache (void)
-{
- /* FIXME: implement locking. */
-}
-
-static void
-_unlock_global_font_cache (void)
-{
- /* FIXME: implement locking. */
-}
-
-static cairo_cache_t *
-_global_font_cache = NULL;
-
-static cairo_cache_t *
-_get_global_font_cache (void)
-{
- if (_global_font_cache == NULL) {
- _global_font_cache = malloc (sizeof (cairo_cache_t));
-
- if (_global_font_cache == NULL)
- goto FAIL;
-
- if (_cairo_cache_init (_global_font_cache,
- &cairo_font_cache_backend,
- CAIRO_FONT_CACHE_NUM_FONTS_DEFAULT))
- goto FAIL;
- }
-
- return _global_font_cache;
-
- FAIL:
- if (_global_font_cache)
- free (_global_font_cache);
- _global_font_cache = NULL;
- return NULL;
-}
-
-
/* Now the internal "unscaled + scale" font API */
-cairo_unscaled_font_t *
-_cairo_unscaled_font_create (const char *family,
- cairo_font_slant_t slant,
- cairo_font_weight_t weight)
+cairo_private cairo_status_t
+_cairo_font_create (const char *family,
+ cairo_font_slant_t slant,
+ cairo_font_weight_t weight,
+ cairo_font_scale_t *sc,
+ cairo_font_t **font)
{
- cairo_cache_t * cache;
- cairo_font_cache_key_t key;
- cairo_font_cache_entry_t *font;
- cairo_status_t status;
-
- _lock_global_font_cache ();
- cache = _get_global_font_cache ();
- if (cache == NULL) {
- _unlock_global_font_cache ();
- return NULL;
- }
-
- key.family = family;
- key.slant = slant;
- key.weight = weight;
-
- status = _cairo_cache_lookup (cache, &key, (void **) &font);
- if (status) {
- _unlock_global_font_cache ();
- return NULL;
- }
+ const cairo_font_backend_t *backend = CAIRO_FONT_BACKEND_DEFAULT;
- _cairo_unscaled_font_reference (font->unscaled);
- _unlock_global_font_cache ();
- return font->unscaled;
+ return backend->create (family, slant, weight, sc, font);
}
void
-_cairo_font_init (cairo_font_t *scaled,
- cairo_font_scale_t *scale,
- cairo_unscaled_font_t *unscaled)
+_cairo_font_init (cairo_font_t *font,
+ cairo_font_scale_t *scale,
+ const cairo_font_backend_t *backend)
{
- scaled->scale = *scale;
- scaled->unscaled = unscaled;
- scaled->refcount = 1;
+ font->scale = *scale;
+ font->refcount = 1;
+ font->backend = backend;
}
-cairo_status_t
-_cairo_unscaled_font_init (cairo_unscaled_font_t *font,
- const cairo_font_backend_t *backend)
+void
+_cairo_unscaled_font_init (cairo_unscaled_font_t *font,
+ const cairo_font_backend_t *backend)
{
font->refcount = 1;
font->backend = backend;
- return CAIRO_STATUS_SUCCESS;
}
-
cairo_status_t
-_cairo_unscaled_font_text_to_glyphs (cairo_unscaled_font_t *font,
- cairo_font_scale_t *scale,
- const unsigned char *utf8,
- cairo_glyph_t **glyphs,
- int *num_glyphs)
+_cairo_font_text_to_glyphs (cairo_font_t *font,
+ const unsigned char *utf8,
+ cairo_glyph_t **glyphs,
+ int *num_glyphs)
{
- return font->backend->text_to_glyphs (font, scale, utf8, glyphs, num_glyphs);
+ return font->backend->text_to_glyphs (font, utf8, glyphs, num_glyphs);
}
cairo_status_t
-_cairo_unscaled_font_glyph_extents (cairo_unscaled_font_t *font,
- cairo_font_scale_t *scale,
- cairo_glyph_t *glyphs,
- int num_glyphs,
- cairo_text_extents_t *extents)
+_cairo_font_glyph_extents (cairo_font_t *font,
+ cairo_glyph_t *glyphs,
+ int num_glyphs,
+ cairo_text_extents_t *extents)
{
- return font->backend->glyph_extents(font, scale, glyphs, num_glyphs, extents);
+ return font->backend->glyph_extents(font, glyphs, num_glyphs, extents);
}
cairo_status_t
-_cairo_unscaled_font_glyph_bbox (cairo_unscaled_font_t *font,
- cairo_font_scale_t *scale,
- cairo_glyph_t *glyphs,
- int num_glyphs,
- cairo_box_t *bbox)
+_cairo_font_glyph_bbox (cairo_font_t *font,
+ cairo_glyph_t *glyphs,
+ int num_glyphs,
+ cairo_box_t *bbox)
{
- return font->backend->glyph_bbox (font, scale, glyphs, num_glyphs, bbox);
+ return font->backend->glyph_bbox (font, glyphs, num_glyphs, bbox);
}
cairo_status_t
-_cairo_unscaled_font_show_glyphs (cairo_unscaled_font_t *font,
- cairo_font_scale_t *scale,
- cairo_operator_t operator,
- cairo_surface_t *source,
- cairo_surface_t *surface,
- int source_x,
- int source_y,
- cairo_glyph_t *glyphs,
- int num_glyphs)
+_cairo_font_show_glyphs (cairo_font_t *font,
+ cairo_operator_t operator,
+ cairo_surface_t *source,
+ cairo_surface_t *surface,
+ int source_x,
+ int source_y,
+ cairo_glyph_t *glyphs,
+ int num_glyphs)
{
cairo_status_t status;
if (surface->backend->show_glyphs != NULL) {
- status = surface->backend->show_glyphs (font, scale, operator, source,
+ status = surface->backend->show_glyphs (font, operator, source,
surface, source_x, source_y,
glyphs, num_glyphs);
if (status == CAIRO_STATUS_SUCCESS)
@@ -297,27 +119,32 @@
}
/* Surface display routine either does not exist or failed. */
- return font->backend->show_glyphs (font, scale, operator, source,
+ return font->backend->show_glyphs (font, operator, source,
surface, source_x, source_y,
glyphs, num_glyphs);
}
cairo_status_t
-_cairo_unscaled_font_glyph_path (cairo_unscaled_font_t *font,
- cairo_font_scale_t *scale,
- cairo_glyph_t *glyphs,
- int num_glyphs,
- cairo_path_t *path)
+_cairo_font_glyph_path (cairo_font_t *font,
+ cairo_glyph_t *glyphs,
+ int num_glyphs,
+ cairo_path_t *path)
{
- return font->backend->glyph_path (font, scale, glyphs, num_glyphs, path);
+ return font->backend->glyph_path (font, glyphs, num_glyphs, path);
+}
+
+void
+_cairo_font_get_glyph_cache_key (cairo_font_t *font,
+ cairo_glyph_cache_key_t *key)
+{
+ font->backend->get_glyph_cache_key (font, key);
}
cairo_status_t
-_cairo_unscaled_font_font_extents (cairo_unscaled_font_t *font,
- cairo_font_scale_t *scale,
- cairo_font_extents_t *extents)
+_cairo_font_font_extents (cairo_font_t *font,
+ cairo_font_extents_t *extents)
{
- return font->backend->font_extents(font, scale, extents);
+ return font->backend->font_extents (font, extents);
}
void
@@ -332,8 +159,7 @@
if (--(font->refcount) > 0)
return;
- if (font->backend)
- font->backend->destroy (font);
+ font->backend->destroy_unscaled_font (font);
}
@@ -352,37 +178,97 @@
if (--(font->refcount) > 0)
return;
- if (font->unscaled)
- _cairo_unscaled_font_destroy (font->unscaled);
-
- free (font);
+ font->backend->destroy_font (font);
}
void
-cairo_font_set_transform (cairo_font_t *font,
- cairo_matrix_t *matrix)
+cairo_font_glyph_extents (cairo_font_t *font,
+ cairo_matrix_t *font_matrix,
+ cairo_glyph_t *glyphs,
+ int num_glyphs,
+ cairo_text_extents_t *extents)
{
- double dummy;
- cairo_matrix_get_affine (matrix,
- &font->scale.matrix[0][0],
- &font->scale.matrix[0][1],
- &font->scale.matrix[1][0],
- &font->scale.matrix[1][1],
- &dummy, &dummy);
-}
+ cairo_status_t status = CAIRO_STATUS_SUCCESS;
+ cairo_glyph_t origin_glyph;
+ cairo_text_extents_t origin_extents;
+ int i;
+ double min_x = 0.0, min_y = 0.0, max_x = 0.0, max_y = 0.0;
+ double x_pos = 0.0, y_pos = 0.0;
+ int set = 0;
-void
-cairo_font_current_transform (cairo_font_t *font,
- cairo_matrix_t *matrix)
-{
- cairo_matrix_set_affine (matrix,
- font->scale.matrix[0][0],
- font->scale.matrix[0][1],
- font->scale.matrix[1][0],
- font->scale.matrix[1][1],
- 0, 0);
-}
+ if (!num_glyphs)
+ {
+ extents->x_bearing = 0.0;
+ extents->y_bearing = 0.0;
+ extents->width = 0.0;
+ extents->height = 0.0;
+ extents->x_advance = 0.0;
+ extents->y_advance = 0.0;
+
+ return;
+ }
+
+ for (i = 0; i < num_glyphs; i++)
+ {
+ double x, y;
+ double wm, hm;
+
+ origin_glyph = glyphs[i];
+ origin_glyph.x = 0.0;
+ origin_glyph.y = 0.0;
+ status = _cairo_font_glyph_extents (font,
+ &origin_glyph, 1,
+ &origin_extents);
+
+ /*
+ * Transform font space metrics into user space metrics
+ * by running the corners through the font matrix and
+ * expanding the bounding box as necessary
+ */
+ x = origin_extents.x_bearing;
+ y = origin_extents.y_bearing;
+ cairo_matrix_transform_point (font_matrix,
+ &x, &y);
+ for (hm = 0.0; hm <= 1.0; hm += 1.0)
+ for (wm = 0.0; wm <= 1.0; wm += 1.0)
+ {
+ x = origin_extents.x_bearing + origin_extents.width * wm;
+ y = origin_extents.y_bearing + origin_extents.height * hm;
+ cairo_matrix_transform_point (font_matrix,
+ &x, &y);
+ x += glyphs[i].x;
+ y += glyphs[i].y;
+ if (!set)
+ {
+ min_x = max_x = x;
+ min_y = max_y = y;
+ set = 1;
+ }
+ else
+ {
+ if (x < min_x) min_x = x;
+ if (x > max_x) max_x = x;
+ if (y < min_y) min_y = y;
+ if (y > max_y) max_y = y;
+ }
+ }
+
+ x = origin_extents.x_advance;
+ y = origin_extents.y_advance;
+ cairo_matrix_transform_point (font_matrix,
+ &x, &y);
+ x_pos = glyphs[i].x + x;
+ y_pos = glyphs[i].y + y;
+ }
+
+ extents->x_bearing = min_x - glyphs[0].x;
+ extents->y_bearing = min_y - glyphs[0].y;
+ extents->width = max_x - min_x;
+ extents->height = max_y - min_y;
+ extents->x_advance = x_pos - glyphs[0].x;
+ extents->y_advance = y_pos - glyphs[0].y;
+}
/* Now we implement functions to access a default global image & metrics
* cache.
@@ -398,7 +284,8 @@
^ ((unsigned long) in->scale.matrix[0][0])
^ ((unsigned long) in->scale.matrix[0][1])
^ ((unsigned long) in->scale.matrix[1][0])
- ^ ((unsigned long) in->scale.matrix[1][1])
+ ^ ((unsigned long) in->scale.matrix[1][1])
+ ^ (in->flags * 1451) /* 1451 is just an abitrary prime */
^ in->index;
}
@@ -412,6 +299,7 @@
b = (cairo_glyph_cache_key_t *) k2;
return (a->index == b->index)
&& (a->unscaled == b->unscaled)
+ && (a->flags == b->flags)
&& (a->scale.matrix[0][0] == b->scale.matrix[0][0])
&& (a->scale.matrix[0][1] == b->scale.matrix[0][1])
&& (a->scale.matrix[1][0] == b->scale.matrix[1][0])
Index: cairo_ft_font.c
===================================================================
RCS file: /cvs/cairo/cairo/src/cairo_ft_font.c,v
retrieving revision 1.32
retrieving revision 1.33
diff -u -d -r1.32 -r1.33
--- cairo_ft_font.c 20 Jan 2005 16:28:54 -0000 1.32
+++ cairo_ft_font.c 21 Jan 2005 22:33:48 -0000 1.33
@@ -1,29 +1,40 @@
-/*
- * Copyright © 2003 Red Hat Inc.
+/* cairo - a vector graphics library with display and print output
*
- * Permission to use, copy, modify, distribute, and sell this software and
- * its documentation for any purpose is hereby granted without fee,
- * provided that the above copyright notice appear in all copies and that
- * both that copyright notice and this permission notice appear in
- * supporting documentation, and that the name of Red Hat Inc. not be used
- * in advertising or publicity pertaining to distribution of the software
- * without specific, written prior permission. Red Hat Inc. makes no
[...1415 lines suppressed...]
+{
+ cairo_ft_font_t *font = (cairo_ft_font_t *) font;
+
+ return (cairo_unscaled_font_t *)font->unscaled;
+}
+
+/* This differs from _cairo_ft_scaled_font_lock_face in that it doesn't
+ * set the scale on the face, but just returns it at the last scale.
+ */
+FT_Face
+_cairo_ft_unscaled_font_lock_face (cairo_unscaled_font_t *unscaled_font)
+{
+ return _ft_unscaled_font_lock_face ((ft_unscaled_font_t *)unscaled_font);
+}
+
+void
+_cairo_ft_unscaled_font_unlock_face (cairo_unscaled_font_t *unscaled_font)
+{
+ _ft_unscaled_font_unlock_face ((ft_unscaled_font_t *)unscaled_font);
+}
Index: cairo_gstate.c
===================================================================
RCS file: /cvs/cairo/cairo/src/cairo_gstate.c,v
retrieving revision 1.72
retrieving revision 1.73
diff -u -d -r1.72 -r1.73
--- cairo_gstate.c 19 Jan 2005 20:12:42 -0000 1.72
+++ cairo_gstate.c 21 Jan 2005 22:33:48 -0000 1.73
@@ -45,6 +45,8 @@
cairo_operator_t operator,
cairo_surface_t *dst,
cairo_traps_t *traps);
+static void
+_cairo_gstate_unset_font (cairo_gstate_t *gstate);
cairo_gstate_t *
_cairo_gstate_create ()
@@ -77,9 +79,11 @@
gstate->num_dashes = 0;
gstate->dash_offset = 0.0;
- gstate->font = _cairo_unscaled_font_create (CAIRO_FONT_FAMILY_DEFAULT,
- CAIRO_FONT_SLANT_DEFAULT,
- CAIRO_FONT_WEIGHT_DEFAULT);
+ gstate->font_family = NULL;
+ gstate->font_slant = CAIRO_FONT_SLANT_DEFAULT;
+ gstate->font_weight = CAIRO_FONT_WEIGHT_DEFAULT;
+
+ gstate->font = NULL;
gstate->surface = NULL;
@@ -118,9 +122,15 @@
memcpy (gstate->dash, other->dash, other->num_dashes * sizeof (double));
}
+ if (other->font_family) {
+ gstate->font_family = strdup (other->font_family);
+ if (!gstate->font_family)
+ goto CLEANUP_DASH;
+ }
+
if (other->font) {
gstate->font = other->font;
- _cairo_unscaled_font_reference (gstate->font);
+ cairo_font_reference (gstate->font);
}
if (other->clip.region)
@@ -148,18 +158,29 @@
_cairo_path_fini (&gstate->path);
CLEANUP_FONT:
- _cairo_unscaled_font_destroy (gstate->font);
+ cairo_font_destroy (gstate->font);
+ gstate->font = NULL;
+
+ if (gstate->font_family) {
+ free (gstate->font_family);
+ gstate->font_family = NULL;
+ }
+ CLEANUP_DASH:
free (gstate->dash);
gstate->dash = NULL;
- return status;
+ return CAIRO_STATUS_NO_MEMORY;
}
void
_cairo_gstate_fini (cairo_gstate_t *gstate)
{
- _cairo_unscaled_font_destroy (gstate->font);
+ if (gstate->font_family)
+ free (gstate->font_family);
+
+ if (gstate->font)
+ cairo_font_destroy (gstate->font);
if (gstate->surface)
cairo_surface_destroy (gstate->surface);
@@ -323,6 +344,8 @@
{
double scale;
+ _cairo_gstate_unset_font (gstate);
+
if (gstate->surface)
cairo_surface_destroy (gstate->surface);
@@ -549,6 +572,8 @@
{
cairo_matrix_t tmp;
+ _cairo_gstate_unset_font (gstate);
+
_cairo_matrix_set_translate (&tmp, tx, ty);
cairo_matrix_multiply (&gstate->ctm, &tmp, &gstate->ctm);
@@ -566,6 +591,8 @@
if (sx == 0 || sy == 0)
return CAIRO_STATUS_INVALID_MATRIX;
+ _cairo_gstate_unset_font (gstate);
+
_cairo_matrix_set_scale (&tmp, sx, sy);
cairo_matrix_multiply (&gstate->ctm, &tmp, &gstate->ctm);
@@ -580,6 +607,8 @@
{
cairo_matrix_t tmp;
+ _cairo_gstate_unset_font (gstate);
+
_cairo_matrix_set_rotate (&tmp, angle);
cairo_matrix_multiply (&gstate->ctm, &tmp, &gstate->ctm);
@@ -595,6 +624,8 @@
{
cairo_matrix_t tmp;
+ _cairo_gstate_unset_font (gstate);
+
cairo_matrix_copy (&tmp, matrix);
cairo_matrix_multiply (&gstate->ctm, &tmp, &gstate->ctm);
@@ -610,6 +641,8 @@
{
cairo_status_t status;
+ _cairo_gstate_unset_font (gstate);
+
cairo_matrix_copy (&gstate->ctm, matrix);
cairo_matrix_copy (&gstate->ctm_inverse, matrix);
@@ -627,6 +660,8 @@
if (scale == 0)
scale = 1;
+ _cairo_gstate_unset_font (gstate);
+
cairo_matrix_set_identity (&gstate->font_matrix);
cairo_matrix_set_identity (&gstate->ctm);
@@ -640,6 +675,8 @@
cairo_status_t
_cairo_gstate_identity_matrix (cairo_gstate_t *gstate)
{
+ _cairo_gstate_unset_font (gstate);
+
cairo_matrix_set_identity (&gstate->ctm);
cairo_matrix_set_identity (&gstate->ctm_inverse);
@@ -2121,6 +2158,14 @@
return CAIRO_STATUS_SUCCESS;
}
+static void
+_cairo_gstate_unset_font (cairo_gstate_t *gstate)
+{
+ if (gstate->font) {
+ cairo_font_destroy (gstate->font);
+ gstate->font = NULL;
+ }
+}
cairo_status_t
_cairo_gstate_select_font (cairo_gstate_t *gstate,
@@ -2128,12 +2173,17 @@
cairo_font_slant_t slant,
cairo_font_weight_t weight)
{
- if (gstate->font)
- _cairo_unscaled_font_destroy (gstate->font);
+ char *new_family;
- gstate->font = _cairo_unscaled_font_create (family, slant, weight);
- if (gstate->font == NULL)
+ new_family = strdup (family);
+ if (!new_family)
return CAIRO_STATUS_NO_MEMORY;
+
+ _cairo_gstate_unset_font (gstate);
+
+ gstate->font_family = new_family;
+ gstate->font_slant = slant;
+ gstate->font_weight = weight;
cairo_matrix_set_identity (&gstate->font_matrix);
@@ -2144,6 +2194,8 @@
_cairo_gstate_scale_font (cairo_gstate_t *gstate,
double scale)
{
+ _cairo_gstate_unset_font (gstate);
+
return cairo_matrix_scale (&gstate->font_matrix, scale, scale);
}
@@ -2153,6 +2205,9 @@
{
cairo_matrix_t tmp;
double a, b, c, d, tx, ty;
+
+ _cairo_gstate_unset_font (gstate);
+
cairo_matrix_get_affine (matrix, &a, &b, &c, &d, &tx, &ty);
cairo_matrix_set_affine (&tmp, a, b, c, d, 0, 0);
return cairo_matrix_multiply (&gstate->font_matrix, &gstate->font_matrix, &tmp);
@@ -2160,28 +2215,10 @@
cairo_status_t
-_cairo_gstate_current_font (cairo_gstate_t *gstate,
- cairo_font_t **font)
+_cairo_gstate_current_font (cairo_gstate_t *gstate, cairo_font_t **font)
{
- cairo_font_scale_t scale;
- cairo_font_t *scaled;
- double dummy;
-
- scaled = malloc (sizeof (cairo_font_t));
- if (scaled == NULL)
- return CAIRO_STATUS_NO_MEMORY;
-
- cairo_matrix_get_affine (&gstate->font_matrix,
- &scale.matrix[0][0],
- &scale.matrix[0][1],
- &scale.matrix[1][0],
- &scale.matrix[1][1],
- &dummy, &dummy);
-
- _cairo_font_init (scaled, &scale, gstate->font);
- _cairo_unscaled_font_reference (gstate->font);
-
- *font = scaled;
+ *font = gstate->font;
+ cairo_font_reference (*font);
return CAIRO_STATUS_SUCCESS;
}
@@ -2190,6 +2227,8 @@
_cairo_gstate_set_font_transform (cairo_gstate_t *gstate,
cairo_matrix_t *matrix)
{
+ _cairo_gstate_unset_font (gstate);
+
cairo_matrix_copy (&gstate->font_matrix, matrix);
}
@@ -2214,12 +2253,10 @@
* independently scale the user coordinate system *or* the font matrix, in
* order to adjust the rendered size of the font.
*
- * If the user asks for a permanent reference to "a font", they are given a
- * handle to a structure holding a scale matrix and an unscaled font. This
- * effectively decouples the font from further changes to user space. Even
- * if the user then "sets" the current cairo_t font to the handle they were
- * passed, further changes to the cairo_t CTM will not affect externally
- * held references to the font.
+ * The only font type exposed to the user is cairo_font_t which is a
+ * a font specialized to a particular scale matrix, CTM, and target
+ * surface. The user is responsible for not using a cairo_font_t
+ * after changing the parameters; doing so will produce garbled metrics.
*
*
* The font's view
@@ -2279,9 +2316,9 @@
*
*/
-static void
-_build_font_scale (cairo_gstate_t *gstate,
- cairo_font_scale_t *sc)
+void
+_cairo_gstate_current_font_scale (cairo_gstate_t *gstate,
+ cairo_font_scale_t *sc)
{
cairo_matrix_t tmp;
double dummy;
@@ -2294,17 +2331,47 @@
&dummy, &dummy);
}
+static cairo_status_t
+_cairo_gstate_ensure_font (cairo_gstate_t *gstate)
+{
+ cairo_font_scale_t sc;
+ cairo_status_t status;
+ const char *family;
+
+ if (gstate->font)
+ return CAIRO_STATUS_SUCCESS;
+
+ _cairo_gstate_current_font_scale (gstate, &sc);
+
+ if (gstate->font_family)
+ family = gstate->font_family;
+ else
+ family = CAIRO_FONT_FAMILY_DEFAULT;
+
+ status = _cairo_font_create (family,
+ gstate->font_slant,
+ gstate->font_weight,
+ &sc,
+ &gstate->font);
+
+ if (status)
+ return status;
+
+ return CAIRO_STATUS_SUCCESS;
+}
+
cairo_status_t
_cairo_gstate_current_font_extents (cairo_gstate_t *gstate,
cairo_font_extents_t *extents)
{
cairo_int_status_t status;
- cairo_font_scale_t sc;
double font_scale_x, font_scale_y;
- _build_font_scale (gstate, &sc);
-
- status = _cairo_unscaled_font_font_extents (gstate->font, &sc, extents);
+ status = _cairo_gstate_ensure_font (gstate);
+ if (status)
+ return status;
+
+ status = _cairo_font_font_extents (gstate->font, extents);
_cairo_matrix_compute_scale_factors (&gstate->font_matrix,
&font_scale_x, &font_scale_y,
@@ -2331,14 +2398,15 @@
int *nglyphs)
{
cairo_status_t status;
- cairo_font_scale_t sc;
cairo_point_t point;
double origin_x, origin_y;
int i;
- _build_font_scale (gstate, &sc);
-
+ status = _cairo_gstate_ensure_font (gstate);
+ if (status)
+ return status;
+
status = _cairo_path_current_point (&gstate->path, &point);
if (status == CAIRO_STATUS_NO_CURRENT_POINT) {
origin_x = 0.0;
@@ -2350,8 +2418,8 @@
&origin_x, &origin_y);
}
- status = _cairo_unscaled_font_text_to_glyphs (gstate->font,
- &sc, utf8, glyphs, nglyphs);
+ status = _cairo_font_text_to_glyphs (gstate->font,
+ utf8, glyphs, nglyphs);
if (status || !glyphs || !nglyphs || !(*glyphs) || !(nglyphs))
return status;
@@ -2373,18 +2441,13 @@
cairo_status_t
_cairo_gstate_set_font (cairo_gstate_t *gstate,
- cairo_font_t *font)
+ cairo_font_t *font)
{
if (gstate->font != NULL)
- _cairo_unscaled_font_destroy (gstate->font);
- gstate->font = font->unscaled;
- _cairo_unscaled_font_reference (gstate->font);
- cairo_matrix_set_affine (&gstate->font_matrix,
- font->scale.matrix[0][0],
- font->scale.matrix[0][1],
- font->scale.matrix[1][0],
- font->scale.matrix[1][1],
- 0, 0);
+ cairo_font_destroy (gstate->font);
+ gstate->font = font;
+ cairo_font_reference (gstate->font);
+
return CAIRO_STATUS_SUCCESS;
}
@@ -2394,90 +2457,18 @@
int num_glyphs,
cairo_text_extents_t *extents)
{
- cairo_status_t status = CAIRO_STATUS_SUCCESS;
- cairo_glyph_t origin_glyph;
- cairo_text_extents_t origin_extents;
- cairo_font_scale_t sc;
- int i;
- double min_x = 0.0, min_y = 0.0, max_x = 0.0, max_y = 0.0;
- double x_pos = 0.0, y_pos = 0.0;
- int set = 0;
-
- if (!num_glyphs)
- {
- extents->x_bearing = 0.0;
- extents->y_bearing = 0.0;
- extents->width = 0.0;
- extents->height = 0.0;
- extents->x_advance = 0.0;
- extents->y_advance = 0.0;
- return CAIRO_STATUS_SUCCESS;
- }
-
- _build_font_scale (gstate, &sc);
-
- for (i = 0; i < num_glyphs; i++)
- {
- double x, y;
- double wm, hm;
-
- origin_glyph = glyphs[i];
- origin_glyph.x = 0.0;
- origin_glyph.y = 0.0;
- status = _cairo_unscaled_font_glyph_extents (gstate->font, &sc,
- &origin_glyph, 1,
- &origin_extents);
-
- /*
- * Transform font space metrics into user space metrics
- * by running the corners through the font matrix and
- * expanding the bounding box as necessary
- */
- x = origin_extents.x_bearing;
- y = origin_extents.y_bearing;
- cairo_matrix_transform_point (&gstate->font_matrix,
- &x, &y);
-
- for (hm = 0.0; hm <= 1.0; hm += 1.0)
- for (wm = 0.0; wm <= 1.0; wm += 1.0)
- {
- x = origin_extents.x_bearing + origin_extents.width * wm;
- y = origin_extents.y_bearing + origin_extents.height * hm;
- cairo_matrix_transform_point (&gstate->font_matrix,
- &x, &y);
- x += glyphs[i].x;
- y += glyphs[i].y;
- if (!set)
- {
- min_x = max_x = x;
- min_y = max_y = y;
- set = 1;
- }
- else
- {
- if (x < min_x) min_x = x;
- if (x > max_x) max_x = x;
- if (y < min_y) min_y = y;
- if (y > max_y) max_y = y;
- }
- }
+ cairo_status_t status;
- x = origin_extents.x_advance;
- y = origin_extents.y_advance;
- cairo_matrix_transform_point (&gstate->font_matrix,
- &x, &y);
- x_pos = glyphs[i].x + x;
- y_pos = glyphs[i].y + y;
- }
+ status = _cairo_gstate_ensure_font (gstate);
+ if (status)
+ return status;
- extents->x_bearing = min_x - glyphs[0].x;
- extents->y_bearing = min_y - glyphs[0].y;
- extents->width = max_x - min_x;
- extents->height = max_y - min_y;
- extents->x_advance = x_pos - glyphs[0].x;
- extents->y_advance = y_pos - glyphs[0].y;
+ cairo_font_glyph_extents (gstate->font,
+ &gstate->font_matrix,
+ glyphs, num_glyphs,
+ extents);
- return status;
+ return CAIRO_STATUS_SUCCESS;
}
cairo_status_t
@@ -2488,12 +2479,13 @@
cairo_status_t status;
int i;
cairo_glyph_t *transformed_glyphs = NULL;
- cairo_font_scale_t sc;
cairo_pattern_t pattern;
cairo_box_t bbox;
- _build_font_scale (gstate, &sc);
-
+ status = _cairo_gstate_ensure_font (gstate);
+ if (status)
+ return status;
+
transformed_glyphs = malloc (num_glyphs * sizeof(cairo_glyph_t));
if (transformed_glyphs == NULL)
return CAIRO_STATUS_NO_MEMORY;
@@ -2507,9 +2499,9 @@
}
_cairo_pattern_init_copy (&pattern, gstate->pattern);
- status = _cairo_unscaled_font_glyph_bbox (gstate->font, &sc,
- transformed_glyphs, num_glyphs,
- &bbox);
+ status = _cairo_font_glyph_bbox (gstate->font,
+ transformed_glyphs, num_glyphs,
+ &bbox);
if (status)
goto CLEANUP_GLYPHS;
@@ -2565,14 +2557,13 @@
transformed_glyphs[i].y -= draw_extents->y1;
}
- status = _cairo_unscaled_font_show_glyphs (gstate->font,
- &sc,
- CAIRO_OPERATOR_ADD,
- pattern.source, intermediate,
- draw_extents->x1 - pattern.source_offset.x,
- draw_extents->y1 - pattern.source_offset.y,
- transformed_glyphs, num_glyphs);
-
+ status = _cairo_font_show_glyphs (gstate->font,
+ CAIRO_OPERATOR_ADD,
+ pattern.source, intermediate,
+ draw_extents->x1 - pattern.source_offset.x,
+ draw_extents->y1 - pattern.source_offset.y,
+ transformed_glyphs, num_glyphs);
+
if (status)
goto BAIL2;
@@ -2610,13 +2601,12 @@
}
else
{
- status = _cairo_unscaled_font_show_glyphs (gstate->font,
- &sc,
- gstate->operator, pattern.source,
- gstate->surface,
- -pattern.source_offset.x,
- -pattern.source_offset.y,
- transformed_glyphs, num_glyphs);
+ status = _cairo_font_show_glyphs (gstate->font,
+ gstate->operator, pattern.source,
+ gstate->surface,
+ -pattern.source_offset.x,
+ -pattern.source_offset.y,
+ transformed_glyphs, num_glyphs);
}
_cairo_pattern_fini (&pattern);
@@ -2635,9 +2625,6 @@
cairo_status_t status;
int i;
cairo_glyph_t *transformed_glyphs = NULL;
- cairo_font_scale_t sc;
-
- _build_font_scale (gstate, &sc);
transformed_glyphs = malloc (num_glyphs * sizeof(cairo_glyph_t));
if (transformed_glyphs == NULL)
@@ -2651,9 +2638,9 @@
&(transformed_glyphs[i].y));
}
- status = _cairo_unscaled_font_glyph_path (gstate->font, &sc,
- transformed_glyphs, num_glyphs,
- &gstate->path);
+ status = _cairo_font_glyph_path (gstate->font,
+ transformed_glyphs, num_glyphs,
+ &gstate->path);
free (transformed_glyphs);
return status;
Index: cairo_pdf_surface.c
===================================================================
RCS file: /cvs/cairo/cairo/src/cairo_pdf_surface.c,v
retrieving revision 1.7
retrieving revision 1.8
diff -u -d -r1.7 -r1.8
--- cairo_pdf_surface.c 20 Jan 2005 16:28:54 -0000 1.7
+++ cairo_pdf_surface.c 21 Jan 2005 22:33:48 -0000 1.8
@@ -36,9 +36,8 @@
#include "cairoint.h"
#include "cairo-pdf.h"
-/* XXX: This seems broken to me. What about users without freetype
- * that want to use a cairo PDF surface? */
-#include "cairo-ft.h"
+/* XXX: Eventually, we need to handle other font backends */
+#include "cairo-ft-private.h"
#include <ft2build.h>
#include FT_FREETYPE_H
@@ -300,19 +299,15 @@
}
static cairo_pdf_font_t *
-cairo_pdf_ft_font_create (cairo_pdf_document_t *document,
- cairo_unscaled_font_t *unscaled_font,
- cairo_font_scale_t *scale)
+cairo_pdf_ft_font_create (cairo_pdf_document_t *document,
+ cairo_unscaled_font_t *unscaled_font)
{
- cairo_font_t scaled_font;
FT_Face face;
cairo_pdf_ft_font_t *font;
unsigned long size;
int i, j;
- /* FIXME: Why do I have to pass a scaled font to get the FT_Face? */
- _cairo_font_init (&scaled_font, scale, unscaled_font);
- face = cairo_ft_font_face (&scaled_font);
+ face = _cairo_ft_unscaled_font_lock_face (unscaled_font);
/* We currently only support freetype truetype fonts. */
size = 0;
@@ -333,7 +328,8 @@
if (_cairo_array_grow_by (&font->output, 4096) != CAIRO_STATUS_SUCCESS)
goto fail1;
- font->face = face;
+ font->base.unscaled_font = unscaled_font;
+ _cairo_unscaled_font_reference (unscaled_font);
font->glyphs = calloc (face->num_glyphs + 1, sizeof (ft_subset_glyph_t));
if (font->glyphs == NULL)
goto fail2;
@@ -364,6 +360,8 @@
if (font->base.widths == NULL)
goto fail5;
+ _cairo_ft_unscaled_font_unlock_face (unscaled_font);
+
font->status = CAIRO_STATUS_SUCCESS;
return &font->base;
@@ -764,12 +762,15 @@
unsigned long start, end, next, checksum;
int i;
+ font->face = _cairo_ft_unscaled_font_lock_face (font->base.unscaled_font);
+
if (cairo_pdf_ft_font_write_offset_table (font))
- return font->status;
+ goto fail;
start = cairo_pdf_ft_font_align_output (font);
end = start;
+ end = 0;
for (i = 0; i < ARRAY_LENGTH (truetype_tables); i++) {
if (truetype_tables[i].write (font, truetype_tables[i].tag))
goto fail;
@@ -789,6 +790,9 @@
*length = _cairo_array_num_elements (&font->output);
fail:
+ _cairo_ft_unscaled_font_unlock_face (font->base.unscaled_font);
+ font->face = NULL;
+
return font->status;
}
@@ -1704,36 +1708,37 @@
static cairo_pdf_font_t *
_cairo_pdf_document_get_font (cairo_pdf_document_t *document,
- cairo_unscaled_font_t *unscaled_font,
- cairo_font_scale_t *scale)
+ cairo_font_t *font)
{
- cairo_pdf_font_t *font;
+ cairo_unscaled_font_t *unscaled_font;
+ cairo_pdf_font_t *pdf_font;
unsigned int num_fonts, i;
+ unscaled_font = _cairo_ft_font_get_unscaled_font (font);
+
num_fonts = _cairo_array_num_elements (&document->fonts);
for (i = 0; i < num_fonts; i++) {
- _cairo_array_copy_element (&document->fonts, i, &font);
- if (font->unscaled_font == unscaled_font)
- return font;
+ _cairo_array_copy_element (&document->fonts, i, &pdf_font);
+ if (pdf_font->unscaled_font == unscaled_font)
+ return pdf_font;
}
/* FIXME: Figure out here which font backend is in use and call
* the appropriate constructor. */
- font = cairo_pdf_ft_font_create (document, unscaled_font, scale);
+ pdf_font = cairo_pdf_ft_font_create (document, unscaled_font);
if (font == NULL)
return NULL;
- if (_cairo_array_append (&document->fonts, &font, 1) == NULL) {
- cairo_pdf_font_destroy (font);
+ if (_cairo_array_append (&document->fonts, &pdf_font, 1) == NULL) {
+ cairo_pdf_font_destroy (pdf_font);
return NULL;
}
- return font;
+ return pdf_font;
}
static cairo_status_t
-_cairo_pdf_surface_show_glyphs (cairo_unscaled_font_t *font,
- cairo_font_scale_t *scale,
+_cairo_pdf_surface_show_glyphs (cairo_font_t *font,
cairo_operator_t operator,
cairo_surface_t *source,
void *abstract_surface,
@@ -1748,7 +1753,7 @@
cairo_pdf_font_t *pdf_font;
int i, index;
- pdf_font = _cairo_pdf_document_get_font (document, font, scale);
+ pdf_font = _cairo_pdf_document_get_font (document, font);
if (pdf_font == NULL)
return CAIRO_STATUS_NO_MEMORY;
@@ -1761,10 +1766,10 @@
fprintf (file,
" %f %f %f %f %f %f Tm (%c) Tj",
- scale->matrix[0][0],
- scale->matrix[0][1],
- scale->matrix[1][0],
- -scale->matrix[1][1],
+ font->scale.matrix[0][0],
+ font->scale.matrix[0][1],
+ font->scale.matrix[1][0],
+ -font->scale.matrix[1][1],
glyphs[i].x,
glyphs[i].y,
index);
Index: cairo_quartz_surface.c
===================================================================
RCS file: /cvs/cairo/cairo/src/cairo_quartz_surface.c,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -d -r1.2 -r1.3
--- cairo_quartz_surface.c 21 Jan 2005 04:36:25 -0000 1.2
+++ cairo_quartz_surface.c 21 Jan 2005 22:33:48 -0000 1.3
@@ -1,6 +1,6 @@
/* cairo - a vector graphics library with display and print output
*
- * Copyright © 2004 Calum Robinson
+ * Copyright © 2004 Calum Robinson
*
* This library is free software; you can redistribute it and/or
* modify it either under the terms of the GNU Lesser General Public
Index: cairo_xlib_surface.c
===================================================================
RCS file: /cvs/cairo/cairo/src/cairo_xlib_surface.c,v
retrieving revision 1.37
retrieving revision 1.38
diff -u -d -r1.37 -r1.38
--- cairo_xlib_surface.c 20 Jan 2005 16:28:54 -0000 1.37
+++ cairo_xlib_surface.c 21 Jan 2005 22:33:48 -0000 1.38
@@ -694,8 +694,7 @@
}
static cairo_status_t
-_cairo_xlib_surface_show_glyphs (cairo_unscaled_font_t *font,
- cairo_font_scale_t *scale,
+_cairo_xlib_surface_show_glyphs (cairo_font_t *font,
cairo_operator_t operator,
cairo_surface_t *source,
void *abstract_surface,
@@ -824,6 +823,7 @@
} glyphset_cache_t;
typedef struct {
+ int refcount;
cairo_glyph_cache_key_t key;
Glyph glyph;
XGlyphInfo info;
@@ -854,17 +854,18 @@
_cairo_lock_global_image_glyph_cache ();
im_cache = _cairo_get_global_image_glyph_cache ();
- if (g == NULL || v == NULL ||g == NULL || im_cache == NULL) {
+ if (g == NULL || v == NULL || im_cache == NULL) {
_cairo_unlock_global_image_glyph_cache ();
return CAIRO_STATUS_NO_MEMORY;
}
- status = _cairo_cache_lookup (im_cache, key, (void **) (&im));
+ status = _cairo_cache_lookup (im_cache, key, (void **) (&im), NULL);
if (status != CAIRO_STATUS_SUCCESS || im == NULL) {
_cairo_unlock_global_image_glyph_cache ();
return CAIRO_STATUS_NO_MEMORY;
}
+ v->refcount = 1;
v->key = *k;
_cairo_unscaled_font_reference (v->key.unscaled);
@@ -925,6 +926,12 @@
return CAIRO_STATUS_SUCCESS;
}
+static void
+_glyphset_cache_entry_reference (glyphset_cache_entry_t *e)
+{
+ e->refcount++;
+}
+
static void
_xlib_glyphset_cache_destroy_cache (void *cache)
{
@@ -940,6 +947,9 @@
g = (glyphset_cache_t *) cache;
v = (glyphset_cache_entry_t *) entry;
+ if (--v->refcount > 0)
+ return;
+
_cairo_unscaled_font_destroy (v->key.unscaled);
XRenderFreeGlyphs (g->display, g->glyphset, &(v->glyph), 1);
free (v);
@@ -1014,8 +1024,7 @@
#define N_STACK_BUF 1024
static cairo_status_t
-_cairo_xlib_surface_show_glyphs32 (cairo_unscaled_font_t *font,
- cairo_font_scale_t *scale,
+_cairo_xlib_surface_show_glyphs32 (cairo_font_t *font,
cairo_operator_t operator,
glyphset_cache_t *g,
cairo_glyph_cache_key_t *key,
@@ -1092,8 +1101,7 @@
static cairo_status_t
-_cairo_xlib_surface_show_glyphs16 (cairo_unscaled_font_t *font,
- cairo_font_scale_t *scale,
+_cairo_xlib_surface_show_glyphs16 (cairo_font_t *font,
cairo_operator_t operator,
glyphset_cache_t *g,
cairo_glyph_cache_key_t *key,
@@ -1169,10 +1177,9 @@
}
static cairo_status_t
-_cairo_xlib_surface_show_glyphs8 (cairo_unscaled_font_t *font,
- cairo_font_scale_t *scale,
+_cairo_xlib_surface_show_glyphs8 (cairo_font_t *font,
cairo_operator_t operator,
- glyphset_cache_t *g,
+ glyphset_cache_t *g,
cairo_glyph_cache_key_t *key,
cairo_xlib_surface_t *src,
cairo_xlib_surface_t *self,
@@ -1247,8 +1254,7 @@
static cairo_status_t
-_cairo_xlib_surface_show_glyphs (cairo_unscaled_font_t *font,
- cairo_font_scale_t *scale,
+_cairo_xlib_surface_show_glyphs (cairo_font_t *font,
cairo_operator_t operator,
cairo_surface_t *source,
void *abstract_surface,
@@ -1305,15 +1311,23 @@
/* Work out the index size to use. */
elt_size = 8;
- key.scale = *scale;
- key.unscaled = font;
+ _cairo_font_get_glyph_cache_key (font, &key);
for (i = 0; i < num_glyphs; ++i) {
key.index = glyphs[i].index;
- status = _cairo_cache_lookup (&g->base, &key, (void **) (&entries[i]));
+ status = _cairo_cache_lookup (&g->base, &key, (void **) (&entries[i]), NULL);
if (status != CAIRO_STATUS_SUCCESS || entries[i] == NULL)
goto UNLOCK;
+ /* Referencing the glyph entries we use prevents them from
+ * being freed if lookup of later entries causes them to
+ * be ejected from the cache. It would be more efficient
+ * (though more complex) to prevent them from being ejected
+ * from the cache at all, so they could get reused later
+ * in the same string.
+ */
+ _glyphset_cache_entry_reference (entries[i]);
+
if (elt_size == 8 && entries[i]->glyph > 0xff)
elt_size = 16;
if (elt_size == 16 && entries[i]->glyph > 0xffff) {
@@ -1325,18 +1339,21 @@
/* Call the appropriate sub-function. */
if (elt_size == 8)
- status = _cairo_xlib_surface_show_glyphs8 (font, scale, operator, g, &key, src, self,
+ status = _cairo_xlib_surface_show_glyphs8 (font, operator, g, &key, src, self,
source_x, source_y,
glyphs, entries, num_glyphs);
else if (elt_size == 16)
- status = _cairo_xlib_surface_show_glyphs16 (font, scale, operator, g, &key, src, self,
+ status = _cairo_xlib_surface_show_glyphs16 (font, operator, g, &key, src, self,
source_x, source_y,
glyphs, entries, num_glyphs);
else
- status = _cairo_xlib_surface_show_glyphs32 (font, scale, operator, g, &key, src, self,
+ status = _cairo_xlib_surface_show_glyphs32 (font, operator, g, &key, src, self,
source_x, source_y,
glyphs, entries, num_glyphs);
+ for (i = 0; i < num_glyphs; ++i)
+ _xlib_glyphset_cache_destroy_entry (g, entries[i]);
+
_unlock_xlib_glyphset_caches ();
if (tmp != NULL) {
Index: cairoint.h
===================================================================
RCS file: /cvs/cairo/cairo/src/cairoint.h,v
retrieving revision 1.85
retrieving revision 1.86
diff -u -d -r1.85 -r1.86
--- cairoint.h 20 Jan 2005 16:28:54 -0000 1.85
+++ cairoint.h 21 Jan 2005 22:33:48 -0000 1.86
@@ -373,43 +373,49 @@
cairo_private cairo_status_t
_cairo_cache_lookup (cairo_cache_t *cache,
- void *key,
- void **entry_return);
+ void *key,
+ void **entry_return,
+ int *created_entry);
+
+cairo_private cairo_status_t
+_cairo_cache_remove (cairo_cache_t *cache,
+ void *key);
+
+cairo_private void *
+_cairo_cache_random_entry (cairo_cache_t *cache,
+ int (*predicate) (void*));
cairo_private unsigned long
_cairo_hash_string (const char *c);
#define CAIRO_IMAGE_GLYPH_CACHE_MEMORY_DEFAULT 0x100000
#define CAIRO_XLIB_GLYPH_CACHE_MEMORY_DEFAULT 0x100000
-#define CAIRO_FONT_CACHE_NUM_FONTS_DEFAULT 20
-#define CAIRO_FT_CACHE_NUM_FONTS_DEFAULT 20
typedef struct {
- double matrix[2][2];
+ double matrix[2][2];
} cairo_font_scale_t;
struct _cairo_font_backend;
+/*
+ * A cairo_unscaled_font_t is just an opaque handle we use in the
+ * glyph cache.
+ */
typedef struct {
int refcount;
const struct _cairo_font_backend *backend;
} cairo_unscaled_font_t;
-/*
- * A cairo_font contains a pointer to a cairo_unscaled_font_t and a scale
- * matrix. These are the things the user holds references to.
- */
-
struct _cairo_font {
int refcount;
- cairo_font_scale_t scale;
- cairo_unscaled_font_t *unscaled;
+ cairo_font_scale_t scale; /* font space => device space */
+ const struct _cairo_font_backend *backend;
};
-/* cairo_font.c is responsible for two global caches:
+/* cairo_font.c is responsible for a global glyph cache:
*
- * - font entries: [[[base], name, weight, slant], cairo_unscaled_font_t ]
- * - glyph entries: [[[base], cairo_font_t, index], image, size, extents ]
+ * - glyph entries: [[[base], cairo_unscaled_font_t, scale, flags, index],
+ * image, size, extents]
*
* Surfaces may build their own glyph caches if they have surface-specific
* glyph resources to maintain; those caches can feed off of the global
@@ -420,6 +426,7 @@
cairo_cache_entry_base_t base;
cairo_unscaled_font_t *unscaled;
cairo_font_scale_t scale;
+ int flags;
unsigned long index;
} cairo_glyph_cache_key_t;
@@ -452,36 +459,34 @@
/* the font backend interface */
typedef struct _cairo_font_backend {
- cairo_unscaled_font_t *(*create) (const char *family,
+ cairo_status_t (*create) (const char *family,
cairo_font_slant_t slant,
- cairo_font_weight_t weight);
+ cairo_font_weight_t weight,
+ cairo_font_scale_t *scale,
+ cairo_font_t **font);
- void (*destroy) (void *font);
+ void (*destroy_font) (void *font);
+ void (*destroy_unscaled_font) (void *font);
cairo_status_t (*font_extents) (void *font,
- cairo_font_scale_t *scale,
cairo_font_extents_t *extents);
cairo_status_t (*text_to_glyphs) (void *font,
- cairo_font_scale_t *scale,
const unsigned char *utf8,
cairo_glyph_t **glyphs,
int *num_glyphs);
cairo_status_t (*glyph_extents) (void *font,
- cairo_font_scale_t *scale,
cairo_glyph_t *glyphs,
int num_glyphs,
cairo_text_extents_t *extents);
cairo_status_t (*glyph_bbox) (void *font,
- cairo_font_scale_t *scale,
const cairo_glyph_t *glyphs,
int num_glyphs,
cairo_box_t *bbox);
cairo_status_t (*show_glyphs) (void *font,
- cairo_font_scale_t *scale,
cairo_operator_t operator,
cairo_surface_t *source,
cairo_surface_t *surface,
@@ -491,10 +496,11 @@
int num_glyphs);
cairo_status_t (*glyph_path) (void *font,
- cairo_font_scale_t *scale,
cairo_glyph_t *glyphs,
int num_glyphs,
cairo_path_t *path);
+ void (*get_glyph_cache_key) (void *font,
+ cairo_glyph_cache_key_t *key);
cairo_status_t (*create_glyph) (cairo_image_glyph_cache_entry_t *entry);
@@ -603,8 +609,7 @@
* surface, using image surfaces as glyphs.
*/
cairo_status_t
- (*show_glyphs) (cairo_unscaled_font_t *font,
- cairo_font_scale_t *scale,
+ (*show_glyphs) (cairo_font_t *font,
cairo_operator_t operator,
cairo_surface_t *source,
void *surface,
@@ -797,7 +802,11 @@
int num_dashes;
double dash_offset;
- cairo_unscaled_font_t *font;
+ char *font_family; /* NULL means CAIRO_FONT_FAMILY_DEFAULT; */
+ cairo_font_slant_t font_slant;
+ cairo_font_weight_t font_weight;
+
+ cairo_font_t *font; /* Specific to the current CTM */
cairo_surface_t *surface;
@@ -1119,6 +1128,10 @@
_cairo_gstate_scale_font (cairo_gstate_t *gstate,
double scale);
+cairo_private void
+_cairo_gstate_current_font_scale (cairo_gstate_t *gstate,
+ cairo_font_scale_t *sc);
+
cairo_private cairo_status_t
_cairo_gstate_transform_font (cairo_gstate_t *gstate,
cairo_matrix_t *matrix);
@@ -1184,19 +1197,21 @@
/* cairo_font.c */
-cairo_private cairo_unscaled_font_t *
-_cairo_unscaled_font_create (const char *family,
- cairo_font_slant_t slant,
- cairo_font_weight_t weight);
+cairo_private cairo_status_t
+_cairo_font_create (const char *family,
+ cairo_font_slant_t slant,
+ cairo_font_weight_t weight,
+ cairo_font_scale_t *sc,
+ cairo_font_t **font);
cairo_private void
-_cairo_font_init (cairo_font_t *scaled,
- cairo_font_scale_t *scale,
- cairo_unscaled_font_t *unscaled);
+_cairo_font_init (cairo_font_t *font,
+ cairo_font_scale_t *scale,
+ const cairo_font_backend_t *backend);
-cairo_private cairo_status_t
-_cairo_unscaled_font_init (cairo_unscaled_font_t *font,
- const struct _cairo_font_backend *backend);
+cairo_private void
+_cairo_unscaled_font_init (cairo_unscaled_font_t *font,
+ const struct _cairo_font_backend *backend);
cairo_private void
_cairo_unscaled_font_reference (cairo_unscaled_font_t *font);
@@ -1205,48 +1220,52 @@
_cairo_unscaled_font_destroy (cairo_unscaled_font_t *font);
cairo_private cairo_status_t
-_cairo_unscaled_font_font_extents (cairo_unscaled_font_t *font,
- cairo_font_scale_t *scale,
- cairo_font_extents_t *extents);
+_cairo_font_font_extents (cairo_font_t *font,
+ cairo_font_extents_t *extents);
cairo_private cairo_status_t
-_cairo_unscaled_font_text_to_glyphs (cairo_unscaled_font_t *font,
- cairo_font_scale_t *scale,
- const unsigned char *utf8,
- cairo_glyph_t **glyphs,
- int *num_glyphs);
+_cairo_font_text_to_glyphs (cairo_font_t *font,
+ const unsigned char *utf8,
+ cairo_glyph_t **glyphs,
+ int *num_glyphs);
cairo_private cairo_status_t
-_cairo_unscaled_font_glyph_extents (cairo_unscaled_font_t *font,
- cairo_font_scale_t *scale,
- cairo_glyph_t *glyphs,
- int num_glyphs,
- cairo_text_extents_t *extents);
+_cairo_font_glyph_extents (cairo_font_t *font,
+ cairo_glyph_t *glyphs,
+ int num_glyphs,
+ cairo_text_extents_t *extents);
cairo_private cairo_status_t
-_cairo_unscaled_font_glyph_bbox (cairo_unscaled_font_t *font,
- cairo_font_scale_t *size,
- cairo_glyph_t *glyphs,
- int num_glyphs,
- cairo_box_t *bbox);
+_cairo_font_glyph_bbox (cairo_font_t *font,
+ cairo_glyph_t *glyphs,
+ int num_glyphs,
+ cairo_box_t *bbox);
cairo_private cairo_status_t
-_cairo_unscaled_font_show_glyphs (cairo_unscaled_font_t *font,
- cairo_font_scale_t *size,
- cairo_operator_t operator,
- cairo_surface_t *source,
- cairo_surface_t *surface,
- int source_x,
- int source_y,
- cairo_glyph_t *glyphs,
- int num_glyphs);
+_cairo_font_show_glyphs (cairo_font_t *font,
+ cairo_operator_t operator,
+ cairo_surface_t *source,
+ cairo_surface_t *surface,
+ int source_x,
+ int source_y,
+ cairo_glyph_t *glyphs,
+ int num_glyphs);
cairo_private cairo_status_t
-_cairo_unscaled_font_glyph_path (cairo_unscaled_font_t *font,
- cairo_font_scale_t *size,
- cairo_glyph_t *glyphs,
- int num_glyphs,
- cairo_path_t *path);
+_cairo_font_glyph_path (cairo_font_t *font,
+ cairo_glyph_t *glyphs,
+ int num_glyphs,
+ cairo_path_t *path);
+
+cairo_private cairo_status_t
+_cairo_font_glyph_path (cairo_font_t *font,
+ cairo_glyph_t *glyphs,
+ int num_glyphs,
+ cairo_path_t *path);
+
+cairo_private void
+_cairo_font_get_glyph_cache_key (cairo_font_t *font,
+ cairo_glyph_cache_key_t *key);
/* cairo_hull.c */
cairo_private cairo_status_t
- Previous message: [cairo-commit] cairo/doc/reference/xml cairo_current_font.xml, 1.2,
1.3 cairo_font_glyph_extents.xml, NONE, 1.1 cairo_font_t.xml,
NONE, 1.1 cairo_ft_font_create.xml, NONE,
1.1 cairo_ft_font_create_for_ft_face.xml, NONE,
1.1 cairo_ft_font_get_pattern.xml, NONE,
1.1 cairo_ft_font_lock_face.xml, NONE,
1.1 cairo_ft_font_unlock_face.xml, NONE, 1.1 cairo_glyph_t.xml,
NONE, 1.1 cairo_matrix_t.xml, 1.1, 1.2 cairo_set_font.xml, 1.2,
1.3 cairo_show_glyphs.xml, 1.2, 1.3 cairo_text_extents_t.xml,
1.1, 1.2
- Next message: [cairo-commit] cairo ChangeLog,1.319,1.320
- Messages sorted by:
[ date ]
[ thread ]
[ subject ]
[ author ]
More information about the cairo-commit
mailing list