Skip to content

Commit

Permalink
Add CairoScript backend.
Browse files Browse the repository at this point in the history
A new meta-surface backend for serialising drawing operations to a
CairoScript file. The principal use (as currently envisaged) is to provide
a round-trip testing mechanism for CairoScript - i.e. we can generate
script files for every test in the suite and check that we can replay them
with perfect fidelity. (Obviously this does not provide complete coverage
of CairoScript's syntax, but should give reasonable coverage over the
operators.)
  • Loading branch information
Chris Wilson committed Nov 13, 2008
1 parent 47a56e0 commit a856371
Show file tree
Hide file tree
Showing 32 changed files with 3,540 additions and 41 deletions.
3 changes: 3 additions & 0 deletions boilerplate/Makefile.sources
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,9 @@ cairo_boilerplate_ps_sources = cairo-boilerplate-ps.c
cairo_boilerplate_quartz_private = cairo-boilerplate-quartz-private.h
cairo_boilerplate_quartz_sources = cairo-boilerplate-quartz.c

cairo_boilerplate_script_private = cairo-boilerplate-script-private.h
cairo_boilerplate_script_sources = cairo-boilerplate-script.c

cairo_boilerplate_sdl_private = cairo-boilerplate-sdl-private.h
cairo_boilerplate_sdl_sources = cairo-boilerplate-sdl.c

Expand Down
57 changes: 57 additions & 0 deletions boilerplate/cairo-boilerplate-script-private.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
/* -*- Mode: c; c-basic-offset: 4; indent-tabs-mode: t; tab-width: 8; -*- */
/*
* 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
* 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: Chris Wilson <chris@chris-wilson.co.uk>
*/

#ifndef _CAIRO_BOILERPLATE_SCRIPT_PRIVATE_H_
#define _CAIRO_BOILERPLATE_SCRIPT_PRIVATE_H_

cairo_surface_t *
_cairo_boilerplate_script_create_surface (const char *name,
cairo_content_t content,
int width,
int height,
int max_width,
int max_height,
cairo_boilerplate_mode_t mode,
int id,
void **closure);

cairo_status_t
_cairo_boilerplate_script_finish_surface (cairo_surface_t *surface);

cairo_status_t
_cairo_boilerplate_script_surface_write_to_png (cairo_surface_t *surface,
const char *filename);

cairo_surface_t *
_cairo_boilerplate_script_get_image_surface (cairo_surface_t *surface,
int page,
int width,
int height);

void
_cairo_boilerplate_script_cleanup (void *closure);

