[cairo-commit] 2 commits - src/cairo.c src/cairo-font-face.c src/cairo-font-options.c src/cairo-ft-font.c src/cairo-gstate.c src/cairo-scaled-font.c src/cairo-win32-font.c test/font-options.c test/.gitignore test/Makefile.am
Chris Wilson
ickle at kemper.freedesktop.org
Thu Jan 17 14:39:27 PST 2008
src/cairo-font-face.c | 8 ++--
src/cairo-font-options.c | 65 +++++++++++++++++++++++++--------
src/cairo-ft-font.c | 16 +++++---
src/cairo-gstate.c | 2 -
src/cairo-scaled-font.c | 18 ++++++---
src/cairo-win32-font.c | 4 +-
src/cairo.c | 10 +++--
test/.gitignore | 1
test/Makefile.am | 12 +++---
test/font-options.c | 91 +++++++++++++++++++++++++++++++++++++++++++++++
10 files changed, 184 insertions(+), 43 deletions(-)
New commits:
commit 0086db893cba90dc73824d77c661d2965ad48112
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date: Thu Jan 17 22:31:05 2008 +0000
[cairo-font-options] Treat NULL as a default cairo_font_options_t
Interpret a NULL cairo_font_options_t as the default values - i.e
as if it were a fresh pointer returned by cairo_font_options_create().
diff --git a/src/cairo-font-face.c b/src/cairo-font-face.c
index f729476..b944534 100644
--- a/src/cairo-font-face.c
+++ b/src/cairo-font-face.c
@@ -476,9 +476,11 @@ _cairo_toy_font_face_scaled_font_create (void *abstract_font_face
if (font_face->base.status)
return font_face->base.status;
- status = cairo_font_options_status ((cairo_font_options_t *) options);
- if (status)
- return status;
+ if (options != NULL) {
+ status = cairo_font_options_status ((cairo_font_options_t *) options);
+ if (status)
+ return status;
+ }
return _cairo_font_face_set_error (&font_face->base,
backend->create_toy (font_face,
diff --git a/src/cairo-font-options.c b/src/cairo-font-options.c
index a2cce35..7005790 100644
--- a/src/cairo-font-options.c
+++ b/src/cairo-font-options.c
@@ -65,10 +65,13 @@ void
_cairo_font_options_init_copy (cairo_font_options_t *options,
const cairo_font_options_t *other)
{
- options->antialias = other->antialias;
- options->subpixel_order = other->subpixel_order;
- options->hint_style = other->hint_style;
- options->hint_metrics = other->hint_metrics;
+ if (other != NULL) {
+ options->antialias = other->antialias;
+ options->subpixel_order = other->subpixel_order;
+ options->hint_style = other->hint_style;
+ options->hint_metrics = other->hint_metrics;
+ } else
+ _cairo_font_options_init_default (options);
}
/**
@@ -91,7 +94,7 @@ cairo_font_options_create (void)
options = malloc (sizeof (cairo_font_options_t));
if (!options) {
_cairo_error_throw (CAIRO_STATUS_NO_MEMORY);
- return (cairo_font_options_t *)&_cairo_font_options_nil;
+ return (cairo_font_options_t *) &_cairo_font_options_nil;
}
_cairo_font_options_init_default (options);
@@ -118,13 +121,16 @@ cairo_font_options_copy (const cairo_font_options_t *original)
{
cairo_font_options_t *options;
- if (cairo_font_options_status ((cairo_font_options_t *) original))
- return (cairo_font_options_t *)&_cairo_font_options_nil;
+ if (original != NULL &&
+ cairo_font_options_status ((cairo_font_options_t *) original))
+ {
+ return (cairo_font_options_t *) &_cairo_font_options_nil;
+ }
options = malloc (sizeof (cairo_font_options_t));
if (!options) {
_cairo_error_throw (CAIRO_STATUS_NO_MEMORY);
- return (cairo_font_options_t *)&_cairo_font_options_nil;
+ return (cairo_font_options_t *) &_cairo_font_options_nil;
}
_cairo_font_options_init_copy (options, original);
@@ -163,7 +169,7 @@ cairo_font_options_status (cairo_font_options_t *options)
{
if (options == NULL)
return CAIRO_STATUS_NULL_POINTER;
- else if (options == (cairo_font_options_t *)&_cairo_font_options_nil)
+ else if (options == (cairo_font_options_t *) &_cairo_font_options_nil)
return CAIRO_STATUS_NO_MEMORY;
else
return CAIRO_STATUS_SUCCESS;
@@ -187,6 +193,10 @@ cairo_font_options_merge (cairo_font_options_t *options,
if (cairo_font_options_status (options))
return;
+ /* A NULL other maps to the defaults and would not overwrite options */
+ if (cairo_font_options_status ((cairo_font_options_t *) other))
+ return;
+
if (other->antialias != CAIRO_ANTIALIAS_DEFAULT)
options->antialias = other->antialias;
if (other->subpixel_order != CAIRO_SUBPIXEL_ORDER_DEFAULT)
@@ -211,6 +221,14 @@ cairo_bool_t
cairo_font_options_equal (const cairo_font_options_t *options,
const cairo_font_options_t *other)
{
+ if (options == NULL)
+ options = &_cairo_font_options_nil;
+ if (other == NULL)
+ other = &_cairo_font_options_nil;
+
+ if (options == other)
+ return TRUE;
+
return (options->antialias == other->antialias &&
options->subpixel_order == other->subpixel_order &&
options->hint_style == other->hint_style &&
@@ -233,6 +251,9 @@ slim_hidden_def (cairo_font_options_equal);
unsigned long
cairo_font_options_hash (const cairo_font_options_t *options)
{
+ if (options == NULL)
+ options = &_cairo_font_options_nil;
+
return ((options->antialias) |
(options->subpixel_order << 4) |
(options->hint_style << 8) |
@@ -270,6 +291,9 @@ slim_hidden_def (cairo_font_options_set_antialias);
cairo_antialias_t
cairo_font_options_get_antialias (const cairo_font_options_t *options)
{
+ if (cairo_font_options_status ((cairo_font_options_t *) options))
+ return CAIRO_ANTIALIAS_DEFAULT;
+
return options->antialias;
}
@@ -307,6 +331,9 @@ slim_hidden_def (cairo_font_options_set_subpixel_order);
cairo_subpixel_order_t
cairo_font_options_get_subpixel_order (const cairo_font_options_t *options)
{
+ if (cairo_font_options_status ((cairo_font_options_t *) options))
+ return CAIRO_SUBPIXEL_ORDER_DEFAULT;
+
return options->subpixel_order;
}
@@ -343,6 +370,9 @@ slim_hidden_def (cairo_font_options_set_hint_style);
cairo_hint_style_t
cairo_font_options_get_hint_style (const cairo_font_options_t *options)
{
+ if (cairo_font_options_status ((cairo_font_options_t *) options))
+ return CAIRO_HINT_STYLE_DEFAULT;
+
return options->hint_style;
}
@@ -379,5 +409,8 @@ slim_hidden_def (cairo_font_options_set_hint_metrics);
cairo_hint_metrics_t
cairo_font_options_get_hint_metrics (const cairo_font_options_t *options)
{
+ if (cairo_font_options_status ((cairo_font_options_t *) options))
+ return CAIRO_HINT_METRICS_DEFAULT;
+
return options->hint_metrics;
}
diff --git a/src/cairo-ft-font.c b/src/cairo-ft-font.c
index 0db38ae..e2ebc2d 100644
--- a/src/cairo-ft-font.c
+++ b/src/cairo-ft-font.c
@@ -1454,6 +1454,8 @@ _cairo_ft_options_merge (cairo_ft_options_t *options,
options->load_flags = load_flags | load_target;
options->extra_flags = other->extra_flags;
+ if (options->base.hint_metrics != CAIRO_HINT_METRICS_OFF)
+ options->extra_flags |= CAIRO_FT_OPTIONS_HINT_METRICS;
}
static cairo_status_t
@@ -1484,9 +1486,6 @@ _cairo_ft_scaled_font_create (cairo_ft_unscaled_font_t *unscaled,
_cairo_unscaled_font_reference (&unscaled->base);
scaled_font->unscaled = unscaled;
- if (options->hint_metrics != CAIRO_HINT_METRICS_OFF)
- ft_options.extra_flags |= CAIRO_FT_OPTIONS_HINT_METRICS;
-
_cairo_font_options_init_copy (&scaled_font->ft_options.base, options);
_cairo_ft_options_merge (&scaled_font->ft_options, &ft_options);
@@ -1645,9 +1644,11 @@ _cairo_ft_scaled_font_create_toy (cairo_toy_font_face_t *toy_face,
goto FREE_PATTERN;
}
- status = _cairo_ft_font_options_substitute (font_options, pattern);
- if (status)
- goto FREE_PATTERN;
+ if (font_options != NULL) {
+ status = _cairo_ft_font_options_substitute (font_options, pattern);
+ if (status)
+ goto FREE_PATTERN;
+ }
FcDefaultSubstitute (pattern);
@@ -2433,6 +2434,9 @@ void
cairo_ft_font_options_substitute (const cairo_font_options_t *options,
FcPattern *pattern)
{
+ if (cairo_font_options_status ((cairo_font_options_t *) options))
+ return;
+
_cairo_ft_font_options_substitute (options, pattern);
}
diff --git a/src/cairo-gstate.c b/src/cairo-gstate.c
index 099f7ed..3577d84 100644
--- a/src/cairo-gstate.c
+++ b/src/cairo-gstate.c
@@ -1365,7 +1365,7 @@ _cairo_gstate_set_font_options (cairo_gstate_t *gstate,
{
_cairo_gstate_unset_scaled_font (gstate);
- gstate->font_options = *options;
+ _cairo_font_options_init_copy (&gstate->font_options, options);
}
void
diff --git a/src/cairo-scaled-font.c b/src/cairo-scaled-font.c
index 2ea85ad..6a6412e 100644
--- a/src/cairo-scaled-font.c
+++ b/src/cairo-scaled-font.c
@@ -412,7 +412,7 @@ _cairo_scaled_font_init_key (cairo_scaled_font_t *scaled_font,
/* ignore translation values in the ctm */
scaled_font->ctm.x0 = 0.;
scaled_font->ctm.y0 = 0.;
- scaled_font->options = *options;
+ _cairo_font_options_init_copy (&scaled_font->options, options);
/* We do a bytewise hash on the font matrices */
hash = _hash_bytes_fnv ((unsigned char *)(&scaled_font->font_matrix.xx),
@@ -466,9 +466,11 @@ _cairo_scaled_font_init (cairo_scaled_font_t *scaled_font,
cairo_matrix_t inverse;
cairo_status_t status;
- status = cairo_font_options_status ((cairo_font_options_t *) options);
- if (status)
- return status;
+ if (options != NULL) {
+ status = cairo_font_options_status ((cairo_font_options_t *) options);
+ if (status)
+ return status;
+ }
/* Initialize scaled_font->scale early for easier bail out on an
* invalid matrix. */
@@ -580,7 +582,8 @@ _cairo_scaled_font_fini (cairo_scaled_font_t *scaled_font)
* @ctm: user to device transformation matrix with which the font will
* be used.
* @options: options to use when getting metrics for the font and
- * rendering with it.
+ * rendering with it. A %NULL pointer will be interpreted as
+ * meaning the default options.
*
* Creates a #cairo_scaled_font_t object from a font face and matrices that
* describe the size of the font and the environment in which it will
@@ -602,8 +605,11 @@ cairo_scaled_font_create (cairo_font_face_t *font_face,
if (font_face->status)
return (cairo_scaled_font_t *)&_cairo_scaled_font_nil;
- if (cairo_font_options_status ((cairo_font_options_t *) options))
+ if (options != NULL &&
+ cairo_font_options_status ((cairo_font_options_t *) options))
+ {
return (cairo_scaled_font_t *)&_cairo_scaled_font_nil;
+ }
if (! _cairo_matrix_is_invertible (font_matrix))
return (cairo_scaled_font_t *)&_cairo_scaled_font_nil;
diff --git a/src/cairo-win32-font.c b/src/cairo-win32-font.c
index 19c494d..f7ae1f0 100644
--- a/src/cairo-win32-font.c
+++ b/src/cairo-win32-font.c
@@ -273,7 +273,7 @@ _win32_scaled_font_create (LOGFONTW *logfont,
* XXX: The other option we could pay attention to, but don't
* here is the hint_metrics options.
*/
- if (options->antialias == CAIRO_ANTIALIAS_DEFAULT)
+ if (options == NULL || options->antialias == CAIRO_ANTIALIAS_DEFAULT)
f->quality = _get_system_quality ();
else {
switch (options->antialias) {
@@ -300,7 +300,7 @@ _win32_scaled_font_create (LOGFONTW *logfont,
if (f->quality == logfont->lfQuality ||
(logfont->lfQuality == DEFAULT_QUALITY &&
- options->antialias == CAIRO_ANTIALIAS_DEFAULT)) {
+ (options == NULL || options->antialias == CAIRO_ANTIALIAS_DEFAULT))) {
/* If face_hfont is non-NULL, then we can use it to avoid creating our
* own --- because the constraints on face_hfont mentioned above
* guarantee it was created in exactly the same way that
diff --git a/src/cairo.c b/src/cairo.c
index 2eac030..4a7aec1 100644
--- a/src/cairo.c
+++ b/src/cairo.c
@@ -2666,10 +2666,12 @@ cairo_set_font_options (cairo_t *cr,
if (cr->status)
return;
- status = cairo_font_options_status ((cairo_font_options_t *) options);
- if (status) {
- _cairo_set_error (cr, status);
- return;
+ if (options != NULL) {
+ status = cairo_font_options_status ((cairo_font_options_t *) options);
+ if (status) {
+ _cairo_set_error (cr, status);
+ return;
+ }
}
_cairo_gstate_set_font_options (cr->gstate, options);
diff --git a/test/.gitignore b/test/.gitignore
index 682b6fc..e3decc7 100644
--- a/test/.gitignore
+++ b/test/.gitignore
@@ -65,6 +65,7 @@ ft-text-vertical-layout-type1
ft-text-vertical-layout-type3
font-face-get-type
font-matrix-translation
+font-options
get-and-set
get-clip
get-group-target
diff --git a/test/Makefile.am b/test/Makefile.am
index 5ed76eb..81d71ba 100644
--- a/test/Makefile.am
+++ b/test/Makefile.am
@@ -50,6 +50,7 @@ fill-rule$(EXEEXT) \
filter-nearest-offset$(EXEEXT) \
font-face-get-type$(EXEEXT) \
font-matrix-translation$(EXEEXT) \
+font-options$(EXEEXT) \
glyph-cache-pressure$(EXEEXT) \
get-and-set$(EXEEXT) \
get-clip$(EXEEXT) \
@@ -533,13 +534,14 @@ surface-pattern-scale-up$(EXEEXT)
# Any test that doesn't generate a log file goes here
NOLOG_TESTS = \
-user-data \
-svg-surface \
-svg-clip \
+fallback-resolution \
+font-options \
+multi-page \
pdf-features \
ps-features \
-multi-page \
-fallback-resolution
+svg-clip \
+svg-surface \
+user-data
# A hook that summarises the failures
check: AM_MAKEFLAGS+=-k
diff --git a/test/font-options.c b/test/font-options.c
new file mode 100644
index 0000000..fdcde15
--- /dev/null
+++ b/test/font-options.c
@@ -0,0 +1,91 @@
+/*
+ * Copyright © 2008 Chris Wilson
+ *
+ * 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
+ * Chris Wilson not be used in advertising or publicity pertaining to
+ * distribution of the software without specific, written prior
+ * permission. Chris Wilson makes no representations about the
+ * suitability of this software for any purpose. It is provided "as
+ * is" without express or implied warranty.
+ *
+ * CHRIS WILSON DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
+ * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS, IN NO EVENT SHALL CHRIS WILSON 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: Chris Wilson <chris at chris-wilson.co.uk>
+ */
+
+#include <cairo.h>
+#include <assert.h>
+#include <stdlib.h>
+
+int
+main (void)
+{
+ cairo_font_options_t *options1;
+ cairo_font_options_t *options2;
+ cairo_surface_t *surface;
+ cairo_matrix_t identity;
+ cairo_t *cr;
+ cairo_scaled_font_t *scaled_font;
+
+ /* first check NULL handling of cairo_font_options_t */
+ options1 = cairo_font_options_create ();
+ options2 = cairo_font_options_copy (NULL);
+
+ assert (cairo_font_options_equal (options1, options2));
+ assert (cairo_font_options_equal (NULL, options2));
+ assert (cairo_font_options_equal (options1, NULL));
+
+ assert (cairo_font_options_hash (options1) == cairo_font_options_hash (options2));
+ assert (cairo_font_options_hash (NULL) == cairo_font_options_hash (options2));
+ assert (cairo_font_options_hash (options1) == cairo_font_options_hash (NULL));
+
+ cairo_font_options_merge (NULL, NULL);
+ cairo_font_options_merge (options1, NULL);
+ cairo_font_options_merge (options1, options2);
+
+ cairo_font_options_destroy (NULL);
+ cairo_font_options_destroy (options1);
+ cairo_font_options_destroy (options2);
+
+ cairo_font_options_set_antialias (NULL, CAIRO_ANTIALIAS_DEFAULT);
+ cairo_font_options_get_antialias (NULL);
+
+ cairo_font_options_set_subpixel_order (NULL, CAIRO_SUBPIXEL_ORDER_DEFAULT);
+ cairo_font_options_get_subpixel_order (NULL);
+
+ cairo_font_options_set_hint_style (NULL, CAIRO_HINT_STYLE_DEFAULT);
+ cairo_font_options_get_hint_style (NULL);
+
+ cairo_font_options_set_hint_metrics (NULL, CAIRO_HINT_METRICS_DEFAULT);
+ cairo_font_options_get_hint_metrics (NULL);
+
+ /* Now try creating fonts with NULLs */
+ surface = cairo_image_surface_create (CAIRO_FORMAT_RGB24, 0, 0);
+ cr = cairo_create (surface);
+ cairo_surface_destroy (surface);
+
+ cairo_matrix_init_identity (&identity);
+ scaled_font = cairo_scaled_font_create (cairo_get_font_face (cr),
+ &identity, &identity,
+ NULL);
+ assert (cairo_scaled_font_status (scaled_font) == CAIRO_STATUS_SUCCESS);
+ cairo_scaled_font_get_font_options (scaled_font, NULL);
+ cairo_scaled_font_destroy (scaled_font);
+
+ cairo_set_font_options (cr, NULL);
+ cairo_get_font_options (cr, NULL);
+
+ cairo_destroy (cr);
+
+ return 0;
+}
commit 02d0e070638f668bf50a8ce2174c21e5614dd6c4
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date: Thu Jan 17 21:39:31 2008 +0000
[cairo-font-options] Use cairo_font_options_status() rather open-coding.
By switching to cairo_font_options_status() instead of checking against
the _cairo_font_options_nil error object, the API is protected from NULL
dereferences.
diff --git a/src/cairo-font-options.c b/src/cairo-font-options.c
index 6b2cb08..a2cce35 100644
--- a/src/cairo-font-options.c
+++ b/src/cairo-font-options.c
@@ -52,7 +52,7 @@ static const cairo_font_options_t _cairo_font_options_nil = {
void
_cairo_font_options_init_default (cairo_font_options_t *options)
{
- if (options == (cairo_font_options_t *)&_cairo_font_options_nil)
+ if (cairo_font_options_status (options))
return;
options->antialias = CAIRO_ANTIALIAS_DEFAULT;
@@ -118,7 +118,7 @@ cairo_font_options_copy (const cairo_font_options_t *original)
{
cairo_font_options_t *options;
- if (original == &_cairo_font_options_nil)
+ if (cairo_font_options_status ((cairo_font_options_t *) original))
return (cairo_font_options_t *)&_cairo_font_options_nil;
options = malloc (sizeof (cairo_font_options_t));
@@ -142,7 +142,7 @@ cairo_font_options_copy (const cairo_font_options_t *original)
void
cairo_font_options_destroy (cairo_font_options_t *options)
{
- if (options == (cairo_font_options_t *)&_cairo_font_options_nil)
+ if (cairo_font_options_status (options))
return;
free (options);
@@ -184,7 +184,7 @@ void
cairo_font_options_merge (cairo_font_options_t *options,
const cairo_font_options_t *other)
{
- if (options == (cairo_font_options_t *)&_cairo_font_options_nil)
+ if (cairo_font_options_status (options))
return;
if (other->antialias != CAIRO_ANTIALIAS_DEFAULT)
@@ -252,7 +252,7 @@ void
cairo_font_options_set_antialias (cairo_font_options_t *options,
cairo_antialias_t antialias)
{
- if (options == (cairo_font_options_t *)&_cairo_font_options_nil)
+ if (cairo_font_options_status (options))
return;
options->antialias = antialias;
@@ -288,7 +288,7 @@ void
cairo_font_options_set_subpixel_order (cairo_font_options_t *options,
cairo_subpixel_order_t subpixel_order)
{
- if (options == (cairo_font_options_t *)&_cairo_font_options_nil)
+ if (cairo_font_options_status (options))
return;
options->subpixel_order = subpixel_order;
@@ -324,7 +324,7 @@ void
cairo_font_options_set_hint_style (cairo_font_options_t *options,
cairo_hint_style_t hint_style)
{
- if (options == (cairo_font_options_t *)&_cairo_font_options_nil)
+ if (cairo_font_options_status (options))
return;
options->hint_style = hint_style;
@@ -360,7 +360,7 @@ void
cairo_font_options_set_hint_metrics (cairo_font_options_t *options,
cairo_hint_metrics_t hint_metrics)
{
- if (options == (cairo_font_options_t *)&_cairo_font_options_nil)
+ if (cairo_font_options_status (options))
return;
options->hint_metrics = hint_metrics;
More information about the cairo-commit
mailing list