Skip to content

Commit

Permalink
Add recording surface support
Browse files Browse the repository at this point in the history
  • Loading branch information
mgdm committed Sep 19, 2011
1 parent 1d9bcb7 commit 964b916
Show file tree
Hide file tree
Showing 6 changed files with 266 additions and 1 deletion.
25 changes: 25 additions & 0 deletions cairo.c
Original file line number Diff line number Diff line change
Expand Up @@ -584,6 +584,12 @@ ZEND_BEGIN_ARG_INFO(cairo_ps_surface_dsc_comment_args, ZEND_SEND_BY_VAL)
ZEND_ARG_INFO(0, comment)
ZEND_END_ARG_INFO()

/* Recording surface args */
ZEND_BEGIN_ARG_INFO(cairo_recording_surface_create_args, ZEND_SEND_BY_VAL)
ZEND_ARG_INFO(0, content)
ZEND_ARG_INFO(0, extents)
ZEND_END_ARG_INFO()

/* {{{ proto int cairo_version(void)
Returns an integer version number of the cairo library being used */
PHP_FUNCTION(cairo_version)
Expand Down Expand Up @@ -706,6 +712,9 @@ PHP_METHOD(Cairo, availableSurfaces)
#ifdef CAIRO_HAS_WIN32_SURFACE
add_next_index_string(return_value,"WIN32",1);
#endif
#ifdef CAIRO_HAS_RECORDING_SURFACE
add_next_index_string(return_value,"RECORDING",1);
#endif
}
/* }}} */

Expand Down Expand Up @@ -1101,6 +1110,11 @@ static const zend_function_entry cairo_functions[] = {
PHP_FE(cairo_win32_surface_get_image, NULL)
#endif*/
/* Recording surface functions */
#ifdef CAIRO_HAS_RECORDING_SURFACE
PHP_FE(cairo_recording_surface_create, cairo_recording_surface_create_args)
#endif

/* Compatibility with old cairo-wrapper extension */
#if PHP_VERSION_ID >= 50300
ZEND_FENTRY(cairo_matrix_create_scale, ZEND_FN(cairo_matrix_init_scale), cairo_matrix_init_scale_args, ZEND_ACC_DEPRECATED)
Expand Down Expand Up @@ -1204,6 +1218,10 @@ PHP_MINIT_FUNCTION(cairo)
#ifdef CAIRO_HAS_SVG_SURFACE
PHP_MINIT(cairo_svg_surface)(INIT_FUNC_ARGS_PASSTHRU);
#endif

#ifdef CAIRO_HAS_RECORDING_SURFACE
PHP_MINIT(cairo_recording_surface)(INIT_FUNC_ARGS_PASSTHRU);
#endif
/*
#ifdef CAIRO_HAS_QUARTZ_SURFACE
PHP_MINIT(cairo_quartz_surface)(INIT_FUNC_ARGS_PASSTHRU);
Expand Down Expand Up @@ -1289,6 +1307,13 @@ PHP_MINFO_FUNCTION(cairo)
"enabled"
#else
"disabled"
#endif
);
php_info_print_table_row(2, "Recording Surface",
#ifdef CAIRO_HAS_RECORDING_SURFACE
"enabled"
#else
"disabled"
#endif
);
php_info_print_table_colspan_header(2, "Font Backends Available");
Expand Down
169 changes: 169 additions & 0 deletions cairo_recording_surface.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,169 @@
/*
+----------------------------------------------------------------------+
| PHP Version 5 |
+----------------------------------------------------------------------+
| Copyright (c) 1997-2011 The PHP Group |
+----------------------------------------------------------------------+
| This source file is subject to version 3.01 of the PHP license, |
| that is bundled with this package in the file LICENSE, and is |
| available through the world-wide-web at the following url: |
| http://www.php.net/license/3_01.txt |
| If you did not receive a copy of the PHP license and are unable to |
| obtain it through the world-wide-web, please send a note to |
| license@php.net so we can mail you a copy immediately. |
+----------------------------------------------------------------------+
| Author: Elizabeth Smith <auroraeosrose@php.net> |
| Michael Maclean <mgdm@php.net> |
| Akshat Gupta <g.akshat@gmail.com> |
+----------------------------------------------------------------------+
*/

/* $Id$ */

#ifdef HAVE_CONFIG_H
#include "config.h"
#endif

#include "php.h"
#include "php_cairo.h"
#include "zend_exceptions.h"

#ifdef CAIRO_HAS_RECORDING_SURFACE

zend_class_entry *cairo_ce_cairorecordingsurface;
zend_class_entry *cairo_ce_cairoformat;

ZEND_BEGIN_ARG_INFO(CairoRecordingSurface___construct_args, ZEND_SEND_BY_VAL)
ZEND_ARG_INFO(0, content)
ZEND_ARG_INFO(0, extents)
ZEND_END_ARG_INFO()

static double php_cairo_get_double_from_array(zval *val, const char *name) {
zval **tmp;

if (zend_hash_find(Z_ARRVAL_P(val), name, strlen(name) + 1, (void **)&tmp) == SUCCESS) {
if (Z_TYPE_PP(tmp) != IS_DOUBLE) {
convert_to_double(*tmp);
}

return Z_DVAL_PP(tmp);
} else {
zend_error(E_WARNING, "Key '%s' does not exist", name);
}
return 0;
}

static cairo_rectangle_t *php_cairo_make_rectangle(zval *val) {
cairo_rectangle_t *rectangle = ecalloc(1, sizeof(cairo_rectangle_t));

rectangle->x = php_cairo_get_double_from_array(val, "x");
rectangle->y = php_cairo_get_double_from_array(val, "y");
rectangle->width = php_cairo_get_double_from_array(val, "width");
rectangle->height = php_cairo_get_double_from_array(val, "height");
return rectangle;
}

/* {{{ proto CairoRecordingSurface __construct(int content, array extents)
Returns new CairoRecordingSurface */
PHP_METHOD(CairoRecordingSurface, __construct)
{
long content;
cairo_surface_object *surface_object;
zval *extents = NULL;
cairo_rectangle_t *rectangle = NULL;

PHP_CAIRO_ERROR_HANDLING(TRUE)
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l|a", &content, &extents) == FAILURE) {
PHP_CAIRO_RESTORE_ERRORS(TRUE)
return;
}

if (extents != NULL) {
rectangle = php_cairo_make_rectangle(extents);
}
PHP_CAIRO_RESTORE_ERRORS(TRUE)

surface_object = (cairo_surface_object *)zend_object_store_get_object(getThis() TSRMLS_CC);
surface_object->surface = cairo_recording_surface_create(content, rectangle);

if (rectangle != NULL) {
efree(rectangle);
}

php_cairo_throw_exception(cairo_surface_status(surface_object->surface) TSRMLS_CC);
}
/* }}} */

