Bumping manifests a=b2g-bump
[gecko.git] / gfx / cairo / zombie-face.patch
bloba4175fecc42c3ff3e715623b437e84143971466d
1 From 0238fe2cafea2e1ed19bb222117bd73ee6898d4d Mon Sep 17 00:00:00 2001
2 From: Karl Tomlinson <karlt+@karlt.net>
3 Date: Thu, 14 May 2009 10:46:29 +0000
4 Subject: [ft] Resolve mutual referencing problems with zombie faces
6 Bug 21706 -- zombie ft_font_face / ft_unscaled_font mutual
7 referencing problems
8 [http://bugs.freedesktop.org/show_bug.cgi?id=21706]
10 There can be more than one zombie font_face belonging to an unscaled_font,
11 but only the first is destroyed. This leaks the client's FT_Face
12 (and associated font data) as release of the FT_Face depends on release
13 of the font_face.
15 (The reason why Firefox ends up with two different font_faces for one
16 unscaled_font is that load_flags for faces with artificial oblique have
17 FT_LOAD_NO_BITMAP set.
18 https://bugzilla.mozilla.org/show_bug.cgi?id=486974)
20 Also it's possible for _cairo_ft_font_face_create to pull out a zombie
21 font_face from the unscaled_font, which would crash
22 _cairo_ft_font_face_scaled_font_create, as that expects non-null
23 font_face->unscaled (if !font-face->pattern).
24 ---
25 diff --git a/AUTHORS b/AUTHORS
26 index 289fecb..8c06174 100644
27 --- a/AUTHORS
28 +++ b/AUTHORS
29 @@ -86,7 +86,7 @@ Travis Spencer <tspencer@cs.pdx.edu> XCB backend fix
30 Bill Spitzak <spitzak@d2.com> Build fix to find Xrender.h without xrender.pc
31 Zhe Su <james.su@gmail.com> Add support for fontconfig's embeddedbitmap option
32 Owen Taylor <otaylor@redhat.com> Font rewrite, documentation, win32 backend
33 -Karl Tomlinson <karlt+@karlt.net>
34 +Karl Tomlinson <karlt+@karlt.net> Optimisation and obscure bug fixes (mozilla)
35 Alp Toker <alp@atoker.com> Fix several code/comment typos
36 Malcolm Tredinnick <malcolm@commsecure.com.au> Documentation fixes
37 David Turner <david@freetype.org> Optimize gradient calculations
38 diff --git a/src/cairo-ft-font.c b/src/cairo-ft-font.c
39 index 1e2a18e..f9ff0b1 100644
40 --- a/src/cairo-ft-font.c
41 +++ b/src/cairo-ft-font.c
42 @@ -543,8 +543,10 @@ _cairo_ft_unscaled_font_destroy (void *abstract_font)
43 /* See comments in _ft_font_face_destroy about the "zombie" state
44 * for a _ft_font_face.
46 - if (unscaled->faces && !unscaled->faces->unscaled)
47 + if (unscaled->faces && unscaled->faces->unscaled == NULL) {
48 + assert (unscaled->faces->next == NULL);
49 cairo_font_face_destroy (&unscaled->faces->base);
50 + }
51 } else {
52 _font_map_release_face_lock_held (font_map, unscaled);
54 @@ -2233,9 +2235,10 @@ _cairo_ft_font_face_destroy (void *abstract_face)
55 if (font_face == NULL)
56 return;
58 - /* When destroying the face created by cairo_ft_font_face_create_for_ft_face,
59 + /* When destroying a face created by cairo_ft_font_face_create_for_ft_face,
60 * we have a special "zombie" state for the face when the unscaled font
61 - * is still alive but there are no public references to the font face.
62 + * is still alive but there are no other references to a font face with
63 + * the same FT_Face.
65 * We go from:
67 @@ -2249,6 +2252,8 @@ _cairo_ft_font_face_destroy (void *abstract_face)
69 if (font_face->unscaled &&
70 font_face->unscaled->from_face &&
71 + font_face->next == NULL &&
72 + font_face->unscaled->faces == font_face &&
73 CAIRO_REFERENCE_COUNT_GET_VALUE (&font_face->unscaled->base.ref_count) > 1)
75 cairo_font_face_reference (&font_face->base);
76 @@ -2394,12 +2399,21 @@ _cairo_ft_font_face_create (cairo_ft_unscaled_font_t *unscaled,
77 font_face->ft_options.extra_flags == ft_options->extra_flags &&
78 cairo_font_options_equal (&font_face->ft_options.base, &ft_options->base))
80 - if (font_face->base.status == CAIRO_STATUS_SUCCESS)
81 - return cairo_font_face_reference (&font_face->base);
82 + if (font_face->base.status) {
83 + /* The font_face has been left in an error state, abandon it. */
84 + *prev_font_face = font_face->next;
85 + break;
86 + }
88 - /* The font_face has been left in an error state, abandon it. */
89 - *prev_font_face = font_face->next;
90 - break;
91 + if (font_face->unscaled == NULL) {
92 + /* Resurrect this "zombie" font_face (from
93 + * _cairo_ft_font_face_destroy), switching its unscaled_font
94 + * from owner to ownee. */
95 + font_face->unscaled = unscaled;
96 + _cairo_unscaled_font_reference (&unscaled->base);
97 + return &font_face->base;
98 + } else
99 + return cairo_font_face_reference (&font_face->base);
103 @@ -2415,6 +2429,14 @@ _cairo_ft_font_face_create (cairo_ft_unscaled_font_t *unscaled,
105 font_face->ft_options = *ft_options;
107 + if (unscaled->faces && unscaled->faces->unscaled == NULL) {
108 + /* This "zombie" font_face (from _cairo_ft_font_face_destroy)
109 + * is no longer needed. */
110 + assert (unscaled->from_face && unscaled->faces->next == NULL);
111 + cairo_font_face_destroy (&unscaled->faces->base);
112 + unscaled->faces = NULL;
115 font_face->next = unscaled->faces;
116 unscaled->faces = font_face;
119 cgit v0.8.2