#endif
125 changes: 125 additions & 0 deletions boilerplate/cairo-boilerplate-script.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,125 @@
/* -*- Mode: c; c-basic-offset: 4; indent-tabs-mode: t; tab-width: 8; -*- */
/*
* Copyright © 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-boilerplate.h"
#include "cairo-boilerplate-script-private.h"

#include "cairo-script.h"

cairo_user_data_key_t script_closure_key;

typedef struct _script_target_closure {
char *filename;
int width;
int height;
} script_target_closure_t;

cairo_surface_t *
_cairo_boilerplate_script_create_surface (const char *name,
cairo_content_t content,
int width,
int height,
int max_width,
int max_height,
cairo_boilerplate_mode_t mode,
int id,
void **closure)
{
script_target_closure_t *ptc;
cairo_surface_t *surface;
cairo_status_t status;

*closure = ptc = xmalloc (sizeof (script_target_closure_t));

ptc->width = width;
ptc->height = height;

xasprintf (&ptc->filename, "%s.out.cs", name);
xunlink (ptc->filename);

surface = cairo_script_surface_create (ptc->filename, width, height);

status = cairo_surface_set_user_data (surface,
&script_closure_key, ptc, NULL);
if (status == CAIRO_STATUS_SUCCESS)
return surface;

cairo_surface_destroy (surface);
surface = cairo_boilerplate_surface_create_in_error (status);

free (ptc->filename);
free (ptc);
return surface;
}

cairo_status_t
_cairo_boilerplate_script_finish_surface (cairo_surface_t *surface)
{
cairo_surface_finish (surface);
return cairo_surface_status (surface);
}

cairo_status_t
_cairo_boilerplate_script_surface_write_to_png (cairo_surface_t *surface,
const char *filename)
{
return CAIRO_STATUS_WRITE_ERROR;
}

static cairo_surface_t *
_cairo_boilerplate_script_convert_to_image (cairo_surface_t *surface,
int page)
{
script_target_closure_t *ptc = cairo_surface_get_user_data (surface,
&script_closure_key);
return cairo_boilerplate_convert_to_image (ptc->filename, page);
}

cairo_surface_t *
_cairo_boilerplate_script_get_image_surface (cairo_surface_t *surface,
int page,
int width,
int height)
{
cairo_surface_t *image;

image = _cairo_boilerplate_script_convert_to_image (surface, page);
cairo_surface_set_device_offset (image,
cairo_image_surface_get_width (image) - width,
cairo_image_surface_get_height (image) - height);
surface = _cairo_boilerplate_get_image_surface (image, 0, width, height);
cairo_surface_destroy (image);

return surface;
}

void
_cairo_boilerplate_script_cleanup (void *closure)
{
script_target_closure_t *ptc = closure;
free (ptc->filename);
free (ptc);
}
16 changes: 16 additions & 0 deletions boilerplate/cairo-boilerplate.c
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,9 @@
#if CAIRO_HAS_QUARTZ_SURFACE
#include "cairo-boilerplate-quartz-private.h"
#endif
#if CAIRO_HAS_SCRIPT_SURFACE
#include "cairo-boilerplate-script-private.h"
#endif
#if CAIRO_HAS_SDL_SURFACE
#include "cairo-boilerplate-sdl-private.h"
#endif
Expand Down Expand Up @@ -603,6 +606,19 @@ static cairo_boilerplate_target_t targets[] =
NULL, TRUE, TRUE
},
#endif
#if CAIRO_HAS_SCRIPT_SURFACE
{
"script", "script", ".cs",
CAIRO_SURFACE_TYPE_SCRIPT, CAIRO_CONTENT_COLOR_ALPHA, 0,
_cairo_boilerplate_script_create_surface,
NULL,
_cairo_boilerplate_script_finish_surface,
_cairo_boilerplate_script_get_image_surface,
_cairo_boilerplate_script_surface_write_to_png,
_cairo_boilerplate_script_cleanup,
NULL, FALSE
},
#endif
#if CAIRO_HAS_SVG_SURFACE && CAIRO_CAN_TEST_SVG_SURFACE
/* It seems we should be able to round-trip SVG content perfectly
* through librsvg and cairo, but for some mysterious reason, some
Expand Down
2 changes: 2 additions & 0 deletions build/configure.ac.features
Original file line number Diff line number Diff line change
Expand Up @@ -367,6 +367,7 @@ AC_DEFUN([CAIRO_REPORT],
echo " XCB: $use_xcb"
echo " Win32: $use_win32"
echo " OS2: $use_os2"
echo " CairoScript: $use_script"
echo " PostScript: $use_ps"
echo " PDF: $use_pdf"
echo " SVG: $use_svg"
Expand All @@ -389,6 +390,7 @@ AC_DEFUN([CAIRO_REPORT],
echo " test surfaces: $use_test_surfaces"
echo " ps testing: $test_ps"
echo " pdf testing: $test_pdf"
echo " cs testing: $test_script"
echo " svg testing: $test_svg"
if test x"$use_win32" = "xyes"; then
echo " win32 printing testing: $test_win32_printing"
Expand Down
16 changes: 16 additions & 0 deletions configure.ac
Original file line number Diff line number Diff line change
Expand Up @@ -236,6 +236,22 @@ CAIRO_ENABLE_SURFACE_BACKEND(directfb, directfb, no, [

dnl ===========================================================================

CAIRO_ENABLE_SURFACE_BACKEND(script, script, no, [
test_script="yes"
csi_CFLAGS=
csi_LIBS=-lcairo-script-interpreter
if test "x$test_script" = "xyes"; then
AC_DEFINE([CAIRO_CAN_TEST_SCRIPT_SURFACE], 1,
[Define to 1 if the CairoScript backend can be tested])
else
AC_MSG_WARN([CairoScript backend will not be tested])
fi
AC_SUBST(csi_CFLAGS)
AC_SUBST(csi_LIBS)
])

dnl ===========================================================================

# We use pkg-config to look for freetype2, but fall back to
# freetype-config if it fails. We prefer pkg-config, since we can
# then just put freetype2 >= $FREETYPE_MIN_VERSION in
Expand Down
1 change: 1 addition & 0 deletions doc/public/tmpl/cairo-surface.sgml
Original file line number Diff line number Diff line change
Expand Up @@ -194,6 +194,7 @@ cairo_<emphasis>backend</emphasis>_surface_create().
@CAIRO_SURFACE_TYPE_WIN32_PRINTING:
@CAIRO_SURFACE_TYPE_QUARTZ_IMAGE:
@CAIRO_SURFACE_TYPE_SDL:
@CAIRO_SURFACE_TYPE_SCRIPT:

<!-- ##### FUNCTION cairo_surface_get_type ##### -->
<para>
Expand Down
3 changes: 3 additions & 0 deletions src/Makefile.sources
Original file line number Diff line number Diff line change
Expand Up @@ -249,3 +249,6 @@ cairo_directfb_sources = cairo-directfb-surface.c

cairo_sdl_headers = cairo-sdl.h
cairo_sdl_sources = cairo-sdl-surface.c

cairo_script_headers = cairo-script.h
cairo_script_sources = cairo-script-surface.c
1 change: 1 addition & 0 deletions src/cairo-base85-stream.c
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,7 @@ _cairo_base85_stream_create (cairo_output_stream_t *output)

_cairo_output_stream_init (&stream->base,
_cairo_base85_stream_write,
NULL,
_cairo_base85_stream_close);
stream->output = output;
stream->pending = 0;
Expand Down
2 changes: 1 addition & 1 deletion src/cairo-cache-private.h
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,7 @@ _cairo_cache_insert (cairo_cache_t *cache,
cairo_cache_entry_t *entry);

cairo_private void
_cairo_cache_foreach (cairo_cache_t *cache,
_cairo_cache_foreach (cairo_cache_t *cache,
cairo_cache_callback_func_t cache_callback,
void *closure);

Expand Down
41 changes: 24 additions & 17 deletions src/cairo-cache.c
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ _cairo_cache_remove (cairo_cache_t *cache,

static void
_cairo_cache_shrink_to_accommodate (cairo_cache_t *cache,
unsigned long additional);
unsigned long additional);

static cairo_status_t
_cairo_cache_init (cairo_cache_t *cache,
Expand All @@ -67,24 +67,19 @@ _cairo_cache_init (cairo_cache_t *cache,
}

static void
_cairo_cache_fini (cairo_cache_t *cache)
_cairo_cache_pluck (void *entry, void *closure)
{
cairo_cache_entry_t *entry;

/* We have to manually remove all entries from the cache ourselves
* rather than relying on _cairo_hash_table_destroy() to do that
* since otherwise the cache->entry_destroy callback would not get
* called on each entry. */

