[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().
This commit is contained in:
Chris Wilson 2008-01-17 22:31:05 +00:00
parent 02d0e07063
commit 0086db893c
10 changed files with 177 additions and 36 deletions

View file

@ -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,

View file

@ -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;
}

View file

@ -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);
}

View file

@ -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

View file

@ -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;

View file

@ -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

View file

@ -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);

1
test/.gitignore vendored
View file

@ -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

View file

@ -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

91
test/font-options.c Normal file
View file

@ -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@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;
}