Add device_x_scale and device_y_scale to surface so that the coordinate system seen by the backend can differ from the nominal device coordinate space used by the application.

Useful for printer backends where the device coordinate space should be in pixels while the user visible device space is in points.
There is no API to set these values; the backends using this functionality should do that themselves before the first cairo_t is created.
reviewed by: cworth
This commit is contained in:
Keith Packard 2005-08-24 01:39:56 +00:00
parent 77a0ae7439
commit e4166936b9
5 changed files with 77 additions and 17 deletions

View file

@ -1,3 +1,30 @@
2005-08-24 Keith Packard <keithp@keithp.com>
reviewed by: cworth
* src/cairo-gstate-private.h:
* src/cairo-gstate.c: (_cairo_gstate_init),
(_cairo_gstate_apply_device_transform),
(_cairo_gstate_apply_device_inverse_transform),
(_cairo_gstate_get_matrix), (_cairo_gstate_set_matrix),
(_cairo_gstate_identity_matrix), (_cairo_gstate_user_to_backend),
(_cairo_gstate_backend_to_user):
* src/cairo-surface.c: (_cairo_surface_init),
(cairo_surface_set_device_offset):
* src/cairoint.h:
Add device_x_scale and device_y_scale to
surface so that the coordinate system seen
by the backend can differ from the nominal
device coordinate space used by the application.
Useful for printer backends where the device
coordinate space should be in pixels while the
user visible device space is in points.
There is no API to set these values; the backends
using this functionality should do that themselves
before the first cairo_t is created.
2005-08-24 Carl Worth <cworth@cworth.org>
* src/cairo.c: (cairo_show_text): Fix cairo_show_text to advance

View file

@ -63,14 +63,14 @@ struct _cairo_gstate {
cairo_clip_t clip;
cairo_surface_t *target;
cairo_matrix_t ctm;
cairo_matrix_t ctm_inverse;
cairo_matrix_t source_ctm_inverse; /* At the time ->source was set */
cairo_pen_t pen_regular;
cairo_surface_t *target;
cairo_pattern_t *source;
struct _cairo_gstate *next;

View file

@ -116,13 +116,13 @@ _cairo_gstate_init (cairo_gstate_t *gstate,
_cairo_clip_init (&gstate->clip, target);
gstate->target = cairo_surface_reference (target);
_cairo_gstate_identity_matrix (gstate);
cairo_matrix_init_identity (&gstate->source_ctm_inverse);
gstate->source_ctm_inverse = gstate->ctm_inverse;
_cairo_pen_init_empty (&gstate->pen_regular);
gstate->target = cairo_surface_reference (target);
gstate->source = _cairo_pattern_create_solid (CAIRO_COLOR_BLACK);
if (gstate->source->status)
return CAIRO_STATUS_NO_MEMORY;
@ -491,10 +491,37 @@ _cairo_gstate_get_miter_limit (cairo_gstate_t *gstate)
return gstate->miter_limit;
}
static void
_cairo_gstate_apply_device_transform (cairo_gstate_t *gstate,
cairo_matrix_t *matrix)
{
if (gstate->target->device_x_scale != 1.0 ||
gstate->target->device_y_scale != 1.0)
{
cairo_matrix_scale (matrix,
gstate->target->device_x_scale,
gstate->target->device_y_scale);
}
}
static void
_cairo_gstate_apply_device_inverse_transform (cairo_gstate_t *gstate,
cairo_matrix_t *matrix)
{
if (gstate->target->device_x_scale != 1.0 ||
gstate->target->device_y_scale != 1.0)
{
cairo_matrix_scale (matrix,
1/gstate->target->device_x_scale,
1/gstate->target->device_y_scale);
}
}
void
_cairo_gstate_get_matrix (cairo_gstate_t *gstate, cairo_matrix_t *matrix)
{
*matrix = gstate->ctm;
_cairo_gstate_apply_device_inverse_transform (gstate, matrix);
}
cairo_status_t
@ -580,6 +607,9 @@ _cairo_gstate_set_matrix (cairo_gstate_t *gstate,
if (status)
return status;
_cairo_gstate_apply_device_transform (gstate, &gstate->ctm);
_cairo_gstate_apply_device_inverse_transform (gstate, &gstate->ctm_inverse);
return CAIRO_STATUS_SUCCESS;
}
@ -591,6 +621,9 @@ _cairo_gstate_identity_matrix (cairo_gstate_t *gstate)
cairo_matrix_init_identity (&gstate->ctm);
cairo_matrix_init_identity (&gstate->ctm_inverse);
_cairo_gstate_apply_device_transform (gstate, &gstate->ctm);
_cairo_gstate_apply_device_inverse_transform (gstate, &gstate->ctm_inverse);
return CAIRO_STATUS_SUCCESS;
}
@ -632,19 +665,15 @@ void
_cairo_gstate_user_to_backend (cairo_gstate_t *gstate, double *x, double *y)
{
cairo_matrix_transform_point (&gstate->ctm, x, y);
if (gstate->target) {
*x += gstate->target->device_x_offset;
*y += gstate->target->device_y_offset;
}
*x += gstate->target->device_x_offset;
*y += gstate->target->device_y_offset;
}
void
_cairo_gstate_backend_to_user (cairo_gstate_t *gstate, double *x, double *y)
{
if (gstate->target) {
*x -= gstate->target->device_x_offset;
*y -= gstate->target->device_y_offset;
}
*x -= gstate->target->device_x_offset;
*y -= gstate->target->device_y_offset;
cairo_matrix_transform_point (&gstate->ctm_inverse, x, y);
}

View file

@ -147,8 +147,10 @@ _cairo_surface_init (cairo_surface_t *surface,
_cairo_user_data_array_init (&surface->user_data);
surface->device_x_offset = 0;
surface->device_y_offset = 0;
surface->device_x_offset = 0.0;
surface->device_y_offset = 0.0;
surface->device_x_scale = 1.0;
surface->device_y_scale = 1.0;
surface->next_clip_serial = 0;
surface->current_clip_serial = 0;
@ -542,8 +544,8 @@ cairo_surface_set_device_offset (cairo_surface_t *surface,
return;
}
surface->device_x_offset = x_offset;
surface->device_y_offset = y_offset;
surface->device_x_offset = x_offset * surface->device_x_scale;
surface->device_y_offset = y_offset * surface->device_y_scale;
}
/**

View file

@ -852,6 +852,8 @@ struct _cairo_surface {
double device_x_offset;
double device_y_offset;
double device_x_scale;
double device_y_scale;
/*
* Each time a clip region is modified, it gets the next value in this