/* {{{ proto CairoRecordingSurface cairo_recording_surface_create(int content, array extents)
Returns new CairoRecordingSurface object */
PHP_FUNCTION(cairo_recording_surface_create)
{
long content;
cairo_surface_object *surface_object;
cairo_rectangle_t *rectangle;
zval *extents;

if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l|a", &content, &extents) == FAILURE) {
return;
}

if (extents != NULL) {
rectangle = php_cairo_make_rectangle(extents);
}

object_init_ex(return_value, cairo_ce_cairorecordingsurface);
surface_object = (cairo_surface_object *)zend_object_store_get_object(return_value TSRMLS_CC);
surface_object->surface = cairo_recording_surface_create(content, rectangle);
efree(rectangle);
php_cairo_trigger_error(cairo_surface_status(surface_object->surface) TSRMLS_CC);
}
/* }}} */

PHP_FUNCTION(cairo_recording_surface_ink_extents)
{
zval *surface_zval;
cairo_surface_object *surface_object;
double x, y, width, height;

if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &surface_zval, cairo_ce_cairorecordingsurface) == FAILURE) {
return;
}

surface_object = (cairo_surface_object *)zend_object_store_get_object(getThis() TSRMLS_CC);
cairo_recording_surface_ink_extents(surface_object->surface, &x, &y, &width, &height);
array_init(return_value);
add_assoc_double(return_value, "x", x);
add_assoc_double(return_value, "y", y);
add_assoc_double(return_value, "width", width);
add_assoc_double(return_value, "height", height);
}

static function_entry cairo_recording_surface_methods[] = {
PHP_ME(CairoRecordingSurface, __construct, CairoRecordingSurface___construct_args, ZEND_ACC_PUBLIC | ZEND_ACC_CTOR)
PHP_ME_MAPPING(inkExtents, cairo_recording_surface_ink_extents, NULL, ZEND_ACC_PUBLIC)
{NULL, NULL, NULL}
};


/* {{{ PHP_MINIT_FUNCTION */
PHP_MINIT_FUNCTION(cairo_recording_surface)
{
zend_class_entry ce;

INIT_CLASS_ENTRY(ce, "CairoRecordingSurface", cairo_recording_surface_methods);
cairo_ce_cairorecordingsurface = zend_register_internal_class_ex(&ce, cairo_ce_cairosurface, "CairoSurface" TSRMLS_CC);
cairo_ce_cairorecordingsurface->create_object = cairo_surface_object_new;

return SUCCESS;
}

#endif

/*
* Local variables:
* tab-width: 4
* c-basic-offset: 4
* End:
* vim600: noet sw=4 ts=4 fdm=marker
* vim<600: noet sw=4 ts=4
*/
6 changes: 6 additions & 0 deletions cairo_surface.c
Original file line number Diff line number Diff line change
Expand Up @@ -642,6 +642,12 @@ zend_class_entry* php_cairo_get_surface_ce(cairo_surface_t *surface TSRMLS_DC)
type = cairo_ce_cairopssurface;
break;
#endif

