[cairo-commit] Branch '1.8' - 4 commits - AUTHORS src/cairo-ft-font.c test/cairo-test.c test/get-path-extents.c
Chris Wilson
ickle at kemper.freedesktop.org
Tue Jun 2 23:24:17 PDT 2009
AUTHORS | 2 +-
src/cairo-ft-font.c | 42 ++++++++++++++++++++++++++++++++----------
test/cairo-test.c | 42 +++++++++++++++++++++---------------------
test/get-path-extents.c | 8 ++++----
4 files changed, 58 insertions(+), 36 deletions(-)
New commits:
commit c8f4b2fe80583de939613cc4d118a0b5920cb7ae
Author: Karl Tomlinson <karlt+ at karlt.net>
Date: Thu May 14 11:46:29 2009 +0100
[ft] Resolve mutual referencing problems with zombie faces
Bug 21706 -- zombie ft_font_face / ft_unscaled_font mutual
referencing problems
[http://bugs.freedesktop.org/show_bug.cgi?id=21706]
There can be more than one zombie font_face belonging to an unscaled_font,
but only the first is destroyed. This leaks the client's FT_Face
(and associated font data) as release of the FT_Face depends on release
of the font_face.
(The reason why Firefox ends up with two different font_faces for one
unscaled_font is that load_flags for faces with artificial oblique have
FT_LOAD_NO_BITMAP set.
https://bugzilla.mozilla.org/show_bug.cgi?id=486974)
Also it's possible for _cairo_ft_font_face_create to pull out a zombie
font_face from the unscaled_font, which would crash
_cairo_ft_font_face_scaled_font_create, as that expects non-null
font_face->unscaled (if !font-face->pattern).
diff --git a/AUTHORS b/AUTHORS
index 289fecb..8c06174 100644
--- a/AUTHORS
+++ b/AUTHORS
@@ -86,7 +86,7 @@ Travis Spencer <tspencer at cs.pdx.edu> XCB backend fix
Bill Spitzak <spitzak at d2.com> Build fix to find Xrender.h without xrender.pc
Zhe Su <james.su at gmail.com> Add support for fontconfig's embeddedbitmap option
Owen Taylor <otaylor at redhat.com> Font rewrite, documentation, win32 backend
-Karl Tomlinson <karlt+ at karlt.net>
+Karl Tomlinson <karlt+ at karlt.net> Optimisation and obscure bug fixes (mozilla)
Alp Toker <alp at atoker.com> Fix several code/comment typos
Malcolm Tredinnick <malcolm at commsecure.com.au> Documentation fixes
David Turner <david at freetype.org> Optimize gradient calculations
diff --git a/src/cairo-ft-font.c b/src/cairo-ft-font.c
index 22206bb..19bfe46 100644
--- a/src/cairo-ft-font.c
+++ b/src/cairo-ft-font.c
@@ -511,8 +511,10 @@ _cairo_ft_unscaled_font_destroy (void *abstract_font)
/* See comments in _ft_font_face_destroy about the "zombie" state
* for a _ft_font_face.
*/
- if (unscaled->faces && !unscaled->faces->unscaled)
+ if (unscaled->faces && unscaled->faces->unscaled == NULL) {
+ assert (unscaled->faces->next == NULL);
cairo_font_face_destroy (&unscaled->faces->base);
+ }
} else {
_font_map_release_face_lock_held (font_map, unscaled);
}
@@ -2235,9 +2237,10 @@ _cairo_ft_font_face_destroy (void *abstract_face)
if (font_face == NULL)
return;
- /* When destroying the face created by cairo_ft_font_face_create_for_ft_face,
+ /* When destroying a face created by cairo_ft_font_face_create_for_ft_face,
* we have a special "zombie" state for the face when the unscaled font
- * is still alive but there are no public references to the font face.
+ * is still alive but there are no other references to a font face with
+ * the same FT_Face.
*
* We go from:
*
@@ -2251,6 +2254,8 @@ _cairo_ft_font_face_destroy (void *abstract_face)
if (font_face->unscaled &&
font_face->unscaled->from_face &&
+ font_face->next == NULL &&
+ font_face->unscaled->faces == font_face &&
CAIRO_REFERENCE_COUNT_GET_VALUE (&font_face->unscaled->base.ref_count) > 1)
{
cairo_font_face_reference (&font_face->base);
@@ -2337,12 +2342,21 @@ _cairo_ft_font_face_create (cairo_ft_unscaled_font_t *unscaled,
font_face->ft_options.extra_flags == ft_options->extra_flags &&
cairo_font_options_equal (&font_face->ft_options.base, &ft_options->base))
{
- if (font_face->base.status == CAIRO_STATUS_SUCCESS)
- return cairo_font_face_reference (&font_face->base);
+ if (font_face->base.status) {
+ /* The font_face has been left in an error state, abandon it. */
+ *prev_font_face = font_face->next;
+ break;
+ }
- /* The font_face has been left in an error state, abandon it. */
- *prev_font_face = font_face->next;
- break;
+ if (font_face->unscaled == NULL) {
+ /* Resurrect this "zombie" font_face (from
+ * _cairo_ft_font_face_destroy), switching its unscaled_font
+ * from owner to ownee. */
+ font_face->unscaled = unscaled;
+ _cairo_unscaled_font_reference (&unscaled->base);
+ return &font_face->base;
+ } else
+ return cairo_font_face_reference (&font_face->base);
}
}
@@ -2358,6 +2372,14 @@ _cairo_ft_font_face_create (cairo_ft_unscaled_font_t *unscaled,
font_face->ft_options = *ft_options;
+ if (unscaled->faces && unscaled->faces->unscaled == NULL) {
+ /* This "zombie" font_face (from _cairo_ft_font_face_destroy)
+ * is no longer needed. */
+ assert (unscaled->from_face && unscaled->faces->next == NULL);
+ cairo_font_face_destroy (&unscaled->faces->base);
+ unscaled->faces = NULL;
+ }
+
font_face->next = unscaled->faces;
unscaled->faces = font_face;
commit 634298af1326a39452c9432a2d9a8fd98c9c2d19
Author: Behdad Esfahbod <behdad at behdad.org>
Date: Sat May 30 23:03:55 2009 -0400
[ft] Fix vertical advance metrics of bitmap fonts (#21985)
diff --git a/src/cairo-ft-font.c b/src/cairo-ft-font.c
index 3675db6..22206bb 100644
--- a/src/cairo-ft-font.c
+++ b/src/cairo-ft-font.c
@@ -1993,7 +1993,7 @@ _cairo_ft_scaled_glyph_init (void *abstract_font,
FT_Pos x1, x2;
FT_Pos y1, y2;
FT_Pos advance;
-
+
if (!vertical_layout) {
x1 = (metrics->horiBearingX) & -64;
x2 = (metrics->horiBearingX + metrics->width + 63) & -64;
@@ -2048,7 +2048,7 @@ _cairo_ft_scaled_glyph_init (void *abstract_font,
if (hint_metrics || glyph->format != FT_GLYPH_FORMAT_OUTLINE)
fs_metrics.y_advance = DOUBLE_FROM_26_6 (metrics->vertAdvance) * y_factor;
else
- fs_metrics.y_advance = DOUBLE_FROM_26_6 (glyph->linearVertAdvance) * y_factor;
+ fs_metrics.y_advance = DOUBLE_FROM_16_16 (glyph->linearVertAdvance) * y_factor;
}
}
commit 5c63efe5fd182212c3f382bbdc0179c9e99e636d
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date: Fri May 8 17:36:01 2009 +0100
[test] Relax APPROX_EQUALS condition
The bounding box of the text is rounded to the nearest pixel boundaries,
so therefore the test must accept a similar level of imprecision.
diff --git a/test/get-path-extents.c b/test/get-path-extents.c
index 5bfdcd7..7a959c8 100644
--- a/test/get-path-extents.c
+++ b/test/get-path-extents.c
@@ -79,10 +79,10 @@ check_extents (const cairo_test_context_t *ctx,
break;
case APPROX_EQUALS:
relation_string = "approx. equal";
- if (floor (ext_x1 + 0.5) == floor (x + 0.5) &&
- floor (ext_y1 + 0.5) == floor (y + 0.5) &&
- floor (ext_x2 + 0.5) == floor (x + width + 0.5) &&
- floor (ext_y2 + 0.5) == floor (y + height + 0.5))
+ if (fabs (ext_x1 - x) < 1. &&
+ fabs (ext_y1 - y) < 1. &&
+ fabs (ext_x2 - (x + width)) < 1. &&
+ fabs (ext_y2 - (y + height)) < 1.)
{
return 1;
}
commit 130ac1f9453b5e746576fc4887d7e1372c1605b1
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date: Wed Jun 3 07:06:42 2009 +0100
[test] Sync with memfault headers.
Update the macros to reflect the current version of memfault.
diff --git a/test/cairo-test.c b/test/cairo-test.c
index 12fc3ad..61ea63d 100644
--- a/test/cairo-test.c
+++ b/test/cairo-test.c
@@ -128,7 +128,7 @@ _cairo_test_init (cairo_test_context_t *ctx,
{
char *log_name;
- MF (VALGRIND_DISABLE_FAULTS ());
+ MF (MEMFAULT_DISABLE_FAULTS ());
#if HAVE_FEENABLEEXCEPT
feenableexcept (FE_DIVBYZERO | FE_INVALID | FE_OVERFLOW);
@@ -191,7 +191,7 @@ cairo_test_init_thread (cairo_test_context_t *ctx,
cairo_test_context_t *master,
int thread)
{
- MF (VALGRIND_DISABLE_FAULTS ());
+ MF (MEMFAULT_DISABLE_FAULTS ());
*ctx = *master;
ctx->thread = thread;
@@ -631,11 +631,11 @@ cairo_test_for_target (cairo_test_context_t *ctx,
REPEAT:
#if HAVE_MEMFAULT
- VALGRIND_CLEAR_FAULTS ();
- VALGRIND_RESET_LEAKS ();
+ MEMFAULT_CLEAR_FAULTS ();
+ MEMFAULT_RESET_LEAKS ();
ctx->last_fault_count = 0;
- last_fault_count = VALGRIND_COUNT_FAULTS ();
- VALGRIND_ENABLE_FAULTS ();
+ last_fault_count = MEMFAULT_COUNT_FAULTS ();
+ MEMFAULT_ENABLE_FAULTS ();
#endif
have_output = FALSE;
have_result = FALSE;
@@ -660,7 +660,7 @@ REPEAT:
goto REPEAT;
if (cairo_surface_status (surface)) {
- MF (VALGRIND_PRINT_FAULTS ());
+ MF (MEMFAULT_PRINT_FAULTS ());
cairo_test_log (ctx, "Error: Created an error surface\n");
ret = CAIRO_TEST_FAILURE;
goto UNWIND_STRINGS;
@@ -668,7 +668,7 @@ REPEAT:
/* Check that we created a surface of the expected type. */
if (cairo_surface_get_type (surface) != target->expected_type) {
- MF (VALGRIND_PRINT_FAULTS ());
+ MF (MEMFAULT_PRINT_FAULTS ());
cairo_test_log (ctx, "Error: Created surface is of type %d (expected %d)\n",
cairo_surface_get_type (surface), target->expected_type);
ret = CAIRO_TEST_FAILURE;
@@ -681,7 +681,7 @@ REPEAT:
expected_content = cairo_boilerplate_content (target->content);
if (cairo_surface_get_content (surface) != expected_content) {
- MF (VALGRIND_PRINT_FAULTS ());
+ MF (MEMFAULT_PRINT_FAULTS ());
cairo_test_log (ctx, "Error: Created surface has content %d (expected %d)\n",
cairo_surface_get_content (surface), expected_content);
ret = CAIRO_TEST_FAILURE;
@@ -736,11 +736,11 @@ REPEAT:
}
#if HAVE_MEMFAULT
- VALGRIND_DISABLE_FAULTS ();
+ MEMFAULT_DISABLE_FAULTS ();
/* repeat test after malloc failure injection */
if (ctx->malloc_failure &&
- VALGRIND_COUNT_FAULTS () - last_fault_count > 0 &&
+ MEMFAULT_COUNT_FAULTS () - last_fault_count > 0 &&
(status == CAIRO_TEST_NO_MEMORY ||
cairo_status (cr) == CAIRO_STATUS_NO_MEMORY ||
cairo_surface_status (surface) == CAIRO_STATUS_NO_MEMORY))
@@ -754,9 +754,9 @@ REPEAT:
#if HAVE_FCFINI
FcFini ();
#endif
- if (VALGRIND_COUNT_LEAKS () > 0) {
- VALGRIND_PRINT_FAULTS ();
- VALGRIND_PRINT_LEAKS ();
+ if (MEMFAULT_COUNT_LEAKS () > 0) {
+ MEMFAULT_PRINT_FAULTS ();
+ MEMFAULT_PRINT_LEAKS ();
}
}
@@ -779,9 +779,9 @@ REPEAT:
}
#if HAVE_MEMFAULT
- if (VALGRIND_COUNT_FAULTS () - last_fault_count > 0) {
+ if (MEMFAULT_COUNT_FAULTS () - last_fault_count > 0) {
VALGRIND_PRINTF ("Unreported memfaults...");
- VALGRIND_PRINT_FAULTS ();
+ MEMFAULT_PRINT_FAULTS ();
}
#endif
@@ -983,7 +983,7 @@ UNWIND_CAIRO:
#if HAVE_MEMFAULT
if (ret == CAIRO_TEST_FAILURE && ctx->expectation != CAIRO_TEST_FAILURE)
- VALGRIND_PRINT_FAULTS ();
+ MEMFAULT_PRINT_FAULTS ();
#endif
cairo_destroy (cr);
UNWIND_SURFACE:
@@ -1000,13 +1000,13 @@ UNWIND_SURFACE:
FcFini ();
#endif
- if (VALGRIND_COUNT_LEAKS () > 0) {
+ if (MEMFAULT_COUNT_LEAKS () > 0) {
if (ret != CAIRO_TEST_FAILURE ||
ctx->expectation == CAIRO_TEST_FAILURE)
{
- VALGRIND_PRINT_FAULTS ();
+ MEMFAULT_PRINT_FAULTS ();
}
- VALGRIND_PRINT_LEAKS ();
+ MEMFAULT_PRINT_LEAKS ();
}
}
@@ -1481,7 +1481,7 @@ cairo_test_malloc_failure (const cairo_test_context_t *ctx,
#if HAVE_MEMFAULT
/* prevent infinite loops... */
- n_faults = VALGRIND_COUNT_FAULTS ();
+ n_faults = MEMFAULT_COUNT_FAULTS ();
if (n_faults == ctx->last_fault_count)
return FALSE;
More information about the cairo-commit
mailing list