[script] Add cvi, cvr, mod

Add implementations of convert-to-integer, convert-to-real and modulus
supplied by Zack Weinberg <zweinberg@mozilla.com>.
This commit is contained in:
Chris Wilson 2009-07-28 09:32:36 +01:00
parent 24b5ac6377
commit e2f912dc5b
3 changed files with 100 additions and 4 deletions

View file

@ -1108,6 +1108,78 @@ _curve_to (csi_t *ctx)
return CSI_STATUS_SUCCESS;
}
static csi_status_t
_cvi (csi_t *ctx)
{
csi_object_t *val, obj;
check (1);
val = _csi_peek_ostack (ctx, 0);
switch ((int) csi_object_get_type (val)) {
case CSI_OBJECT_TYPE_INTEGER:
return CSI_STATUS_SUCCESS;
case CSI_OBJECT_TYPE_REAL:
pop (1);
return _csi_push_ostack_integer (ctx, val->datum.real);
case CSI_OBJECT_TYPE_STRING:
if (! _csi_parse_number (&obj,
val->datum.string->string,
val->datum.string->len))
{
return _csi_error (CSI_STATUS_INVALID_SCRIPT);
}
pop (1);
if (csi_object_get_type (&obj) == CSI_OBJECT_TYPE_INTEGER)
return push (&obj);
else
return _csi_push_ostack_integer (ctx, obj.datum.real);
default:
return _csi_error (CSI_STATUS_INVALID_SCRIPT);
}
}
static csi_status_t
_cvr (csi_t *ctx)
{
csi_object_t *val, obj;
check (1);
val = _csi_peek_ostack (ctx, 0);
switch ((int) csi_object_get_type (val)) {
case CSI_OBJECT_TYPE_REAL:
return CSI_STATUS_SUCCESS;
case CSI_OBJECT_TYPE_INTEGER:
pop (1);
return _csi_push_ostack_real (ctx, val->datum.integer);
case CSI_OBJECT_TYPE_STRING:
if (! _csi_parse_number (&obj,
val->datum.string->string,
val->datum.string->len))
{
return _csi_error (CSI_STATUS_INVALID_SCRIPT);
}
pop (1);
if (csi_object_get_type (&obj) == CSI_OBJECT_TYPE_REAL)
return push (&obj);
else
return _csi_push_ostack_real (ctx, obj.datum.integer);
default:
return _csi_error (CSI_STATUS_INVALID_SCRIPT);
}
}
static csi_status_t
_def (csi_t *ctx)
{
@ -3241,6 +3313,25 @@ _matrix (csi_t *ctx)
return push (&matrix);
}
static csi_status_t
_mod (csi_t *ctx)
{
csi_integer_t x, y;
csi_status_t status;
check (2);
status = _csi_ostack_get_integer (ctx, 0, &y);
if (_csi_unlikely (status))
return status;
status = _csi_ostack_get_integer (ctx, 1, &x);
if (_csi_unlikely (status))
return status;
pop (2);
return _csi_push_ostack_integer (ctx, x % y);
}
static csi_status_t
_move_to (csi_t *ctx)
{
@ -5548,6 +5639,8 @@ _defs[] = {
{ "count", NULL },
{ "count-to-mark", NULL },
{ "curve-to", _curve_to },
{ "cvi", _cvi },
{ "cvr", _cvr },
{ "def", _def },
{ "device-to-user", NULL },
{ "device-to-user-distance", NULL },
@ -5601,7 +5694,7 @@ _defs[] = {
{ "mark", _mark },
{ "mask", _mask },
{ "matrix", _matrix },
{ "mod", NULL },
{ "mod", _mod },
{ "move-to", _move_to },
{ "mul", _mul },
{ "multiply", NULL },

View file

@ -824,6 +824,9 @@ _csi_translate_file (csi_t *ctx,
csi_private void
_csi_scanner_fini (csi_t *ctx, csi_scanner_t *scanner);
csi_private csi_boolean_t
_csi_parse_number (csi_object_t *obj, const char *s, int len);
/* cairo-script-stack.c */
csi_private csi_status_t

View file

@ -228,8 +228,8 @@ token_add_unchecked (csi_scanner_t *scan, int c)
buffer_add (&scan->buffer, c);
}
static csi_boolean_t
parse_number (csi_object_t *obj, const char *s, int len)
csi_boolean_t
_csi_parse_number (csi_object_t *obj, const char *s, int len)
{
int radix = 0;
long long mantissa = 0;
@ -464,7 +464,7 @@ token_end (csi_t *ctx, csi_scanner_t *scan, csi_file_t *src)
if (_csi_unlikely (status))
longjmp (scan->jmpbuf, status);
} else {
if (! parse_number (&obj, s, len)) {
if (! _csi_parse_number (&obj, s, len)) {
status = csi_name_new (ctx, &obj, s, len);
if (_csi_unlikely (status))
longjmp (scan->jmpbuf, status);