#ifdef CAIRO_HAS_PS_SURFACE
case CAIRO_SURFACE_TYPE_RECORDING:
type = cairo_ce_cairorecordingsurface;
break;
#endif
/*
#ifdef CAIRO_HAS_WIN32_SURFACE
case CAIRO_SURFACE_TYPE_WIN32:
Expand Down
2 changes: 1 addition & 1 deletion config.m4
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ if test "$PHP_CAIRO" != "no"; then

PHP_NEW_EXTENSION(cairo, cairo.c cairo_error.c cairo_context.c cairo_pattern.c cairo_matrix.c cairo_path.c \
cairo_surface.c cairo_image_surface.c cairo_svg_surface.c cairo_pdf_surface.c cairo_ps_surface.c \
cairo_font.c cairo_font_options.c cairo_font_face.c cairo_scaled_font.c cairo_ft_font.c, $ext_shared)
cairo_font.c cairo_font_options.c cairo_font_face.c cairo_scaled_font.c cairo_ft_font.c cairo_recording_surface.c, $ext_shared)

EXT_CAIRO_HEADERS="php_cairo_api.h"

Expand Down
8 changes: 8 additions & 0 deletions php_cairo.h
Original file line number Diff line number Diff line change
Expand Up @@ -192,6 +192,7 @@ PHP_MINIT_FUNCTION(cairo_image_surface);
PHP_MINIT_FUNCTION(cairo_svg_surface);
PHP_MINIT_FUNCTION(cairo_pdf_surface);
PHP_MINIT_FUNCTION(cairo_ps_surface);
PHP_MINIT_FUNCTION(cairo_recording_surface);
PHP_MINIT_FUNCTION(cairo_ft_font);
PHP_MINIT_FUNCTION(cairo_win32_font);

Expand Down Expand Up @@ -478,6 +479,11 @@ PHP_FUNCTION(cairo_font_face_get_type);
PHP_FUNCTION(cairo_ps_surface_dsc_comment);
#endif

/* Recording surface functions */
#ifdef CAIRO_HAS_RECORDING_SURFACE
PHP_FUNCTION(cairo_recording_surface_create);
#endif

extern zend_object_handlers cairo_std_object_handlers;
extern zend_class_entry *cairo_ce_cairoexception;
extern zend_class_entry *cairo_ce_cairocontext;
Expand All @@ -489,6 +495,8 @@ extern zend_class_entry *cairo_ce_cairoimagesurface;
extern zend_class_entry *cairo_ce_cairosvgsurface;
extern zend_class_entry *cairo_ce_cairopdfsurface;
extern zend_class_entry *cairo_ce_cairopssurface;
extern zend_class_entry *cairo_ce_cairorecordingsurface;
extern zend_class_entry *cairo_ce_cairocontent;
extern zend_class_entry *cairo_ce_cairofontoptions;
extern zend_class_entry *cairo_ce_cairofontface;
extern zend_class_entry *cairo_ce_cairofonttype;
Expand Down
57 changes: 57 additions & 0 deletions tests/CairoSurface/CairoRecordingSurface/__construct.phpt
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
--TEST--
new CairoRecordingSurface [__construct() method ]
--SKIPIF--
<?php
if(!extension_loaded('cairo')) die('skip - Cairo extension not available');
if(!in_array('RECORDING', Cairo::availableSurfaces())) die('skip - SVG surface not available');
?>
--FILE--
<?php
$surface = new CairoRecordingSurface(CairoContent::COLOR_ALPHA);
var_dump($surface);

$extents = array('x' => 0, 'y' => 0, 'width' => 400, 'height' => 400);
$surface = new CairoRecordingSurface(CairoContent::COLOR_ALPHA, $extents);
var_dump($surface);

/* Wrong number args - 1 */
try {
new CairoRecordingSurface();
trigger_error('We should bomb here');
} catch (CairoException $e) {
echo $e->getMessage(), PHP_EOL;
}

/* Wrong number args - 4 */
try {
new CairoRecordingSurface(NULL, 1, 1, 1);
trigger_error('We should bomb here');
} catch (CairoException $e) {
echo $e->getMessage(), PHP_EOL;
}

/* Wrong arg type 1 */
try {
new CairoRecordingSurface(array(), 1);
trigger_error('We should bomb here');
} catch (CairoException $e) {
echo $e->getMessage(), PHP_EOL;
}

/* Wrong arg type 2 */
try {
new CairoRecordingSurface(NULL, 1);
trigger_error('We should bomb here');
} catch (CairoException $e) {
echo $e->getMessage(), PHP_EOL;
}
?>
--EXPECTF--
object(CairoRecordingSurface)#%d (0) {
}
object(CairoRecordingSurface)#%d (0) {
}
CairoRecordingSurface::__construct() expects at least 1 parameter, 0 given
CairoRecordingSurface::__construct() expects at most 2 parameters, 4 given
CairoRecordingSurface::__construct() expects parameter 1 to be long, array given
CairoRecordingSurface::__construct() expects parameter 2 to be array, integer given

0 comments on commit 964b916

Please sign in to comment.