while (1) {
entry = _cairo_hash_table_random_entry (cache->hash_table, NULL);
if (entry == NULL)
break;
_cairo_cache_remove (cache, entry);
}
_cairo_cache_remove (closure, entry);
}

static void
_cairo_cache_fini (cairo_cache_t *cache)
{
_cairo_hash_table_foreach (cache->hash_table,
_cairo_cache_pluck,
cache);
assert (cache->size == 0);
_cairo_hash_table_destroy (cache->hash_table);
cache->size = 0;
}

/**
Expand Down Expand Up @@ -354,8 +349,20 @@ unsigned long
_cairo_hash_string (const char *c)
{
/* This is the djb2 hash. */
unsigned long hash = 5381;
unsigned long hash = _CAIRO_HASH_INIT_VALUE;
while (c && *c)
hash = ((hash << 5) + hash) + *c++;
return hash;
}

unsigned long
_cairo_hash_bytes (unsigned long hash,
const void *ptr,
unsigned int length)
{
const uint8_t *bytes = ptr;
/* This is the djb2 hash. */
while (length--)
hash = ((hash << 5) + hash) + *bytes++;
return hash;
}
1 change: 1 addition & 0 deletions src/cairo-deflate-stream.c
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,7 @@ _cairo_deflate_stream_create (cairo_output_stream_t *output)

_cairo_output_stream_init (&stream->base,
_cairo_deflate_stream_write,
NULL,
_cairo_deflate_stream_close);
stream->output = output;

Expand Down
12 changes: 12 additions & 0 deletions src/cairo-ft-font.c
Original file line number Diff line number Diff line change
Expand Up @@ -2739,6 +2739,18 @@ _cairo_ft_scaled_font_is_vertical (cairo_scaled_font_t *scaled_font)
return FALSE;
}

unsigned int
_cairo_ft_scaled_font_get_load_flags (cairo_scaled_font_t *scaled_font)
{
cairo_ft_scaled_font_t *ft_scaled_font;

if (! _cairo_scaled_font_is_ft (scaled_font))
return 0;

ft_scaled_font = (cairo_ft_scaled_font_t *) scaled_font;
return ft_scaled_font->ft_options.load_flags;
}

void
_cairo_ft_font_reset_static_data (void)
{
Expand Down
3 changes: 3 additions & 0 deletions src/cairo-ft-private.h
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,9 @@ _cairo_ft_unscaled_font_unlock_face (cairo_ft_unscaled_font_t *unscaled);
cairo_private cairo_bool_t
_cairo_ft_scaled_font_is_vertical (cairo_scaled_font_t *scaled_font);

cairo_private unsigned int
_cairo_ft_scaled_font_get_load_flags (cairo_scaled_font_t *scaled_font);

CAIRO_END_DECLS

#endif /* CAIRO_HAS_FT_FONT */
Expand Down
Loading

0 comments on commit a856371

Please sign in to comment.