Fixes for bug #4110:

Don't call _cairo_ft_unscaled_font_init_key in the from_face case, just clear filename and id instead. Initialize unscaled->base first so that initialization order matches the structure declaration order.
Fix to accept a NULL string and hash it identically to a zero-length string.
Add a test that calls cairo_ft_font_create_for_ft_face to demonstrate bug #4110.
This commit is contained in:
Carl Worth 2005-08-17 09:51:09 +00:00
parent f5f21a768d
commit 639680e5fe
6 changed files with 140 additions and 16 deletions

View file

@ -1,3 +1,19 @@
2005-08-17 Carl Worth <cworth@cworth.org>
Fixes for bug #4110:
* src/cairo-ft-font.c (_cairo_ft_unscaled_font_init): Don't call
_cairo_ft_unscaled_font_init_key in the from_face case, just clear
filename and id instead. Initialize unscaled->base first so that
initialization order matches the structure declaration order.
* src/cairo-cache.c (_cairo_hash_string): Fix to accept a NULL
string and hash it identically to a zero-length string.
* test/Makefile.am:
* test/ft-font-create-for-ft-face: Add a test that calls
cairo_ft_font_create_for_ft_face to demonstrate bug #4110.
2005-08-16 Billy Biggs <vektor@dumbterm.net>
* test/filter-nearest-offset.c: (draw): Fix the filter-nearest-offset
@ -51,7 +67,7 @@
* configure.in: Add a check for the MMX intrinsics used by pixman.
gcc >= 3.4 is required.
2005-08-16 Carl Worth <cworth@cworth.org>
* src/cairoint.h (CAIRO_PRINTF_FORMAT): Rename cairo_printf_format

View file

@ -512,7 +512,7 @@ _cairo_hash_string (const char *c)
{
/* This is the djb2 hash. */
unsigned long hash = 5381;
while (*c)
while (c && *c)
hash = ((hash << 5) + hash) + *c++;
return hash;
}

View file

@ -290,22 +290,25 @@ _cairo_ft_unscaled_font_init (cairo_ft_unscaled_font_t *unscaled,
int id,
FT_Face face)
{
char *filename_copy = NULL;
_cairo_unscaled_font_init (&unscaled->base,
&cairo_ft_unscaled_font_backend);
if (face) {
unscaled->from_face = TRUE;
unscaled->face = face;
unscaled->filename = NULL;
unscaled->id = 0;
} else {
char *filename_copy;
unscaled->from_face = FALSE;
unscaled->face = NULL;
if (filename) {
filename_copy = strdup (filename);
if (filename_copy == NULL)
return CAIRO_STATUS_NO_MEMORY;
}
_cairo_ft_unscaled_font_init_key (unscaled, filename_copy, id);
if (face) {
unscaled->from_face = 1;
unscaled->face = face;
} else {
unscaled->from_face = 0;
unscaled->face = NULL;
_cairo_ft_unscaled_font_init_key (unscaled, filename_copy, id);
}
unscaled->have_scale = 0;
@ -313,9 +316,6 @@ _cairo_ft_unscaled_font_init (cairo_ft_unscaled_font_t *unscaled,
unscaled->faces = NULL;
_cairo_unscaled_font_init (&unscaled->base,
&cairo_ft_unscaled_font_backend);
return CAIRO_STATUS_SUCCESS;
}

View file

@ -15,6 +15,7 @@ create-from-png-stream
fill-and-stroke
fill-rule
filter-nearest-offset
ft-font-create-for-ft-face
get-and-set
gradient-alpha
imagediff

View file

@ -47,6 +47,10 @@ unbounded-operator \
user-data \
rel-path
if CAIRO_HAS_FT_FONT
TESTS += ft-font-create-for-ft-face
endif
if CAIRO_HAS_PDF_SURFACE
TESTS += pdf-surface pdf-clip
endif
@ -174,6 +178,7 @@ create_from_png_stream_LDADD = $(LDADDS)
fill_and_stroke_LDADD = $(LDADDS)
fill_rule_LDADD = $(LDADDS)
filter_nearest_offset_LDADD = $(LDADDS)
ft_font_create_for_ft_face_LDADD = $(LDADDS)
get_and_set_LDADD = $(LDADDS)
gradient_alpha_LDADD = $(LDADDS)
leaky_polygon_LDADD = $(LDADDS)

View file

@ -0,0 +1,102 @@
/*
* Copyright © 2005 Red Hat, Inc.
*
* 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 representations about the
* suitability of this software for any purpose. It is provided "as
* is" without express or implied warranty.
*
* RED HAT, INC. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
* SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
* FITNESS, IN NO EVENT SHALL RED HAT, INC. BE LIABLE FOR ANY SPECIAL,
* INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
* RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
* OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
* IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*
* Author: Carl D. Worth <cworth@cworth.org>
*/
#include "cairo-test.h"
#include <cairo-ft.h>
cairo_test_t test = {
"ft-font-create-for-ft-face",
"Simple test to verify that cairo_ft_font_create_for_ft_face doesn't crash.",
0, 0
};
static cairo_test_status_t
draw (cairo_t *cr, int width, int height)
{
FcPattern *pattern;
cairo_font_face_t *font_face;
cairo_scaled_font_t *scaled_font;
cairo_font_options_t *font_options;
cairo_font_extents_t font_extents;
cairo_matrix_t font_matrix, ctm;
FT_Face ft_face;
/* We're trying here to get our hands on _some_ FT_Face but we do
* not at all care which one, so an empty pattern should work just
* fine. */
pattern = FcPatternCreate ();
if (!pattern)
return CAIRO_TEST_FAILURE;
font_face = cairo_ft_font_face_create_for_pattern (pattern);
cairo_matrix_init_identity (&font_matrix);
cairo_get_matrix (cr, &ctm);
font_options = cairo_font_options_create ();
scaled_font = cairo_scaled_font_create (font_face,
&font_matrix,
&ctm,
font_options);
ft_face = cairo_ft_scaled_font_lock_face (scaled_font);
cairo_font_options_destroy (font_options);
cairo_font_face_destroy (font_face);
FcPatternDestroy (pattern);
if (!ft_face) {
cairo_scaled_font_destroy (scaled_font);
return CAIRO_TEST_FAILURE;
}
/* phew, that was a lot of work. But at least we didn't ever have
* to call freetype directly, nor did we have to make many (any?)
* assumptions about the current system.
*
* Now, on to the simple thing we actually want to test.
*/
font_face = cairo_ft_font_face_create_for_ft_face (ft_face, 0);
/* Set the font_face and force cairo to actually use it for
* something. */
cairo_set_font_face (cr, font_face);
cairo_font_extents (cr, &font_extents);
/* Finally, even more cleanup */
cairo_font_face_destroy (font_face);
cairo_ft_scaled_font_unlock_face (scaled_font);
cairo_scaled_font_destroy (scaled_font);
return CAIRO_TEST_SUCCESS;
}
int
main (void)
{
return cairo_test (&test, draw);
}