Re-landing fixed cairo update, r=pav

This commit is contained in:
vladimir%pobox.com 2006-03-17 22:24:30 +00:00
Родитель 14a2473a5d
Коммит 10491893d5
59 изменённых файлов: 2031 добавлений и 1291 удалений

Просмотреть файл

@ -71,6 +71,7 @@ CSRCS = \
cairo-hash.c \
cairo-hull.c \
cairo-image-surface.c \
cairo-lzw.c \
cairo-matrix.c \
cairo-meta-surface.c \
cairo-output-stream.c \

Просмотреть файл

@ -111,6 +111,7 @@ _cairo_atsui_font_face_scaled_font_create (void *abstract_face,
}
static const cairo_font_face_backend_t _cairo_atsui_font_face_backend = {
CAIRO_FONT_TYPE_ATSUI,
_cairo_atsui_font_face_destroy,
_cairo_atsui_font_face_scaled_font_create
};
@ -149,7 +150,7 @@ CreateSizedCopyOfStyle(ATSUStyle inStyle, const cairo_matrix_t *scale)
ATSUStyle style;
OSStatus err;
// Set the style's size
/* Set the style's size */
CGAffineTransform theTransform =
CGAffineTransformMakeWithCairoFontScale(scale);
Fixed theSize =
@ -191,7 +192,7 @@ _cairo_atsui_font_set_metrics (cairo_atsui_font_t *font)
extents.height = metrics.capHeight;
extents.max_x_advance = metrics.maxAdvanceWidth;
// The FT backend doesn't handle max_y_advance either, so we'll ignore it for now.
/* The FT backend doesn't handle max_y_advance either, so we'll ignore it for now. */
extents.max_y_advance = 0.0;
_cairo_scaled_font_set_metrics (&font->base, &extents);
@ -292,7 +293,7 @@ _cairo_atsui_font_create_toy(cairo_toy_font_face_t *toy_face,
kFontNoLanguageCode, &fontID);
if (err != noErr) {
// couldn't get the font - remap css names and try again
/* couldn't get the font - remap css names and try again */
if (!strcmp(family, "serif"))
family = "Times";
@ -304,7 +305,7 @@ _cairo_atsui_font_create_toy(cairo_toy_font_face_t *toy_face,
family = "Gadget";
else if (!strcmp(family, "monospace"))
family = "Courier";
else // anything else - return error instead?
else /* anything else - return error instead? */
family = "Courier";
err = ATSUFindFontFromName(family, strlen(family),
@ -545,7 +546,7 @@ _cairo_atsui_font_text_to_glyphs (void *abstract_font,
err = ATSUSetTextPointerLocation(textLayout, utf16, 0, n16, n16);
// Set the style for all of the text
/* Set the style for all of the text */
err = ATSUSetRunStyle(textLayout,
font->style, kATSUFromTextBeginning, kATSUToTextEnd);
@ -606,7 +607,7 @@ _cairo_atsui_font_old_show_glyphs (void *abstract_font,
&rect,
&extra);
// Create a CGBitmapContext for the dest surface for drawing into
/* Create a CGBitmapContext for the dest surface for drawing into */
if (destImageSurface->depth == 1) {
colorSpace = CGColorSpaceCreateDeviceGray();
bits_per_comp = 1;
@ -651,7 +652,7 @@ _cairo_atsui_font_old_show_glyphs (void *abstract_font,
CGContextSetFontSize(myBitmapContext, 1.0);
CGContextSetTextMatrix(myBitmapContext, textTransform);
if (pattern->type == CAIRO_PATTERN_SOLID &&
if (pattern->type == CAIRO_PATTERN_TYPE_SOLID &&
_cairo_pattern_is_opaque_solid(pattern))
{
cairo_solid_pattern_t *solid = (cairo_solid_pattern_t *)pattern;
@ -693,11 +694,12 @@ _cairo_atsui_font_old_show_glyphs (void *abstract_font,
/* XXX: Need to get the text clipped */
}
// TODO - bold and italic text
//
// We could draw the text using ATSUI and get bold, italics
// etc. for free, but ATSUI does a lot of text layout work
// that we don't really need...
/* TODO - bold and italic text
*
* We could draw the text using ATSUI and get bold, italics
* etc. for free, but ATSUI does a lot of text layout work
* that we don't really need...
*/
for (i = 0; i < num_glyphs; i++) {
@ -723,6 +725,7 @@ _cairo_atsui_font_old_show_glyphs (void *abstract_font,
}
const cairo_scaled_font_backend_t cairo_atsui_scaled_font_backend = {
CAIRO_FONT_TYPE_ATSUI,
_cairo_atsui_font_create_toy,
_cairo_atsui_font_fini,
_cairo_atsui_font_scaled_glyph_init,

Просмотреть файл

@ -431,35 +431,28 @@ _cairo_beos_surface_acquire_source_image (void *abstract_surfa
cairo_beos_surface_t *surface = reinterpret_cast<cairo_beos_surface_t*>(
abstract_surface);
AutoLockView locker(surface->view);
if (!locker) {
_cairo_error(CAIRO_STATUS_NO_MEMORY);
if (!locker)
return CAIRO_STATUS_NO_MEMORY; /// XXX not exactly right, but what can we do?
}
surface->view->Sync();
if (surface->bitmap) {
*image_out = _cairo_beos_bitmap_to_surface(surface->bitmap);
if (!*image_out) {
_cairo_error(CAIRO_STATUS_NO_MEMORY);
if (!*image_out)
return CAIRO_STATUS_NO_MEMORY;
}
*image_extra = NULL;
return CAIRO_STATUS_SUCCESS;
}
BBitmap* bmp;
if (_cairo_beos_view_to_bitmap(surface->view, &bmp) != OK) {
_cairo_error(CAIRO_STATUS_NO_MEMORY);
if (_cairo_beos_view_to_bitmap(surface->view, &bmp) != OK)
return CAIRO_STATUS_NO_MEMORY; /// XXX incorrect if the error was NOT_VISIBLE
}
*image_out = _cairo_beos_bitmap_to_surface(bmp);
if (!*image_out) {
delete bmp;
_cairo_error(CAIRO_STATUS_NO_MEMORY);
return CAIRO_STATUS_NO_MEMORY;
}
*image_extra = bmp;
@ -500,10 +493,8 @@ _cairo_beos_surface_acquire_dest_image (void *abstract_surface
if (surface->bitmap) {
surface->view->Sync();
*image_out = _cairo_beos_bitmap_to_surface(surface->bitmap);
if (!*image_out) {
_cairo_error(CAIRO_STATUS_NO_MEMORY);
if (!*image_out)
return CAIRO_STATUS_NO_MEMORY;
}
image_rect->x = 0;
image_rect->y = 0;
@ -525,10 +516,8 @@ _cairo_beos_surface_acquire_dest_image (void *abstract_surface
*image_extra = NULL;
return CAIRO_STATUS_SUCCESS;
}
if (status == ERROR) {
_cairo_error(CAIRO_STATUS_NO_MEMORY);
if (status == ERROR)
return CAIRO_STATUS_NO_MEMORY;
}
*image_rect = _brect_to_cairo_rect(rect);
@ -540,10 +529,9 @@ _cairo_beos_surface_acquire_dest_image (void *abstract_surface
*image_out = _cairo_beos_bitmap_to_surface(bitmap);
delete bitmap;
if (!*image_out) {
_cairo_error(CAIRO_STATUS_NO_MEMORY);
if (!*image_out)
return CAIRO_STATUS_NO_MEMORY;
}
*image_extra = NULL;
return CAIRO_STATUS_SUCCESS;
@ -610,7 +598,7 @@ _cairo_beos_composite (cairo_operator_t op,
return CAIRO_INT_STATUS_UNSUPPORTED;
// XXX should eventually support the others
if (src->type != CAIRO_PATTERN_SURFACE ||
if (src->type != CAIRO_PATTERN_TYPE_SURFACE ||
src->extend != CAIRO_EXTEND_NONE)
{
return CAIRO_INT_STATUS_UNSUPPORTED;
@ -789,6 +777,7 @@ _cairo_beos_surface_get_extents (void *abstract_surface,
}
static const struct _cairo_surface_backend cairo_beos_surface_backend = {
CAIRO_SURFACE_TYPE_BEOS,
NULL, /* create_similar */
_cairo_beos_surface_finish,
_cairo_beos_surface_acquire_source_image,

Просмотреть файл

@ -87,6 +87,11 @@ _cairo_clip_fini (cairo_clip_t *clip);
cairo_private void
_cairo_clip_init_copy (cairo_clip_t *clip, cairo_clip_t *other);
cairo_private void
_cairo_clip_init_deep_copy (cairo_clip_t *clip,
cairo_clip_t *other,
cairo_surface_t *target);
cairo_private cairo_status_t
_cairo_clip_reset (cairo_clip_t *clip);
@ -119,8 +124,8 @@ _cairo_clip_has_clip (cairo_clip_t *clip);
cairo_private cairo_bool_t
_cairo_clip_extract_rectangles (cairo_clip_t *clip,
int max_rectangles,
cairo_clip_rect_t *rectangles_out,
int *num_rectangles_out);
int max_rectangles,
cairo_clip_rect_t *rectangles_out,
int *num_rectangles_out);
#endif /* CAIRO_CLIP_PRIVATE_H */

Просмотреть файл

@ -234,8 +234,7 @@ _cairo_clip_intersect_path (cairo_clip_t *clip,
cairo_path_fixed_t *path,
cairo_fill_rule_t fill_rule,
double tolerance,
cairo_antialias_t antialias,
cairo_surface_t *target)
cairo_antialias_t antialias)
{
cairo_clip_path_t *clip_path;
cairo_status_t status;
@ -248,8 +247,10 @@ _cairo_clip_intersect_path (cairo_clip_t *clip,
return CAIRO_STATUS_NO_MEMORY;
status = _cairo_path_fixed_init_copy (&clip_path->path, path);
if (status)
if (status) {
free (clip_path);
return status;
}
clip_path->ref_count = 1;
clip_path->fill_rule = fill_rule;
@ -257,7 +258,6 @@ _cairo_clip_intersect_path (cairo_clip_t *clip,
clip_path->antialias = antialias;
clip_path->prev = clip->path;
clip->path = clip_path;
clip->serial = _cairo_surface_allocate_clip_serial (target);
return CAIRO_STATUS_SUCCESS;
}
@ -433,13 +433,26 @@ _cairo_clip_clip (cairo_clip_t *clip,
{
cairo_status_t status;
cairo_traps_t traps;
cairo_path_fixed_t path_transformed;
if (_cairo_surface_has_device_offset_or_scale (target)) {
_cairo_path_fixed_init_copy (&path_transformed, path);
_cairo_path_fixed_offset (&path_transformed,
_cairo_fixed_from_double (target->device_x_offset),
_cairo_fixed_from_double (target->device_y_offset));
path = &path_transformed;
}
status = _cairo_clip_intersect_path (clip,
path, fill_rule, tolerance,
antialias, target);
antialias);
if (status == CAIRO_STATUS_SUCCESS)
clip->serial = _cairo_surface_allocate_clip_serial (target);
if (status != CAIRO_INT_STATUS_UNSUPPORTED)
return status;
_cairo_traps_init (&traps);
status = _cairo_path_fixed_fill_to_traps (path,
fill_rule,
@ -456,6 +469,8 @@ _cairo_clip_clip (cairo_clip_t *clip,
bail:
_cairo_traps_fini (&traps);
if (path == &path_transformed)
_cairo_path_fixed_fini (&path_transformed);
return status;
}
@ -509,3 +524,70 @@ _cairo_clip_extract_rectangles (cairo_clip_t *clip,
return _cairo_region_to_clip_rectangles (clip->region,
max_rectangles, rectangles_out, num_rectangles_out);
}
void
_cairo_clip_translate (cairo_clip_t *clip,
cairo_fixed_t tx,
cairo_fixed_t ty)
{
if (clip->region) {
pixman_region_translate (clip->region,
_cairo_fixed_integer_part (tx),
_cairo_fixed_integer_part (ty));
}
if (clip->surface) {
clip->surface_rect.x += _cairo_fixed_integer_part (tx);
clip->surface_rect.y += _cairo_fixed_integer_part (ty);
}
if (clip->path) {
cairo_clip_path_t *clip_path = clip->path;
while (clip_path) {
_cairo_path_fixed_offset (&clip_path->path, tx, ty);
clip_path = clip_path->prev;
}
}
}
static void
_cairo_clip_path_reapply_clip_path (cairo_clip_t *clip,
cairo_clip_path_t *clip_path)
{
if (clip_path->prev)
_cairo_clip_path_reapply_clip_path (clip, clip_path->prev);
_cairo_clip_intersect_path (clip,
&clip_path->path,
clip_path->fill_rule,
clip_path->tolerance,
clip_path->antialias);
}
void
_cairo_clip_init_deep_copy (cairo_clip_t *clip,
cairo_clip_t *other,
cairo_surface_t *target)
{
_cairo_clip_init (clip, target);
if (other->mode != clip->mode) {
/* We should reapply the original clip path in this case, and let
* whatever the right handling is happen */
} else {
if (other->region) {
clip->region = pixman_region_create ();
pixman_region_copy (clip->region, other->region);
}
if (other->surface) {
_cairo_surface_clone_similar (target, clip->surface, &clip->surface);
clip->surface_rect = other->surface_rect;
}
if (other->path) {
_cairo_clip_path_reapply_clip_path (clip, other->path);
}
}
}

Просмотреть файл

@ -150,7 +150,7 @@ static inline int cairo_to_directfb_format(cairo_format_t format ) {
return DSPF_A1;
default:
{
//assert(0);
/*assert(0);*/
return DSPF_UNKNOWN;
}
}
@ -483,9 +483,9 @@ _cairo_directfb_surface_composite (cairo_operator_t op,
if( _dfb_set_operator(op,surface->buffer) == DFB_UNSUPPORTED )
return CAIRO_INT_STATUS_UNSUPPORTED;
if (src_pattern->type == CAIRO_PATTERN_SOLID ) {
if (src_pattern->type == CAIRO_PATTERN_TYPE_SOLID ) {
} else if (src_pattern->type != CAIRO_PATTERN_SURFACE ||
} else if (src_pattern->type != CAIRO_PATTERN_TYPE_SURFACE ||
src_pattern->extend != CAIRO_EXTEND_NONE) {
return CAIRO_INT_STATUS_UNSUPPORTED;
}
@ -494,7 +494,7 @@ _cairo_directfb_surface_composite (cairo_operator_t op,
/* FIXME: When we fully support RENDER style 4-channel
* masks we need to check r/g/b != 1.0.
*/
if (mask_pattern->type != CAIRO_PATTERN_SOLID)
if (mask_pattern->type != CAIRO_PATTERN_TYPE_SOLID)
return CAIRO_INT_STATUS_UNSUPPORTED;
alpha = ((cairo_solid_pattern_t *)mask_pattern)->color.alpha_short >> 8;
@ -662,6 +662,7 @@ _cairo_directfb_surface_scaled_glyph_fini (cairo_scaled_glyph_t *scaled_glyph,
static const cairo_surface_backend_t cairo_directfb_surface_backend = {
CAIRO_SURFACE_TYPE_DIRECTFB,
_cairo_directfb_surface_create_similar,
_cairo_directfb_surface_finish,
_cairo_directfb_surface_acquire_source_image,

Просмотреть файл

@ -130,6 +130,18 @@ cairo_font_face_destroy (cairo_font_face_t *font_face)
free (font_face);
}
/**
* cairo_font_face_get_type:
* @font_face: a #cairo_font_face_t
*
* Return value: The type of @font_face. See #cairo_font_type_t.
**/
cairo_font_type_t
cairo_font_face_get_type (cairo_font_face_t *font_face)
{
return font_face->backend->type;
}
/**
* cairo_font_face_status:
* @font_face: a #cairo_font_face_t
@ -409,6 +421,7 @@ _cairo_toy_font_face_scaled_font_create (void *abstract_font_face
}
static const cairo_font_face_backend_t _cairo_toy_font_face_backend = {
CAIRO_FONT_TYPE_TOY,
_cairo_toy_font_face_destroy,
_cairo_toy_font_face_scaled_font_create
};

Просмотреть файл

@ -715,191 +715,184 @@ _get_bitmap_surface (FT_Bitmap *bitmap,
width = bitmap->width;
height = bitmap->rows;
if (width * height == 0) {
if (own_buffer && bitmap->buffer)
free (bitmap->buffer);
*surface = NULL;
} else {
switch (bitmap->pixel_mode) {
case FT_PIXEL_MODE_MONO:
stride = (((width + 31) & ~31) >> 3);
switch (bitmap->pixel_mode) {
case FT_PIXEL_MODE_MONO:
stride = (((width + 31) & ~31) >> 3);
if (own_buffer) {
data = bitmap->buffer;
assert (stride == bitmap->pitch);
} else {
data = malloc (stride * height);
if (!data)
return CAIRO_STATUS_NO_MEMORY;
if (stride == bitmap->pitch) {
memcpy (data, bitmap->buffer, stride * height);
} else {
int i;
unsigned char *source, *dest;
source = bitmap->buffer;
dest = data;
for (i = height; i; i--) {
memcpy (dest, source, bitmap->pitch);
memset (dest + bitmap->pitch, '\0', stride - bitmap->pitch);
source += bitmap->pitch;
dest += stride;
}
}
}
if (_native_byte_order_lsb())
{
unsigned char *d = data, c;
int count = stride * height;
while (count--) {
c = *d;
c = ((c << 1) & 0xaa) | ((c >> 1) & 0x55);
c = ((c << 2) & 0xcc) | ((c >> 2) & 0x33);
c = ((c << 4) & 0xf0) | ((c >> 4) & 0x0f);
*d++ = c;
}
}
format = CAIRO_FORMAT_A1;
break;
case FT_PIXEL_MODE_LCD:
case FT_PIXEL_MODE_LCD_V:
case FT_PIXEL_MODE_GRAY:
switch (font_options->antialias) {
case CAIRO_ANTIALIAS_DEFAULT:
case CAIRO_ANTIALIAS_GRAY:
case CAIRO_ANTIALIAS_NONE:
default:
stride = bitmap->pitch;
if (own_buffer) {
data = bitmap->buffer;
assert (stride == bitmap->pitch);
} else {
data = malloc (stride * height);
if (!data)
return CAIRO_STATUS_NO_MEMORY;
if (stride == bitmap->pitch) {
memcpy (data, bitmap->buffer, stride * height);
} else {
int i;
unsigned char *source, *dest;
source = bitmap->buffer;
dest = data;
for (i = height; i; i--) {
memcpy (dest, source, bitmap->pitch);
memset (dest + bitmap->pitch, '\0', stride - bitmap->pitch);
source += bitmap->pitch;
dest += stride;
}
}
memcpy (data, bitmap->buffer, stride * height);
}
if (_native_byte_order_lsb())
{
unsigned char *d = data, c;
int count = stride * height;
while (count--) {
c = *d;
c = ((c << 1) & 0xaa) | ((c >> 1) & 0x55);
c = ((c << 2) & 0xcc) | ((c >> 2) & 0x33);
c = ((c << 4) & 0xf0) | ((c >> 4) & 0x0f);
*d++ = c;
}
}
format = CAIRO_FORMAT_A1;
format = CAIRO_FORMAT_A8;
break;
case FT_PIXEL_MODE_LCD:
case FT_PIXEL_MODE_LCD_V:
case FT_PIXEL_MODE_GRAY:
switch (font_options->antialias) {
case CAIRO_ANTIALIAS_DEFAULT:
case CAIRO_ANTIALIAS_GRAY:
case CAIRO_ANTIALIAS_NONE:
case CAIRO_ANTIALIAS_SUBPIXEL: {
int x, y;
unsigned char *in_line, *out_line, *in;
unsigned int *out;
unsigned int red, green, blue;
int rf, gf, bf;
int s;
int o, os;
unsigned char *data_rgba;
unsigned int width_rgba, stride_rgba;
int vmul = 1;
int hmul = 1;
switch (font_options->subpixel_order) {
case CAIRO_SUBPIXEL_ORDER_DEFAULT:
case CAIRO_SUBPIXEL_ORDER_RGB:
case CAIRO_SUBPIXEL_ORDER_BGR:
default:
stride = bitmap->pitch;
if (own_buffer) {
data = bitmap->buffer;
} else {
data = malloc (stride * height);
if (!data)
return CAIRO_STATUS_NO_MEMORY;
memcpy (data, bitmap->buffer, stride * height);
}
format = CAIRO_FORMAT_A8;
width /= 3;
hmul = 3;
break;
case CAIRO_ANTIALIAS_SUBPIXEL: {
int x, y;
unsigned char *in_line, *out_line, *in;
unsigned int *out;
unsigned int red, green, blue;
int rf, gf, bf;
int s;
int o, os;
unsigned char *data_rgba;
unsigned int width_rgba, stride_rgba;
int vmul = 1;
int hmul = 1;
switch (font_options->subpixel_order) {
case CAIRO_SUBPIXEL_ORDER_DEFAULT:
case CAIRO_SUBPIXEL_ORDER_RGB:
case CAIRO_SUBPIXEL_ORDER_BGR:
default:
width /= 3;
hmul = 3;
break;
case CAIRO_SUBPIXEL_ORDER_VRGB:
case CAIRO_SUBPIXEL_ORDER_VBGR:
vmul = 3;
height /= 3;
break;
}
/*
* Filter the glyph to soften the color fringes
*/
width_rgba = width;
stride = bitmap->pitch;
stride_rgba = (width_rgba * 4 + 3) & ~3;
data_rgba = calloc (1, stride_rgba * height);
case CAIRO_SUBPIXEL_ORDER_VRGB:
case CAIRO_SUBPIXEL_ORDER_VBGR:
vmul = 3;
height /= 3;
break;
}
/*
* Filter the glyph to soften the color fringes
*/
width_rgba = width;
stride = bitmap->pitch;
stride_rgba = (width_rgba * 4 + 3) & ~3;
data_rgba = calloc (1, stride_rgba * height);
os = 1;
switch (font_options->subpixel_order) {
case CAIRO_SUBPIXEL_ORDER_VRGB:
os = stride;
case CAIRO_SUBPIXEL_ORDER_DEFAULT:
case CAIRO_SUBPIXEL_ORDER_RGB:
default:
rf = 0;
gf = 1;
bf = 2;
break;
case CAIRO_SUBPIXEL_ORDER_VBGR:
os = stride;
case CAIRO_SUBPIXEL_ORDER_BGR:
bf = 0;
gf = 1;
rf = 2;
break;
}
in_line = bitmap->buffer;
out_line = data_rgba;
for (y = 0; y < height; y++)
os = 1;
switch (font_options->subpixel_order) {
case CAIRO_SUBPIXEL_ORDER_VRGB:
os = stride;
case CAIRO_SUBPIXEL_ORDER_DEFAULT:
case CAIRO_SUBPIXEL_ORDER_RGB:
default:
rf = 0;
gf = 1;
bf = 2;
break;
case CAIRO_SUBPIXEL_ORDER_VBGR:
os = stride;
case CAIRO_SUBPIXEL_ORDER_BGR:
bf = 0;
gf = 1;
rf = 2;
break;
}
in_line = bitmap->buffer;
out_line = data_rgba;
for (y = 0; y < height; y++)
{
in = in_line;
out = (unsigned int *) out_line;
in_line += stride * vmul;
out_line += stride_rgba;
for (x = 0; x < width * hmul; x += hmul)
{
in = in_line;
out = (unsigned int *) out_line;
in_line += stride * vmul;
out_line += stride_rgba;
for (x = 0; x < width * hmul; x += hmul)
red = green = blue = 0;
o = 0;
for (s = 0; s < 3; s++)
{
red = green = blue = 0;
o = 0;
for (s = 0; s < 3; s++)
{
red += filters[rf][s]*in[x+o];
green += filters[gf][s]*in[x+o];
blue += filters[bf][s]*in[x+o];
o += os;
}
red = red / 65536;
green = green / 65536;
blue = blue / 65536;
*out++ = (green << 24) | (red << 16) | (green << 8) | blue;
red += filters[rf][s]*in[x+o];
green += filters[gf][s]*in[x+o];
blue += filters[bf][s]*in[x+o];
o += os;
}
red = red / 65536;
green = green / 65536;
blue = blue / 65536;
*out++ = (green << 24) | (red << 16) | (green << 8) | blue;
}
/* Images here are stored in native format. The
* backend must convert to its own format as needed
*/
if (own_buffer)
free (bitmap->buffer);
data = data_rgba;
stride = stride_rgba;
format = CAIRO_FORMAT_ARGB32;
subpixel = TRUE;
break;
}
}
/* Images here are stored in native format. The
* backend must convert to its own format as needed
*/
if (own_buffer)
free (bitmap->buffer);
data = data_rgba;
stride = stride_rgba;
format = CAIRO_FORMAT_ARGB32;
subpixel = TRUE;
break;
case FT_PIXEL_MODE_GRAY2:
case FT_PIXEL_MODE_GRAY4:
/* These could be triggered by very rare types of TrueType fonts */
default:
return CAIRO_STATUS_NO_MEMORY;
}
*surface = (cairo_image_surface_t *)
cairo_image_surface_create_for_data (data,
format,
width, height, stride);
if ((*surface)->base.status) {
free (data);
return CAIRO_STATUS_NO_MEMORY;
}
if (subpixel)
pixman_image_set_component_alpha ((*surface)->pixman_image, TRUE);
_cairo_image_surface_assume_ownership_of_data ((*surface));
break;
case FT_PIXEL_MODE_GRAY2:
case FT_PIXEL_MODE_GRAY4:
/* These could be triggered by very rare types of TrueType fonts */
default:
return CAIRO_STATUS_NO_MEMORY;
}
*surface = (cairo_image_surface_t *)
cairo_image_surface_create_for_data (data,
format,
width, height, stride);
if ((*surface)->base.status) {
free (data);
return CAIRO_STATUS_NO_MEMORY;
}
if (subpixel)
pixman_image_set_component_alpha ((*surface)->pixman_image, TRUE);
_cairo_image_surface_assume_ownership_of_data ((*surface));
return CAIRO_STATUS_SUCCESS;
}
@ -1074,7 +1067,9 @@ _render_glyph_bitmap (FT_Face face,
if (error)
return CAIRO_STATUS_NO_MEMORY;
_get_bitmap_surface (&glyphslot->bitmap, FALSE, font_options, surface);
status = _get_bitmap_surface (&glyphslot->bitmap, FALSE, font_options, surface);
if (status)
return status;
/*
* Note: the font's coordinate system is upside down from ours, so the
@ -1906,6 +1901,7 @@ _cairo_ft_show_glyphs (void *abstract_font,
}
const cairo_scaled_font_backend_t cairo_ft_scaled_font_backend = {
CAIRO_FONT_TYPE_FT,
_cairo_ft_scaled_font_create_toy,
_cairo_ft_scaled_font_fini,
_cairo_ft_scaled_glyph_init,
@ -2009,6 +2005,7 @@ _cairo_ft_font_face_scaled_font_create (void *abstract_face,
}
static const cairo_font_face_backend_t _cairo_ft_font_face_backend = {
CAIRO_FONT_TYPE_FT,
_cairo_ft_font_face_destroy,
_cairo_ft_font_face_scaled_font_create
};

Просмотреть файл

@ -551,8 +551,8 @@ _cairo_glitz_pattern_acquire_surface (cairo_pattern_t *pattern,
attr->acquired = FALSE;
switch (pattern->type) {
case CAIRO_PATTERN_LINEAR:
case CAIRO_PATTERN_RADIAL: {
case CAIRO_PATTERN_TYPE_LINEAR:
case CAIRO_PATTERN_TYPE_RADIAL: {
cairo_gradient_pattern_t *gradient =
(cairo_gradient_pattern_t *) pattern;
char *data;
@ -587,7 +587,7 @@ _cairo_glitz_pattern_acquire_surface (cairo_pattern_t *pattern,
if (!CAIRO_GLITZ_FEATURE_OK (dst->surface, FRAGMENT_PROGRAM))
break;
if (pattern->type == CAIRO_PATTERN_RADIAL)
if (pattern->type == CAIRO_PATTERN_TYPE_RADIAL)
n_base_params = 6;
else
n_base_params = 4;
@ -639,7 +639,7 @@ _cairo_glitz_pattern_acquire_surface (cairo_pattern_t *pattern,
glitz_buffer_destroy (buffer);
if (pattern->type == CAIRO_PATTERN_LINEAR)
if (pattern->type == CAIRO_PATTERN_TYPE_LINEAR)
{
cairo_linear_pattern_t *grad = (cairo_linear_pattern_t *) pattern;
@ -776,8 +776,8 @@ _cairo_glitz_pattern_acquire_surfaces (cairo_pattern_t *src,
* information in mask, so this will need to change when we
* support RENDER-style 4-channel masks. */
if (src->type == CAIRO_PATTERN_SOLID &&
mask->type == CAIRO_PATTERN_SOLID)
if (src->type == CAIRO_PATTERN_TYPE_SOLID &&
mask->type == CAIRO_PATTERN_TYPE_SOLID)
{
cairo_color_t combined;
cairo_solid_pattern_t *src_solid = (cairo_solid_pattern_t *) src;
@ -1018,7 +1018,7 @@ _cairo_glitz_surface_composite_trapezoids (cairo_operator_t op,
if (_glitz_ensure_target (dst->surface))
return CAIRO_INT_STATUS_UNSUPPORTED;
if (pattern->type == CAIRO_PATTERN_SURFACE)
if (pattern->type == CAIRO_PATTERN_TYPE_SURFACE)
{
_cairo_pattern_init_copy (&tmp_src_pattern.base, pattern);
@ -2121,6 +2121,7 @@ _cairo_glitz_surface_flush (void *abstract_surface)
}
static const cairo_surface_backend_t cairo_glitz_surface_backend = {
CAIRO_SURFACE_TYPE_GLITZ,
_cairo_glitz_surface_create_similar,
_cairo_glitz_surface_finish,
_cairo_glitz_surface_acquire_source_image,

Просмотреть файл

@ -252,13 +252,6 @@ _cairo_gstate_clone (cairo_gstate_t *other)
return gstate;
}
void
_moz_cairo_gstate_set_target (cairo_gstate_t *gstate, cairo_surface_t *target)
{
cairo_surface_destroy (gstate->target);
gstate->target = cairo_surface_reference (target);
}
static cairo_status_t
_cairo_gstate_recursive_apply_clip_path (cairo_gstate_t *gstate,
cairo_clip_path_t *cpath)
@ -310,30 +303,14 @@ _cairo_gstate_redirect_target (cairo_gstate_t *gstate, cairo_surface_t *child)
* since its ref is now owned by gstate->parent_target */
gstate->target = cairo_surface_reference (child);
/* Check that the new surface's clip mode is compatible */
if (gstate->clip.mode != _cairo_surface_get_clip_mode (child)) {
/* clip is not compatible; try to recreate it */
/* XXX - saving the clip path always might be useful here,
* so that we could recover non-CLIP_MODE_PATH clips */
if (gstate->clip.mode == CAIRO_CLIP_MODE_PATH) {
cairo_clip_t saved_clip = gstate->clip;
_cairo_clip_fini (&gstate->clip);
_cairo_clip_init_deep_copy (&gstate->clip, &gstate->next->clip, child);
_cairo_clip_init (&gstate->clip, child);
/* unwind the path and re-apply */
_cairo_gstate_recursive_apply_clip_path (gstate, saved_clip.path);
_cairo_clip_fini (&saved_clip);
} else {
/* uh, not sure what to do here.. */
_cairo_clip_fini (&gstate->clip);
_cairo_clip_init (&gstate->clip, child);
}
} else {
/* clip is compatible; allocate a new serial for the new surface. */
if (gstate->clip.serial)
gstate->clip.serial = _cairo_surface_allocate_clip_serial (child);
}
/* The clip is in surface backend coordinates for the previous target;
* translate it into the child's backend coordinates. */
_cairo_clip_translate (&gstate->clip,
_cairo_fixed_from_double (child->device_x_offset - gstate->parent_target->device_x_offset),
_cairo_fixed_from_double (child->device_y_offset - gstate->parent_target->device_y_offset));
}
/**
@ -394,6 +371,51 @@ _cairo_gstate_get_original_target (cairo_gstate_t *gstate)
return gstate->original_target;
}
/**
* _cairo_gstate_get_target_offsets_from_original
* @gstate: a #cairo_gstate_t
* @dx: device offset from gstate original target
* @dy: device offset from gstate original target
*
* Return the device offsets in dx, dy for the current group target
* from the original target at the top of the gstate chain.
**/
void
_cairo_gstate_get_target_offsets_from_original (cairo_gstate_t *gstate,
double *dx,
double *dy)
{
/* Because the device offsets for the current group target are
* always relative to its parent, we have to walk up the gstate
* stack to figure out the actual device offsets. */
double x = 0.0, y = 0.0;
double prevx = 0.0, prevy = 0.0;
while (gstate) {
if (gstate->parent_target) {
/* The device offset on a group surface is relative to its
* parent; we need to recover the offset to the actual
* top-level surface origin. So we increase the offsets
* by the difference between the previous (child) and the
* current (parent). We only check for
* gstate->parent_target to catch the actual redirection
* levels; we then use the target field in the gstate,
* which is the actual group target at that point.*/
x += (prevx - gstate->target->device_x_offset);
y += (prevy - gstate->target->device_y_offset);
prevx = gstate->target->device_x_offset;
prevy = gstate->target->device_y_offset;
}
gstate = gstate->next;
}
if (dx)
*dx = x;
if (dy)
*dy = y;
}
/**
* _cairo_gstate_get_clip:
* @gstate: a #cairo_gstate_t
@ -744,8 +766,24 @@ _cairo_gstate_copy_transformed_pattern (cairo_gstate_t *gstate,
cairo_pattern_t *original,
cairo_matrix_t *ctm_inverse)
{
cairo_surface_pattern_t *surface_pattern;
cairo_surface_t *surface;
cairo_matrix_t offset_matrix;
_cairo_pattern_init_copy (pattern, original);
_cairo_pattern_transform (pattern, ctm_inverse);
if (cairo_pattern_get_type (original) == CAIRO_PATTERN_TYPE_SURFACE) {
surface_pattern = (cairo_surface_pattern_t *) original;
surface = surface_pattern->surface;
if (_cairo_surface_has_device_offset_or_scale (surface)) {
cairo_matrix_init_translate (&offset_matrix,
surface->device_x_offset,
surface->device_y_offset);
_cairo_pattern_transform (pattern, &offset_matrix);
}
}
}
static void

Просмотреть файл

@ -903,6 +903,7 @@ _cairo_surface_is_image (const cairo_surface_t *surface)
}
const cairo_surface_backend_t cairo_image_surface_backend = {
CAIRO_SURFACE_TYPE_IMAGE,
_cairo_image_surface_create_similar,
_cairo_image_surface_finish,
_cairo_image_surface_acquire_source_image,

Просмотреть файл

@ -0,0 +1,498 @@
/* cairo - a vector graphics library with display and print output
*
* Copyright © 2006 Red Hat, Inc
*
* This library is free software; you can redistribute it and/or
* modify it either under the terms of the GNU Lesser General Public
* License version 2.1 as published by the Free Software Foundation
* (the "LGPL") or, at your option, under the terms of the Mozilla
* Public License Version 1.1 (the "MPL"). If you do not alter this
* notice, a recipient may use your version of this file under either
* the MPL or the LGPL.
*
* You should have received a copy of the LGPL along with this library
* in the file COPYING-LGPL-2.1; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
* You should have received a copy of the MPL along with this library
* in the file COPYING-MPL-1.1
*
* The contents of this file are subject to the Mozilla Public License
* Version 1.1 (the "License"); you may not use this file except in
* compliance with the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY
* OF ANY KIND, either express or implied. See the LGPL or the MPL for
* the specific language governing rights and limitations.
*
* The Original Code is the cairo graphics library.
*
* Contributor(s):
* Alexander Larsson <alexl@redhat.com>
*
* This code is derived from tif_lzw.c in libtiff 3.8.0.
* The original copyright notice appears below in its entirety.
*/
#include "cairoint.h"
#include <stdlib.h>
#include <stdio.h>
#include <stdarg.h>
#include <assert.h>
#include <string.h>
/*
* Copyright (c) 1988-1997 Sam Leffler
* Copyright (c) 1991-1997 Silicon Graphics, Inc.
*
* Permission to use, copy, modify, distribute, and sell this software and
* its documentation for any purpose is hereby granted without fee, provided
* that (i) the above copyright notices and this permission notice appear in
* all copies of the software and related documentation, and (ii) the names of
* Sam Leffler and Silicon Graphics may not be used in any advertising or
* publicity relating to the software without the specific, prior written
* permission of Sam Leffler and Silicon Graphics.
*
* THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND,
* EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY
* WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
*
* IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR
* ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
* OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
* WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF
* LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
* OF THIS SOFTWARE.
*/
/*
* TIFF Library.
* Rev 5.0 Lempel-Ziv & Welch Compression Support
*
* This code is derived from the compress program whose code is
* derived from software contributed to Berkeley by James A. Woods,
* derived from original work by Spencer Thomas and Joseph Orost.
*
* The original Berkeley copyright notice appears below in its entirety.
*/
#define MAXCODE(n) ((1L<<(n))-1)
/*
* The TIFF spec specifies that encoded bit
* strings range from 9 to 12 bits.
*/
#define BITS_MIN 9 /* start with 9 bits */
#define BITS_MAX 12 /* max of 12 bit strings */
/* predefined codes */
#define CODE_CLEAR 256 /* code to clear string table */
#define CODE_EOI 257 /* end-of-information code */
#define CODE_FIRST 258 /* first free code entry */
#define CODE_MAX MAXCODE(BITS_MAX)
#define HSIZE 9001L /* 91% occupancy */
#define HSHIFT (13-8)
#ifdef LZW_COMPAT
/* NB: +1024 is for compatibility with old files */
#define CSIZE (MAXCODE(BITS_MAX)+1024L)
#else
#define CSIZE (MAXCODE(BITS_MAX)+1L)
#endif
typedef uint16_t hcode_t; /* codes fit in 16 bits */
typedef struct {
long hash;
hcode_t code;
} hash_t;
typedef struct {
/* Out buffer */
unsigned char *out_buffer; /* compressed out buffer */
size_t out_buffer_size; /* # of allocated bytes in out buffer */
unsigned char *out_buffer_pos; /* current spot in out buffer */
size_t out_buffer_bytes; /* # of data bytes in out buffer */
unsigned char *out_buffer_end; /* bound on out_buffer */
unsigned short nbits; /* # of bits/code */
unsigned short maxcode; /* maximum code for lzw_nbits */
unsigned short free_ent; /* next free entry in hash table */
long nextdata; /* next bits of i/o */
long nextbits; /* # of valid bits in lzw_nextdata */
int enc_oldcode; /* last code encountered */
long enc_checkpoint; /* point at which to clear table */
#define CHECK_GAP 10000 /* enc_ratio check interval */
long enc_ratio; /* current compression ratio */
long enc_incount; /* (input) data bytes encoded */
long enc_outcount; /* encoded (output) bytes */
hash_t* enc_hashtab; /* kept separate for small machines */
} LZWCodecState;
static void cl_hash(LZWCodecState*);
/*
* LZW Encoding.
*/
static unsigned char *
grow_out_buffer (LZWCodecState *sp, unsigned char *op)
{
size_t cc;
cc = (size_t)(op - sp->out_buffer);
sp->out_buffer_size = sp->out_buffer_size * 2;
sp->out_buffer = realloc (sp->out_buffer, sp->out_buffer_size);
/*
* The 4 here insures there is space for 2 max-sized
* codes in LZWEncode and LZWPostDecode.
*/
sp->out_buffer_end = sp->out_buffer + sp->out_buffer_size-1 - 4;
return sp->out_buffer + cc;
}
static int
LZWSetupEncode (LZWCodecState* sp)
{
memset (sp, 0, sizeof (LZWCodecState));
sp->enc_hashtab = (hash_t*) malloc (HSIZE * sizeof (hash_t));
if (sp->enc_hashtab == NULL)
return 0;
return 1;
}
static void
LZWFreeEncode (LZWCodecState* sp)
{
if (sp->enc_hashtab)
free (sp->enc_hashtab);
}
/*
* Reset encoding state at the start of a strip.
*/
static void
LZWPreEncode (LZWCodecState *sp)
{
sp->nbits = BITS_MIN;
sp->maxcode = MAXCODE(BITS_MIN);
sp->free_ent = CODE_FIRST;
sp->nextbits = 0;
sp->nextdata = 0;
sp->enc_checkpoint = CHECK_GAP;
sp->enc_ratio = 0;
sp->enc_incount = 0;
sp->enc_outcount = 0;
/*
* The 4 here insures there is space for 2 max-sized
* codes in LZWEncode and LZWPostDecode.
*/
sp->out_buffer_end = sp->out_buffer + sp->out_buffer_size-1 - 4;
cl_hash(sp); /* clear hash table */
sp->enc_oldcode = (hcode_t) -1; /* generates CODE_CLEAR in LZWEncode */
}
#define CALCRATIO(sp, rat) { \
if (incount > 0x007fffff) { /* NB: shift will overflow */ \
rat = outcount >> 8; \
rat = (rat == 0 ? 0x7fffffff : incount/rat); \
} else \
rat = (incount << 8) / outcount; \
}
#define PutNextCode(op, c) { \
nextdata = (nextdata << nbits) | c; \
nextbits += nbits; \
*op++ = (unsigned char)(nextdata >> (nextbits-8)); \
nextbits -= 8; \
if (nextbits >= 8) { \
*op++ = (unsigned char)(nextdata >> (nextbits-8)); \
nextbits -= 8; \
} \
outcount += nbits; \
}
/*
* Encode a chunk of pixels.
*
* Uses an open addressing double hashing (no chaining) on the
* prefix code/next character combination. We do a variant of
* Knuth's algorithm D (vol. 3, sec. 6.4) along with G. Knott's
* relatively-prime secondary probe. Here, the modular division
* first probe is gives way to a faster exclusive-or manipulation.
* Also do block compression with an adaptive reset, whereby the
* code table is cleared when the compression ratio decreases,
* but after the table fills. The variable-length output codes
* are re-sized at this point, and a CODE_CLEAR is generated
* for the decoder.
*/
static int
LZWEncode (LZWCodecState *sp,
unsigned char *bp,
size_t cc)
{
register long fcode;
register hash_t *hp;
register int h, c;
hcode_t ent;
long disp;
long incount, outcount, checkpoint;
long nextdata, nextbits;
int free_ent, maxcode, nbits;
unsigned char *op;
/*
* Load local state.
*/
incount = sp->enc_incount;
outcount = sp->enc_outcount;
checkpoint = sp->enc_checkpoint;
nextdata = sp->nextdata;
nextbits = sp->nextbits;
free_ent = sp->free_ent;
maxcode = sp->maxcode;
nbits = sp->nbits;
op = sp->out_buffer_pos;
ent = sp->enc_oldcode;
if (ent == (hcode_t) -1 && cc > 0) {
/*
* NB: This is safe because it can only happen
* at the start of a strip where we know there
* is space in the data buffer.
*/
PutNextCode(op, CODE_CLEAR);
ent = *bp++; cc--; incount++;
}
while (cc > 0) {
c = *bp++; cc--; incount++;
fcode = ((long)c << BITS_MAX) + ent;
h = (c << HSHIFT) ^ ent; /* xor hashing */
#ifdef _WINDOWS
/*
* Check hash index for an overflow.
*/
if (h >= HSIZE)
h -= HSIZE;
#endif
hp = &sp->enc_hashtab[h];
if (hp->hash == fcode) {
ent = hp->code;
continue;
}
if (hp->hash >= 0) {
/*
* Primary hash failed, check secondary hash.
*/
disp = HSIZE - h;
if (h == 0)
disp = 1;
do {
/*
* Avoid pointer arithmetic 'cuz of
* wraparound problems with segments.
*/
if ((h -= disp) < 0)
h += HSIZE;
hp = &sp->enc_hashtab[h];
if (hp->hash == fcode) {
ent = hp->code;
goto hit;
}
} while (hp->hash >= 0);
}
/*
* New entry, emit code and add to table.
*/
/*
* Verify there is space in the buffer for the code
* and any potential Clear code that might be emitted
* below. The value of limit is setup so that there
* are at least 4 bytes free--room for 2 codes.
*/
if (op > sp->out_buffer_end) {
op = grow_out_buffer (sp, op);
if (sp->out_buffer == NULL) {
return 0;
}
}
PutNextCode(op, ent);
ent = c;
hp->code = free_ent++;
hp->hash = fcode;
if (free_ent == CODE_MAX-1) {
/* table is full, emit clear code and reset */
cl_hash(sp);
sp->enc_ratio = 0;
incount = 0;
outcount = 0;
free_ent = CODE_FIRST;
PutNextCode(op, CODE_CLEAR);
nbits = BITS_MIN;
maxcode = MAXCODE(BITS_MIN);
} else {
/*
* If the next entry is going to be too big for
* the code size, then increase it, if possible.
*/
if (free_ent > maxcode) {
nbits++;
assert(nbits <= BITS_MAX);
maxcode = (int) MAXCODE(nbits);
} else if (incount >= checkpoint) {
long rat;
/*
* Check compression ratio and, if things seem
* to be slipping, clear the hash table and
* reset state. The compression ratio is a
* 24+8-bit fractional number.
*/
checkpoint = incount+CHECK_GAP;
CALCRATIO(sp, rat);
if (rat <= sp->enc_ratio) {
cl_hash(sp);
sp->enc_ratio = 0;
incount = 0;
outcount = 0;
free_ent = CODE_FIRST;
PutNextCode(op, CODE_CLEAR);
nbits = BITS_MIN;
maxcode = MAXCODE(BITS_MIN);
} else
sp->enc_ratio = rat;
}
}
hit:
;
}
/*
* Restore global state.
*/
sp->enc_incount = incount;
sp->enc_outcount = outcount;
sp->enc_checkpoint = checkpoint;
sp->enc_oldcode = ent;
sp->nextdata = nextdata;
sp->nextbits = nextbits;
sp->free_ent = free_ent;
sp->maxcode = maxcode;
sp->nbits = nbits;
sp->out_buffer_pos = op;
return 1;
}
/*
* Finish off an encoded strip by flushing the last
* string and tacking on an End Of Information code.
*/
static int
LZWPostEncode (LZWCodecState *sp)
{
unsigned char *op = sp->out_buffer_pos;
long nextbits = sp->nextbits;
long nextdata = sp->nextdata;
long outcount = sp->enc_outcount;
int nbits = sp->nbits;
if (op > sp->out_buffer_end) {
op = grow_out_buffer (sp, op);
if (sp->out_buffer == NULL) {
return 0;
}
}
if (sp->enc_oldcode != (hcode_t) -1) {
PutNextCode(op, sp->enc_oldcode);
sp->enc_oldcode = (hcode_t) -1;
}
PutNextCode(op, CODE_EOI);
if (nextbits > 0)
*op++ = (unsigned char)(nextdata << (8-nextbits));
sp->out_buffer_bytes = (size_t)(op - sp->out_buffer);
return 1;
}
/*
* Reset encoding hash table.
*/
static void
cl_hash (LZWCodecState* sp)
{
register hash_t *hp = &sp->enc_hashtab[HSIZE-1];
register long i = HSIZE-8;
do {
i -= 8;
hp[-7].hash = -1;
hp[-6].hash = -1;
hp[-5].hash = -1;
hp[-4].hash = -1;
hp[-3].hash = -1;
hp[-2].hash = -1;
hp[-1].hash = -1;
hp[ 0].hash = -1;
hp -= 8;
} while (i >= 0);
for (i += 8; i > 0; i--, hp--)
hp->hash = -1;
}
/*
* Copyright (c) 1985, 1986 The Regents of the University of California.
* All rights reserved.
*
* This code is derived from software contributed to Berkeley by
* James A. Woods, derived from original work by Spencer Thomas
* and Joseph Orost.
*
* Redistribution and use in source and binary forms are permitted
* provided that the above copyright notice and this paragraph are
* duplicated in all such forms and that any documentation,
* advertising materials, and other materials related to such
* distribution and use acknowledge that the software was developed
* by the University of California, Berkeley. The name of the
* University may not be used to endorse or promote products derived
* from this software without specific prior written permission.
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*/
void *
_cairo_compress_lzw (void *data, unsigned long data_size, unsigned long *compressed_size)
{
LZWCodecState state;
if (!LZWSetupEncode (&state))
goto bail0;
state.out_buffer_size = data_size/4;
/* We need *some* space at least */
if (state.out_buffer_size < 256)
state.out_buffer_size = 256;
state.out_buffer = malloc (state.out_buffer_size);
if (state.out_buffer == NULL)
goto bail1;
state.out_buffer_pos = state.out_buffer;
state.out_buffer_bytes = 0;
LZWPreEncode (&state);
if (!LZWEncode (&state, data, data_size))
goto bail2;
if (!LZWPostEncode(&state))
goto bail2;
LZWFreeEncode(&state);
*compressed_size = state.out_buffer_bytes;
return state.out_buffer;
bail2:
if (state.out_buffer)
free (state.out_buffer);
bail1:
LZWFreeEncode(&state);
bail0:
return NULL;
}

Просмотреть файл

@ -201,7 +201,7 @@ _init_pattern_with_snapshot (cairo_pattern_t *pattern,
{
_cairo_pattern_init_copy (pattern, other);
if (pattern->type == CAIRO_PATTERN_SURFACE) {
if (pattern->type == CAIRO_PATTERN_TYPE_SURFACE) {
cairo_surface_pattern_t *surface_pattern =
(cairo_surface_pattern_t *) pattern;
cairo_surface_t *surface = surface_pattern->surface;
@ -557,6 +557,7 @@ _cairo_surface_is_meta (const cairo_surface_t *surface)
}
static const cairo_surface_backend_t cairo_meta_surface_backend = {
CAIRO_INTERNAL_SURFACE_TYPE_META,
_cairo_meta_surface_create_similar,
_cairo_meta_surface_finish,
_cairo_meta_surface_acquire_source_image,

Просмотреть файл

@ -114,6 +114,69 @@ _cairo_output_stream_write_hex_string (cairo_output_stream_t *stream,
}
}
static cairo_bool_t
convert_four_tuple (const unsigned char *four_tuple, char five_tuple[5])
{
cairo_bool_t all_zero;
uint32_t value;
int digit, i;
value = four_tuple[0] << 24 | four_tuple[1] << 16 | four_tuple[2] << 8 | four_tuple[3];
all_zero = TRUE;
for (i = 0; i < 5; i++) {
digit = value % 85;
if (digit != 0)
all_zero = FALSE;
five_tuple[4-i] = digit + 33;
value = value / 85;
}
return all_zero;
}
void
_cairo_output_stream_write_base85_string (cairo_output_stream_t *stream,
const char *data,
size_t length)
{
unsigned char *ptr;
unsigned char four_tuple[4];
char five_tuple[5];
int column;
ptr = (unsigned char *)data;
column = 0;
while (length > 0) {
if (length >= 4) {
if (convert_four_tuple (ptr, five_tuple)) {
column += 1;
_cairo_output_stream_write (stream, "z", 1);
} else {
column += 5;
_cairo_output_stream_write (stream, five_tuple, 5);
}
length -= 4;
ptr += 4;
} else { /* length < 4 */
memset (four_tuple, 0, 4);
memcpy (four_tuple, ptr, length);
convert_four_tuple (four_tuple, five_tuple);
column += length + 1;
_cairo_output_stream_write (stream, five_tuple, length + 1);
length = 0;
}
if (column >= 72) {
_cairo_output_stream_write (stream, "\n", 1);
column = 0;
}
}
if (column > 0) {
_cairo_output_stream_write (stream, "\n", 1);
}
}
/* Format a double in a locale independent way and trim trailing
* zeros. Based on code from Alex Larson <alexl@redhat.com>.
* http://mail.gnome.org/archives/gtk-devel-list/2001-October/msg00087.html
@ -305,9 +368,11 @@ _cairo_output_stream_create_for_file (const char *filename)
return NULL;
stream = _cairo_output_stream_create (stdio_write, fp);
if (stream == NULL)
if (stream)
stream->owns_closure_is_file = TRUE;
else
fclose (fp);
stream->owns_closure_is_file = TRUE;
return stream;
}

Просмотреть файл

@ -47,7 +47,7 @@ _cairo_paginated_surface_create (cairo_surface_t *target,
cairo_private cairo_surface_t *
_cairo_paginated_surface_get_target (cairo_surface_t *surface);
cairo_bool_t
cairo_private cairo_bool_t
_cairo_surface_is_paginated (cairo_surface_t *surface);
#endif /* CAIRO_PAGINATED_SURFACE_H */

Просмотреть файл

@ -97,6 +97,24 @@ const cairo_private cairo_surface_backend_t cairo_paginated_surface_backend;
static cairo_int_status_t
_cairo_paginated_surface_show_page (void *abstract_surface);
/* XXX: This would seem the natural thing to do here. But currently,
* PDF and PS surfaces do not yet work as source surfaces. So instead,
* we don't implement create_similar for the paginate_surface which
* means that any create_similar() call on a paginated_surfacae will
* result in a new image surface. */
#if 0
static cairo_surface_t *
_cairo_paginated_surface_create_similar (void *abstract_surface,
cairo_content_t content,
int width,
int height)
{
cairo_paginated_surface_t *surface = abstract_surface;
return cairo_surface_create_similar (surface->target, content,
width, height);
}
#endif
cairo_surface_t *
_cairo_paginated_surface_create (cairo_surface_t *target,
cairo_content_t content,
@ -111,6 +129,10 @@ _cairo_paginated_surface_create (cairo_surface_t *target,
_cairo_surface_init (&surface->base, &cairo_paginated_surface_backend);
/* Override surface->base.type with target's type so we don't leak
* evidence of the paginated wrapper out to the user. */
surface->base.type = cairo_surface_get_type (target);
surface->content = content;
surface->width = width;
surface->height = height;
@ -381,7 +403,8 @@ _cairo_paginated_surface_snapshot (void *abstract_other)
}
const cairo_surface_backend_t cairo_paginated_surface_backend = {
NULL, /* create_similar */
CAIRO_INTERNAL_SURFACE_TYPE_PAGINATED,
NULL, /* create_similar --- see note for _cairo_paginated_surface_create_similar */
_cairo_paginated_surface_finish,
_cairo_paginated_surface_acquire_source_image,
_cairo_paginated_surface_release_source_image,

Просмотреть файл

@ -549,12 +549,12 @@ _cairo_path_fixed_interpret (cairo_path_fixed_t *path,
return CAIRO_STATUS_SUCCESS;
}
void
static void
_cairo_path_fixed_offset_and_scale (cairo_path_fixed_t *path,
cairo_fixed_t offx,
cairo_fixed_t offy,
cairo_fixed_t scalex,
cairo_fixed_t scaley)
cairo_fixed_t offx,
cairo_fixed_t offy,
cairo_fixed_t scalex,
cairo_fixed_t scaley)
{
cairo_path_arg_buf_t *arg_buf = path->arg_buf_head;
int i;
@ -563,8 +563,7 @@ _cairo_path_fixed_offset_and_scale (cairo_path_fixed_t *path,
while (arg_buf) {
for (i = 0; i < arg_buf->num_points; i++) {
/* CAIRO_FIXED_ONE? */
if (scalex == 0x00010000) {
if (scalex == CAIRO_FIXED_ONE) {
arg_buf->points[i].x += offx;
} else {
fixedtemp = arg_buf->points[i].x + offx;
@ -572,7 +571,7 @@ _cairo_path_fixed_offset_and_scale (cairo_path_fixed_t *path,
arg_buf->points[i].x = _cairo_int64_to_int32(_cairo_int64_rsl (i64temp, 16));
}
if (scaley == 0x00010000) {
if (scaley == CAIRO_FIXED_ONE) {
arg_buf->points[i].y += offy;
} else {
fixedtemp = arg_buf->points[i].y + offy;
@ -585,3 +584,13 @@ _cairo_path_fixed_offset_and_scale (cairo_path_fixed_t *path,
}
}
void
_cairo_path_fixed_offset (cairo_path_fixed_t *path,
cairo_fixed_t offx,
cairo_fixed_t offy)
{
_cairo_path_fixed_offset_and_scale (path, offx, offy,
CAIRO_FIXED_ONE,
CAIRO_FIXED_ONE);
}

Просмотреть файл

@ -30,7 +30,7 @@
#include "cairoint.h"
const cairo_solid_pattern_t cairo_pattern_nil = {
{ CAIRO_PATTERN_SOLID, /* type */
{ CAIRO_PATTERN_TYPE_SOLID, /* type */
(unsigned int)-1, /* ref_count */
CAIRO_STATUS_NO_MEMORY, /* status */
{ 1., 0., 0., 1., 0., 0., }, /* matrix */
@ -39,7 +39,7 @@ const cairo_solid_pattern_t cairo_pattern_nil = {
};
static const cairo_solid_pattern_t cairo_pattern_nil_null_pointer = {
{ CAIRO_PATTERN_SOLID, /* type */
{ CAIRO_PATTERN_TYPE_SOLID, /* type */
(unsigned int)-1, /* ref_count */
CAIRO_STATUS_NULL_POINTER,/* status */
{ 1., 0., 0., 1., 0., 0., }, /* matrix */
@ -48,7 +48,7 @@ static const cairo_solid_pattern_t cairo_pattern_nil_null_pointer = {
};
static const cairo_solid_pattern_t cairo_pattern_nil_file_not_found = {
{ CAIRO_PATTERN_SOLID, /* type */
{ CAIRO_PATTERN_TYPE_SOLID, /* type */
(unsigned int)-1, /* ref_count */
CAIRO_STATUS_FILE_NOT_FOUND, /* status */
{ 1., 0., 0., 1., 0., 0., }, /* matrix */
@ -57,7 +57,7 @@ static const cairo_solid_pattern_t cairo_pattern_nil_file_not_found = {
};
static const cairo_solid_pattern_t cairo_pattern_nil_read_error = {
{ CAIRO_PATTERN_SOLID, /* type */
{ CAIRO_PATTERN_TYPE_SOLID, /* type */
(unsigned int)-1, /* ref_count */
CAIRO_STATUS_READ_ERROR, /* status */
{ 1., 0., 0., 1., 0., 0., }, /* matrix */
@ -117,7 +117,7 @@ _cairo_pattern_init (cairo_pattern_t *pattern, cairo_pattern_type_t type)
pattern->ref_count = 1;
pattern->status = CAIRO_STATUS_SUCCESS;
if (type == CAIRO_PATTERN_SURFACE)
if (type == CAIRO_PATTERN_TYPE_SURFACE)
pattern->extend = CAIRO_EXTEND_SURFACE_DEFAULT;
else
pattern->extend = CAIRO_EXTEND_GRADIENT_DEFAULT;
@ -131,7 +131,7 @@ static void
_cairo_gradient_pattern_init_copy (cairo_gradient_pattern_t *pattern,
const cairo_gradient_pattern_t *other)
{
if (other->base.type == CAIRO_PATTERN_LINEAR)
if (other->base.type == CAIRO_PATTERN_TYPE_LINEAR)
{
cairo_linear_pattern_t *dst = (cairo_linear_pattern_t *) pattern;
cairo_linear_pattern_t *src = (cairo_linear_pattern_t *) other;
@ -170,21 +170,21 @@ _cairo_pattern_init_copy (cairo_pattern_t *pattern,
}
switch (other->type) {
case CAIRO_PATTERN_SOLID: {
case CAIRO_PATTERN_TYPE_SOLID: {
cairo_solid_pattern_t *dst = (cairo_solid_pattern_t *) pattern;
cairo_solid_pattern_t *src = (cairo_solid_pattern_t *) other;
*dst = *src;
} break;
case CAIRO_PATTERN_SURFACE: {
case CAIRO_PATTERN_TYPE_SURFACE: {
cairo_surface_pattern_t *dst = (cairo_surface_pattern_t *) pattern;
cairo_surface_pattern_t *src = (cairo_surface_pattern_t *) other;
*dst = *src;
cairo_surface_reference (dst->surface);
} break;
case CAIRO_PATTERN_LINEAR:
case CAIRO_PATTERN_RADIAL: {
case CAIRO_PATTERN_TYPE_LINEAR:
case CAIRO_PATTERN_TYPE_RADIAL: {
cairo_gradient_pattern_t *dst = (cairo_gradient_pattern_t *) pattern;
cairo_gradient_pattern_t *src = (cairo_gradient_pattern_t *) other;
@ -199,16 +199,16 @@ void
_cairo_pattern_fini (cairo_pattern_t *pattern)
{
switch (pattern->type) {
case CAIRO_PATTERN_SOLID:
case CAIRO_PATTERN_TYPE_SOLID:
break;
case CAIRO_PATTERN_SURFACE: {
case CAIRO_PATTERN_TYPE_SURFACE: {
cairo_surface_pattern_t *surface_pattern =
(cairo_surface_pattern_t *) pattern;
cairo_surface_destroy (surface_pattern->surface);
} break;
case CAIRO_PATTERN_LINEAR:
case CAIRO_PATTERN_RADIAL: {
case CAIRO_PATTERN_TYPE_LINEAR:
case CAIRO_PATTERN_TYPE_RADIAL: {
cairo_gradient_pattern_t *gradient =
(cairo_gradient_pattern_t *) pattern;
@ -222,7 +222,7 @@ void
_cairo_pattern_init_solid (cairo_solid_pattern_t *pattern,
const cairo_color_t *color)
{
_cairo_pattern_init (&pattern->base, CAIRO_PATTERN_SOLID);
_cairo_pattern_init (&pattern->base, CAIRO_PATTERN_TYPE_SOLID);
pattern->color = *color;
}
@ -232,12 +232,12 @@ _cairo_pattern_init_for_surface (cairo_surface_pattern_t *pattern,
{
if (surface->status) {
/* Force to solid to simplify the pattern_fini process. */
pattern->base.type = CAIRO_PATTERN_SOLID;
pattern->base.type = CAIRO_PATTERN_TYPE_SOLID;
_cairo_pattern_set_error (&pattern->base, surface->status);
return;
}
_cairo_pattern_init (&pattern->base, CAIRO_PATTERN_SURFACE);
_cairo_pattern_init (&pattern->base, CAIRO_PATTERN_TYPE_SURFACE);
pattern->surface = cairo_surface_reference (surface);
}
@ -256,7 +256,7 @@ void
_cairo_pattern_init_linear (cairo_linear_pattern_t *pattern,
double x0, double y0, double x1, double y1)
{
_cairo_pattern_init_gradient (&pattern->base, CAIRO_PATTERN_LINEAR);
_cairo_pattern_init_gradient (&pattern->base, CAIRO_PATTERN_TYPE_LINEAR);
pattern->gradient.p1.x = _cairo_fixed_from_double (x0);
pattern->gradient.p1.y = _cairo_fixed_from_double (y0);
@ -269,7 +269,7 @@ _cairo_pattern_init_radial (cairo_radial_pattern_t *pattern,
double cx0, double cy0, double radius0,
double cx1, double cy1, double radius1)
{
_cairo_pattern_init_gradient (&pattern->base, CAIRO_PATTERN_RADIAL);
_cairo_pattern_init_gradient (&pattern->base, CAIRO_PATTERN_TYPE_RADIAL);
pattern->gradient.inner.x = _cairo_fixed_from_double (cx0);
pattern->gradient.inner.y = _cairo_fixed_from_double (cy0);
@ -524,6 +524,18 @@ cairo_pattern_reference (cairo_pattern_t *pattern)
return pattern;
}
/**
* cairo_pattern_get_type:
* @pattern: a #cairo_pattern_t
*
* Return value: The type of @pattern. See #cairo_pattern_type_t.
**/
cairo_pattern_type_t
cairo_pattern_get_type (cairo_pattern_t *pattern)
{
return pattern->type;
}
/**
* cairo_pattern_status:
* @pattern: a #cairo_pattern_t
@ -641,8 +653,8 @@ cairo_pattern_add_color_stop_rgb (cairo_pattern_t *pattern,
if (pattern->status)
return;
if (pattern->type != CAIRO_PATTERN_LINEAR &&
pattern->type != CAIRO_PATTERN_RADIAL)
if (pattern->type != CAIRO_PATTERN_TYPE_LINEAR &&
pattern->type != CAIRO_PATTERN_TYPE_RADIAL)
{
_cairo_pattern_set_error (pattern, CAIRO_STATUS_PATTERN_TYPE_MISMATCH);
return;
@ -689,8 +701,8 @@ cairo_pattern_add_color_stop_rgba (cairo_pattern_t *pattern,
if (pattern->status)
return;
if (pattern->type != CAIRO_PATTERN_LINEAR &&
pattern->type != CAIRO_PATTERN_RADIAL)
if (pattern->type != CAIRO_PATTERN_TYPE_LINEAR &&
pattern->type != CAIRO_PATTERN_TYPE_RADIAL)
{
_cairo_pattern_set_error (pattern, CAIRO_STATUS_PATTERN_TYPE_MISMATCH);
return;
@ -894,7 +906,7 @@ _cairo_pattern_acquire_surface_for_gradient (cairo_gradient_pattern_t *pattern,
cairo_status_t status;
cairo_bool_t repeat = FALSE;
if (pattern->base.type == CAIRO_PATTERN_LINEAR)
if (pattern->base.type == CAIRO_PATTERN_TYPE_LINEAR)
{
cairo_linear_pattern_t *linear = (cairo_linear_pattern_t *) pattern;
@ -936,7 +948,7 @@ _cairo_pattern_acquire_surface_for_gradient (cairo_gradient_pattern_t *pattern,
return CAIRO_STATUS_SUCCESS;
}
if (pattern->base.type == CAIRO_PATTERN_LINEAR) {
if (pattern->base.type == CAIRO_PATTERN_TYPE_LINEAR) {
cairo_bool_t is_horizontal;
cairo_bool_t is_vertical;
@ -1055,7 +1067,7 @@ _cairo_pattern_is_opaque_solid (cairo_pattern_t *pattern)
{
cairo_solid_pattern_t *solid;
if (pattern->type != CAIRO_PATTERN_SOLID)
if (pattern->type != CAIRO_PATTERN_TYPE_SOLID)
return FALSE;
solid = (cairo_solid_pattern_t *) pattern;
@ -1151,7 +1163,7 @@ _cairo_pattern_acquire_surface (cairo_pattern_t *pattern,
}
switch (pattern->type) {
case CAIRO_PATTERN_SOLID: {
case CAIRO_PATTERN_TYPE_SOLID: {
cairo_solid_pattern_t *src = (cairo_solid_pattern_t *) pattern;
status = _cairo_pattern_acquire_surface_for_solid (src, dst,
@ -1159,8 +1171,8 @@ _cairo_pattern_acquire_surface (cairo_pattern_t *pattern,
surface_out,
attributes);
} break;
case CAIRO_PATTERN_LINEAR:
case CAIRO_PATTERN_RADIAL: {
case CAIRO_PATTERN_TYPE_LINEAR:
case CAIRO_PATTERN_TYPE_RADIAL: {
cairo_gradient_pattern_t *src = (cairo_gradient_pattern_t *) pattern;
/* fast path for gradients with less than 2 color stops */
@ -1203,7 +1215,7 @@ _cairo_pattern_acquire_surface (cairo_pattern_t *pattern,
attributes);
}
} break;
case CAIRO_PATTERN_SURFACE: {
case CAIRO_PATTERN_TYPE_SURFACE: {
cairo_surface_pattern_t *src = (cairo_surface_pattern_t *) pattern;
status = _cairo_pattern_acquire_surface_for_surface (src, dst,
@ -1235,7 +1247,7 @@ _cairo_pattern_release_surface (cairo_pattern_t *pattern,
{
cairo_surface_pattern_t *surface_pattern;
assert (pattern->type == CAIRO_PATTERN_SURFACE);
assert (pattern->type == CAIRO_PATTERN_TYPE_SURFACE);
surface_pattern = (cairo_surface_pattern_t *) pattern;
_cairo_surface_release_source_image (surface_pattern->surface,
@ -1277,8 +1289,8 @@ _cairo_pattern_acquire_surfaces (cairo_pattern_t *src,
/* XXX: This optimization assumes that there is no color
* information in mask, so this will need to change when we
* support RENDER-style 4-channel masks. */
if (src->type == CAIRO_PATTERN_SOLID &&
mask && mask->type == CAIRO_PATTERN_SOLID)
if (src->type == CAIRO_PATTERN_TYPE_SOLID &&
mask && mask->type == CAIRO_PATTERN_TYPE_SOLID)
{
cairo_color_t combined;
cairo_solid_pattern_t *src_solid = (cairo_solid_pattern_t *) src;
@ -1346,7 +1358,7 @@ _cairo_pattern_get_extents (cairo_pattern_t *pattern,
cairo_rectangle_t *extents)
{
if (pattern->extend == CAIRO_EXTEND_NONE &&
pattern->type == CAIRO_PATTERN_SURFACE)
pattern->type == CAIRO_PATTERN_TYPE_SURFACE)
{
cairo_status_t status;
cairo_rectangle_t surface_extents;

Просмотреть файл

@ -654,8 +654,10 @@ emit_image_rgb_data (cairo_pdf_document_t *document,
opaque = cairo_image_surface_create (CAIRO_FORMAT_RGB24,
image->width,
image->height);
if (opaque->status)
if (opaque->status) {
free (rgb);
return 0;
}
_cairo_pattern_init_for_surface (&pattern.surface, &image->base);
@ -841,7 +843,7 @@ _cairo_pdf_surface_composite (cairo_operator_t op,
if (mask_pattern)
return CAIRO_STATUS_SUCCESS;
if (src_pattern->type != CAIRO_PATTERN_SURFACE)
if (src_pattern->type != CAIRO_PATTERN_TYPE_SURFACE)
return CAIRO_STATUS_SUCCESS;
if (src->surface->backend == &cairo_pdf_surface_backend)
@ -1237,16 +1239,16 @@ static cairo_status_t
emit_pattern (cairo_pdf_surface_t *surface, cairo_pattern_t *pattern)
{
switch (pattern->type) {
case CAIRO_PATTERN_SOLID:
case CAIRO_PATTERN_TYPE_SOLID:
return emit_solid_pattern (surface, (cairo_solid_pattern_t *) pattern);
case CAIRO_PATTERN_SURFACE:
case CAIRO_PATTERN_TYPE_SURFACE:
return emit_surface_pattern (surface, (cairo_surface_pattern_t *) pattern);
case CAIRO_PATTERN_LINEAR:
case CAIRO_PATTERN_TYPE_LINEAR:
return emit_linear_pattern (surface, (cairo_linear_pattern_t *) pattern);
case CAIRO_PATTERN_RADIAL:
case CAIRO_PATTERN_TYPE_RADIAL:
return emit_radial_pattern (surface, (cairo_radial_pattern_t *) pattern);
}
@ -1657,6 +1659,7 @@ _cairo_pdf_surface_get_font_options (void *abstract_surface,
}
static const cairo_surface_backend_t cairo_pdf_surface_backend = {
CAIRO_SURFACE_TYPE_PDF,
_cairo_pdf_surface_create_similar,
_cairo_pdf_surface_finish,
NULL, /* acquire_source_image */

Просмотреть файл

@ -50,8 +50,6 @@
*
* - Add document structure convention comments where appropriate.
*
* - Fix image compression.
*
* - Create a set of procs to use... specifically a trapezoid proc.
*/
@ -101,11 +99,9 @@ _cairo_ps_surface_emit_header (cairo_ps_surface_t *surface)
surface->width,
surface->height);
/* The "/FlateDecode filter" currently used is a feature of
* LanguageLevel 3 */
_cairo_output_stream_printf (surface->stream,
"%%%%DocumentData: Binary\n"
"%%%%LanguageLevel: 3\n"
"%%%%DocumentData: Clean7Bit\n"
"%%%%LanguageLevel: 2\n"
"%%%%Orientation: Portrait\n"
"%%%%EndComments\n");
}
@ -141,10 +137,6 @@ _cairo_ps_surface_create_for_stream_internal (cairo_output_stream_t *stream,
surface->height = height;
surface->x_dpi = PS_SURFACE_DPI_DEFAULT;
surface->y_dpi = PS_SURFACE_DPI_DEFAULT;
#if DONE_ADDING_DEVICE_SCALE_SUPPORT_AFTER_SWITCHING_TO_PAGINATED
surface->base.device_x_scale = surface->x_dpi / 72.0;
surface->base.device_y_scale = surface->y_dpi / 72.0;
#endif
surface->need_start_page = TRUE;
surface->num_pages = 0;
@ -275,11 +267,6 @@ cairo_ps_surface_set_dpi (cairo_surface_t *surface,
ps_surface->x_dpi = x_dpi;
ps_surface->y_dpi = y_dpi;
#if DONE_ADDING_DEVICE_SCALE_SUPPORT_AFTER_SWITCHING_TO_PAGINATED
ps_surface->base.device_x_scale = ps_surface->x_dpi / 72.0;
ps_surface->base.device_y_scale = ps_surface->y_dpi / 72.0;
#endif
}
/* XXX */
@ -318,8 +305,7 @@ _cairo_ps_surface_start_page (cairo_ps_surface_t *surface)
_cairo_output_stream_printf (surface->stream,
"gsave %f %f translate %f %f scale \n",
0.0, surface->height,
1.0/surface->base.device_x_scale,
-1.0/surface->base.device_y_scale);
1.0, -1.0);
surface->need_start_page = FALSE;
}
@ -546,12 +532,12 @@ pattern_is_translucent (const cairo_pattern_t *abstract_pattern)
pattern = (cairo_pattern_union_t *) abstract_pattern;
switch (pattern->base.type) {
case CAIRO_PATTERN_SOLID:
case CAIRO_PATTERN_TYPE_SOLID:
return color_is_translucent (&pattern->solid.color);
case CAIRO_PATTERN_SURFACE:
case CAIRO_PATTERN_TYPE_SURFACE:
return surface_is_translucent (pattern->surface.surface);
case CAIRO_PATTERN_LINEAR:
case CAIRO_PATTERN_RADIAL:
case CAIRO_PATTERN_TYPE_LINEAR:
case CAIRO_PATTERN_TYPE_RADIAL:
return gradient_is_translucent (&pattern->gradient.base);
}
@ -637,7 +623,7 @@ color_operation_needs_fallback (cairo_operator_t op,
static cairo_bool_t
pattern_type_supported (const cairo_pattern_t *pattern)
{
if (pattern->type == CAIRO_PATTERN_SOLID)
if (pattern->type == CAIRO_PATTERN_TYPE_SOLID)
return TRUE;
return FALSE;
}
@ -658,23 +644,6 @@ pattern_operation_needs_fallback (cairo_operator_t op,
/* PS Output - this section handles output of the parts of the meta
* surface we can render natively in PS. */
static void *
compress_dup (const void *data, unsigned long data_size,
unsigned long *compressed_size)
{
void *compressed;
/* Bound calculation taken from zlib. */
*compressed_size = data_size + (data_size >> 12) + (data_size >> 14) + 11;
compressed = malloc (*compressed_size);
if (compressed == NULL)
return NULL;
compress (compressed, compressed_size, data, data_size);
return compressed;
}
static cairo_status_t
emit_image (cairo_ps_surface_t *surface,
cairo_image_surface_t *image,
@ -745,7 +714,7 @@ emit_image (cairo_ps_surface_t *surface,
}
}
compressed = compress_dup (rgb, rgb_size, &compressed_size);
compressed = _cairo_compress_lzw (rgb, rgb_size, &compressed_size);
if (compressed == NULL) {
status = CAIRO_STATUS_NO_MEMORY;
goto bail2;
@ -765,7 +734,7 @@ emit_image (cairo_ps_surface_t *surface,
" /Height %d\n"
" /BitsPerComponent 8\n"
" /Decode [ 0 1 0 1 0 1 ]\n"
" /DataSource currentfile\n"
" /DataSource currentfile /ASCII85Decode filter /LZWDecode filter \n"
" /ImageMatrix [ %f %f %f %f %f %f ]\n"
">>\n"
"image\n",
@ -775,13 +744,13 @@ emit_image (cairo_ps_surface_t *surface,
d2i.xy, d2i.yy,
d2i.x0, d2i.y0);
/* Compressed image data */
_cairo_output_stream_write (surface->stream, rgb, rgb_size);
/* Compressed image data (Base85 encoded) */
_cairo_output_stream_write_base85_string (surface->stream, (char *)compressed, compressed_size);
status = CAIRO_STATUS_SUCCESS;
/* Mark end of base85 data */
_cairo_output_stream_printf (surface->stream,
"\n");
"~>\n");
free (compressed);
bail2:
free (rgb);
@ -837,19 +806,19 @@ emit_pattern (cairo_ps_surface_t *surface, cairo_pattern_t *pattern)
* different pattern. */
switch (pattern->type) {
case CAIRO_PATTERN_SOLID:
case CAIRO_PATTERN_TYPE_SOLID:
emit_solid_pattern (surface, (cairo_solid_pattern_t *) pattern);
break;
case CAIRO_PATTERN_SURFACE:
case CAIRO_PATTERN_TYPE_SURFACE:
emit_surface_pattern (surface, (cairo_surface_pattern_t *) pattern);
break;
case CAIRO_PATTERN_LINEAR:
case CAIRO_PATTERN_TYPE_LINEAR:
emit_linear_pattern (surface, (cairo_linear_pattern_t *) pattern);
break;
case CAIRO_PATTERN_RADIAL:
case CAIRO_PATTERN_TYPE_RADIAL:
emit_radial_pattern (surface, (cairo_radial_pattern_t *) pattern);
break;
}
@ -890,12 +859,12 @@ _cairo_ps_surface_composite (cairo_operator_t op,
status = CAIRO_STATUS_SUCCESS;
switch (src_pattern->type) {
case CAIRO_PATTERN_SOLID:
case CAIRO_PATTERN_TYPE_SOLID:
_cairo_output_stream_printf (stream,
"%% _cairo_ps_surface_composite: solid\n");
goto bail;
case CAIRO_PATTERN_SURFACE:
case CAIRO_PATTERN_TYPE_SURFACE:
surface_pattern = (cairo_surface_pattern_t *) src_pattern;
if (src_pattern->extend != CAIRO_EXTEND_NONE) {
@ -920,8 +889,8 @@ _cairo_ps_surface_composite (cairo_operator_t op,
image, image_extra);
break;
case CAIRO_PATTERN_LINEAR:
case CAIRO_PATTERN_RADIAL:
case CAIRO_PATTERN_TYPE_LINEAR:
case CAIRO_PATTERN_TYPE_RADIAL:
_cairo_output_stream_printf (stream,
"%% _cairo_ps_surface_composite: gradient\n");
goto bail;
@ -1322,6 +1291,7 @@ _cairo_ps_surface_fill (void *abstract_surface,
}
static const cairo_surface_backend_t cairo_ps_surface_backend = {
CAIRO_SURFACE_TYPE_PS,
NULL, /* create_similar */
_cairo_ps_surface_finish,
NULL, /* acquire_source_image */

Просмотреть файл

@ -73,10 +73,11 @@ _cairo_quartz_surface_acquire_source_image(void *abstract_surface,
UInt32 imageDataSize, rowBytes;
CGDataProviderRef dataProvider;
// We keep a cached (cairo_image_surface_t *) in the cairo_quartz_surface_t
// struct. If the window is ever drawn to without going through Cairo, then
// we would need to refetch the pixel data from the window into the cached
// image surface.
/* We keep a cached (cairo_image_surface_t *) in the cairo_quartz_surface_t
* struct. If the window is ever drawn to without going through Cairo, then
* we would need to refetch the pixel data from the window into the cached
* image surface.
*/
if (surface->image) {
cairo_surface_reference(&surface->image->base);
@ -216,6 +217,7 @@ _cairo_quartz_surface_get_extents (void *abstract_surface,
}
static const struct _cairo_surface_backend cairo_quartz_surface_backend = {
CAIRO_SURFACE_TYPE_QUARTZ,
NULL, /* create_similar */
_cairo_quartz_surface_finish,
_cairo_quartz_surface_acquire_source_image,
@ -257,7 +259,7 @@ cairo_surface_t *cairo_quartz_surface_create(CGContextRef context,
surface->clip_region = NULL;
surface->flipped = flipped;
// Set up the image surface which Cairo draws into and we blit to & from.
/* Set up the image surface which Cairo draws into and we blit to & from. */
void *foo;
_cairo_quartz_surface_acquire_source_image(surface, &surface->image, &foo);

Просмотреть файл

@ -360,8 +360,8 @@ _cairo_quartzgl_cairo_gradient_pattern_to_quartz (cairo_pattern_t *abspat)
cairo_matrix_t mat;
double x0, y0;
if (abspat->type != CAIRO_PATTERN_LINEAR &&
abspat->type != CAIRO_PATTERN_RADIAL)
if (abspat->type != CAIRO_PATTERN_TYPE_LINEAR &&
abspat->type != CAIRO_PATTERN_TYPE_RADIAL)
return NULL;
/* We can only do this if we have an identity pattern matrix;
@ -376,7 +376,7 @@ _cairo_quartzgl_cairo_gradient_pattern_to_quartz (cairo_pattern_t *abspat)
x0 = mat.x0;
y0 = mat.y0;
if (abspat->type == CAIRO_PATTERN_LINEAR) {
if (abspat->type == CAIRO_PATTERN_TYPE_LINEAR) {
cairo_linear_pattern_t *lpat = (cairo_linear_pattern_t*) abspat;
CGShadingRef shading;
CGPoint start, end;
@ -400,7 +400,7 @@ _cairo_quartzgl_cairo_gradient_pattern_to_quartz (cairo_pattern_t *abspat)
return shading;
}
if (abspat->type == CAIRO_PATTERN_RADIAL) {
if (abspat->type == CAIRO_PATTERN_TYPE_RADIAL) {
cairo_radial_pattern_t *rpat = (cairo_radial_pattern_t*) abspat;
CGShadingRef shading;
CGPoint start, end;
@ -517,7 +517,7 @@ _cairo_quartzgl_cairo_repeating_surface_pattern_to_quartz (cairo_quartzgl_surfac
float rw, rh;
/* SURFACE is the only type we'll handle here */
if (abspat->type != CAIRO_PATTERN_SURFACE)
if (abspat->type != CAIRO_PATTERN_TYPE_SURFACE)
return NULL;
spat = (cairo_surface_pattern_t *) abspat;
@ -596,7 +596,7 @@ _cairo_quartzgl_setup_source (cairo_quartzgl_surface_t *surface,
{
assert (!(surface->sourceImage || surface->sourceShading || surface->sourcePattern));
if (source->type == CAIRO_PATTERN_SOLID) {
if (source->type == CAIRO_PATTERN_TYPE_SOLID) {
cairo_solid_pattern_t *solid = (cairo_solid_pattern_t *) source;
CGContextSetRGBStrokeColor (surface->cgContext,
@ -609,15 +609,15 @@ _cairo_quartzgl_setup_source (cairo_quartzgl_surface_t *surface,
solid->color.green,
solid->color.blue,
solid->color.alpha);
} else if (source->type == CAIRO_PATTERN_LINEAR ||
source->type == CAIRO_PATTERN_RADIAL)
} else if (source->type == CAIRO_PATTERN_TYPE_LINEAR ||
source->type == CAIRO_PATTERN_TYPE_RADIAL)
{
CGShadingRef shading = _cairo_quartzgl_cairo_gradient_pattern_to_quartz (source);
if (!shading)
return CAIRO_INT_STATUS_UNSUPPORTED;
surface->sourceShading = shading;
} else if (source->type == CAIRO_PATTERN_SURFACE) {
} else if (source->type == CAIRO_PATTERN_TYPE_SURFACE) {
CGPatternRef pattern = _cairo_quartzgl_cairo_repeating_surface_pattern_to_quartz (surface, source);
if (!pattern)
return CAIRO_INT_STATUS_UNSUPPORTED;
@ -1413,6 +1413,7 @@ _cairo_quartzgl_surface_intersect_clip_path (void *abstract_surface,
}
static const struct _cairo_surface_backend cairo_quartzgl_surface_backend = {
CAIRO_SURFACE_TYPE_QUARTZ2,
_cairo_quartzgl_surface_create_similar,
_cairo_quartzgl_surface_finish,
_cairo_quartzgl_surface_acquire_source_image,

Просмотреть файл

@ -1,4 +1,4 @@
/* $Id: cairo-scaled-font.c,v 1.6 2006/03/17 07:44:28 vladimir%pobox.com Exp $
/* $Id: cairo-scaled-font.c,v 1.8 2006/04/01 00:36:09 vladimir%pobox.com Exp $
*
* Copyright © 2005 Keith Packard
*
@ -118,6 +118,18 @@ _cairo_scaled_font_set_error (cairo_scaled_font_t *scaled_font,
_cairo_error (status);
}
/**
* cairo_scaled_font_get_type:
* @scaled_font: a #cairo_scaled_font_t
*
* Return value: The type of @scaled_font. See #cairo_font_type_t.
**/
cairo_font_type_t
cairo_scaled_font_get_type (cairo_scaled_font_t *scaled_font)
{
return scaled_font->backend->type;
}
/**
* cairo_scaled_font_status:
* @scaled_font: a #cairo_scaled_font_t

Просмотреть файл

@ -214,21 +214,6 @@ _clip_and_composite_combine (cairo_clip_t *clip,
*/
_cairo_pattern_init_for_surface (&dst_pattern, dst);
/* Set a translation on dst_pattern equivalent to the surface
* device offset, to make sure it's in the right place when
* composited.
*/
if (dst->device_x_offset != 0.0 ||
dst->device_y_offset != 0.0 ||
dst->device_x_scale != 1.0 ||
dst->device_y_scale != 1.0)
{
cairo_matrix_t txmat;
cairo_matrix_init_scale (&txmat, dst->device_x_scale, dst->device_y_scale);
cairo_matrix_translate (&txmat, dst->device_x_offset, dst->device_y_offset);
cairo_pattern_set_matrix ((cairo_pattern_t*) &dst_pattern, &txmat);
}
status = _cairo_surface_composite (CAIRO_OPERATOR_SOURCE,
&dst_pattern.base, NULL, intermediate,
extents->x, extents->y,
@ -564,6 +549,9 @@ _clip_and_composite_trapezoids (cairo_pattern_t *src,
return status;
clear_region = _cairo_region_create_from_rectangle (&extents);
if (clear_region == NULL)
return CAIRO_STATUS_NO_MEMORY;
status = _cairo_clip_intersect_to_region (clip, clear_region);
if (status)
return status;
@ -591,7 +579,7 @@ _clip_and_composite_trapezoids (cairo_pattern_t *src,
{
cairo_surface_t *clip_surface = clip ? clip->surface : NULL;
if ((src->type == CAIRO_PATTERN_SOLID || op == CAIRO_OPERATOR_CLEAR) &&
if ((src->type == CAIRO_PATTERN_TYPE_SOLID || op == CAIRO_OPERATOR_CLEAR) &&
!clip_surface)
{
const cairo_color_t *color;
@ -1000,8 +988,6 @@ _cairo_surface_fallback_snapshot (cairo_surface_t *surface)
snapshot->device_x_offset = surface->device_x_offset;
snapshot->device_y_offset = surface->device_y_offset;
snapshot->device_x_scale = surface->device_x_scale;
snapshot->device_y_scale = surface->device_y_scale;
snapshot->is_snapshot = TRUE;
@ -1141,7 +1127,6 @@ _cairo_surface_fallback_composite_trapezoids (cairo_operator_t op,
fallback_state_t state;
cairo_trapezoid_t *offset_traps = NULL;
cairo_status_t status;
int i;
status = _fallback_init (&state, dst, dst_x, dst_y, width, height);
if (status) {

Просмотреть файл

@ -43,6 +43,7 @@
const cairo_surface_t _cairo_surface_nil = {
&cairo_image_surface_backend, /* backend */
CAIRO_SURFACE_TYPE_IMAGE,
-1, /* ref_count */
CAIRO_STATUS_NO_MEMORY, /* status */
FALSE, /* finished */
@ -59,6 +60,7 @@ const cairo_surface_t _cairo_surface_nil = {
const cairo_surface_t _cairo_surface_nil_file_not_found = {
&cairo_image_surface_backend, /* backend */
CAIRO_SURFACE_TYPE_IMAGE,
-1, /* ref_count */
CAIRO_STATUS_FILE_NOT_FOUND, /* status */
FALSE, /* finished */
@ -75,6 +77,7 @@ const cairo_surface_t _cairo_surface_nil_file_not_found = {
const cairo_surface_t _cairo_surface_nil_read_error = {
&cairo_image_surface_backend, /* backend */
CAIRO_SURFACE_TYPE_IMAGE,
-1, /* ref_count */
CAIRO_STATUS_READ_ERROR, /* status */
FALSE, /* finished */
@ -89,21 +92,13 @@ const cairo_surface_t _cairo_surface_nil_read_error = {
0 /* current_clip_serial */
};
/* N.B.: set_device_offset already transforms the device offsets by the scale
* before storing in device_[xy]_scale
*/
/* Helper macros for transforming surface coords to backend coords */
#define BACKEND_X(_surf, _sx) ((_sx)*((_surf)->device_x_scale)+((_surf)->device_x_offset))
#define BACKEND_Y(_surf, _sy) ((_sy)*((_surf)->device_y_scale)+((_surf)->device_y_offset))
#define BACKEND_X_SIZE(_surf, _sx) ((_sx)*((_surf)->device_x_scale))
#define BACKEND_Y_SIZE(_surf, _sy) ((_sy)*((_surf)->device_y_scale))
#define SURFACE_TO_BACKEND_X(_surf, _sx) ((_sx)+((_surf)->device_x_offset))
#define SURFACE_TO_BACKEND_Y(_surf, _sy) ((_sy)+((_surf)->device_y_offset))
/* Helper macros for transforming backend coords to surface coords */
#define SURFACE_X(_surf, _bx) (((_bx)-((_surf)->device_x_offset))/((_surf)->device_x_scale))
#define SURFACE_Y(_surf, _by) (((_by)-((_surf)->device_y_offset))/((_surf)->device_y_scale))
#define SURFACE_X_SIZE(_surf, _bx) ((_bx)/((_surf)->device_x_scale))
#define SURFACE_Y_SIZE(_surf, _by) ((_by)/((_surf)->device_y_scale))
static void _cairo_surface_copy_pattern_for_destination (const cairo_pattern_t *pattern,
cairo_surface_t *destination,
cairo_pattern_t *pattern_out);
/**
* _cairo_surface_set_error:
@ -134,6 +129,22 @@ _cairo_surface_set_error (cairo_surface_t *surface,
_cairo_error (status);
}
/**
* cairo_surface_get_type:
* @surface: a #cairo_surface_t
*
* Return value: The type of @surface. See #cairo_surface_type_t.
**/
cairo_surface_type_t
cairo_surface_get_type (cairo_surface_t *surface)
{
/* We don't use surface->backend->type here so that some of the
* special "wrapper" surfaces such as cairo_paginated_surface_t
* can override surface->type with the type of the "child"
* surface. */
return surface->type;
}
/**
* cairo_surface_status:
* @surface: a #cairo_surface_t
@ -157,6 +168,8 @@ _cairo_surface_init (cairo_surface_t *surface,
const cairo_surface_backend_t *backend)
{
surface->backend = backend;
surface->type = backend->type;
surface->ref_count = 1;
surface->status = CAIRO_STATUS_SUCCESS;
@ -166,8 +179,6 @@ _cairo_surface_init (cairo_surface_t *surface,
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->clip = NULL;
surface->next_clip_serial = 0;
@ -202,7 +213,8 @@ _cairo_surface_create_similar_scratch (cairo_surface_t *other,
*
* Create a new surface that is as compatible as possible with an
* existing surface. The new surface will use the same backend as
* @other unless that is not possible for some reason.
* @other unless that is not possible for some reason. The type of the
* returned surface may be examined with cairo_surface_get_type().
*
* Return value: a pointer to the newly allocated surface. The caller
* owns the surface and should call cairo_surface_destroy when done
@ -540,9 +552,10 @@ cairo_surface_mark_dirty_rectangle (cairo_surface_t *surface,
return;
}
/* Always reset the clip here, to avoid having a SaveDC/RestoreDC around
* cairo calls that update the surface clip resulting in a desync between
* the cairo clip and the backend clip.
/* Always reset the clip here, to avoid having external calls to
* clip manipulation functions of the underlying device clip result
* in a desync between the cairo clip and the backend clip, due to
* the clip caching.
*/
surface->current_clip_serial = -1;
@ -550,8 +563,8 @@ cairo_surface_mark_dirty_rectangle (cairo_surface_t *surface,
cairo_status_t status;
status = surface->backend->mark_dirty_rectangle (surface,
BACKEND_X(surface, x),
BACKEND_Y(surface, y),
SURFACE_TO_BACKEND_X(surface, x),
SURFACE_TO_BACKEND_Y(surface, y),
width, height);
if (status)
@ -592,8 +605,8 @@ cairo_surface_set_device_offset (cairo_surface_t *surface,
return;
}
surface->device_x_offset = x_offset * surface->device_x_scale;
surface->device_y_offset = y_offset * surface->device_y_scale;
surface->device_x_offset = x_offset;
surface->device_y_offset = y_offset;
}
/**
@ -615,6 +628,13 @@ cairo_surface_get_device_offset (cairo_surface_t *surface,
*y_offset = surface->device_y_offset;
}
cairo_bool_t
_cairo_surface_has_device_offset_or_scale (cairo_surface_t *surface)
{
return (surface->device_x_offset != 0.0 ||
surface->device_y_offset != 0.0);
}
/**
* _cairo_surface_acquire_source_image:
* @surface: a #cairo_surface_t
@ -699,26 +719,11 @@ _cairo_surface_acquire_dest_image (cairo_surface_t *surface,
cairo_rectangle_t *image_rect,
void **image_extra)
{
cairo_rectangle_t dev_interest_rect;
cairo_status_t status;
assert (!surface->finished);
if (interest_rect) {
dev_interest_rect = *interest_rect;
dev_interest_rect.x = BACKEND_X(surface, dev_interest_rect.x);
dev_interest_rect.y = BACKEND_Y(surface, dev_interest_rect.y);
}
status = surface->backend->acquire_dest_image (surface,
interest_rect ? &dev_interest_rect : NULL,
image_out, image_rect, image_extra);
/* move image_rect back into surface coordinates from backend device coordinates */
image_rect->x = SURFACE_X(surface, image_rect->x);
image_rect->y = SURFACE_Y(surface, image_rect->y);
return status;
return surface->backend->acquire_dest_image (surface,
interest_rect,
image_out, image_rect, image_extra);
}
/**
@ -740,22 +745,10 @@ _cairo_surface_release_dest_image (cairo_surface_t *surface,
cairo_rectangle_t *image_rect,
void *image_extra)
{
cairo_rectangle_t dev_interest_rect;
assert (!surface->finished);
/* move image_rect into backend device coords (opposite of acquire_dest_image) */
image_rect->x = BACKEND_X(surface, image_rect->x);
image_rect->y = BACKEND_Y(surface, image_rect->y);
if (interest_rect) {
dev_interest_rect = *interest_rect;
dev_interest_rect.x = BACKEND_X(surface, dev_interest_rect.x);
dev_interest_rect.y = BACKEND_Y(surface, dev_interest_rect.y);
}
if (surface->backend->release_dest_image)
surface->backend->release_dest_image (surface, &dev_interest_rect,
surface->backend->release_dest_image (surface, interest_rect,
image, image_rect, image_extra);
}
@ -794,8 +787,6 @@ _cairo_surface_clone_similar (cairo_surface_t *surface,
if (status == CAIRO_STATUS_SUCCESS) {
(*clone_out)->device_x_offset = src->device_x_offset;
(*clone_out)->device_y_offset = src->device_y_offset;
(*clone_out)->device_x_scale = src->device_x_scale;
(*clone_out)->device_y_scale = src->device_y_scale;
}
if (status != CAIRO_INT_STATUS_UNSUPPORTED)
@ -809,8 +800,6 @@ _cairo_surface_clone_similar (cairo_surface_t *surface,
if (status == CAIRO_STATUS_SUCCESS) {
(*clone_out)->device_x_offset = src->device_x_offset;
(*clone_out)->device_y_offset = src->device_y_offset;
(*clone_out)->device_x_scale = src->device_x_scale;
(*clone_out)->device_y_scale = src->device_y_scale;
}
/* If the above failed point, we could implement a full fallback
@ -884,29 +873,11 @@ _cairo_surface_composite (cairo_operator_t op,
return CAIRO_STATUS_SURFACE_FINISHED;
if (dst->backend->composite) {
int backend_src_x = src_x;
int backend_src_y = src_y;
int backend_mask_x = mask_x;
int backend_mask_y = mask_y;
if (src->type == CAIRO_PATTERN_SURFACE) {
cairo_surface_t *src_surface = ((cairo_surface_pattern_t*)src)->surface;
backend_src_x = BACKEND_X(src_surface, src_x);
backend_src_y = BACKEND_Y(src_surface, src_y);
}
if (mask && mask->type == CAIRO_PATTERN_SURFACE) {
cairo_surface_t *mask_surface = ((cairo_surface_pattern_t*)mask)->surface;
backend_mask_x = BACKEND_X(mask_surface, mask_x);
backend_mask_y = BACKEND_Y(mask_surface, mask_y);
}
status = dst->backend->composite (op,
src, mask, dst,
backend_src_x, backend_src_y,
backend_mask_x, backend_mask_y,
BACKEND_X(dst, dst_x),
BACKEND_Y(dst, dst_y),
src_x, src_y,
mask_x, mask_y,
dst_x, dst_y,
width, height);
if (status != CAIRO_INT_STATUS_UNSUPPORTED)
return status;
@ -1035,8 +1006,6 @@ _cairo_surface_fill_rectangles (cairo_surface_t *surface,
int num_rects)
{
cairo_int_status_t status;
cairo_rectangle_t *dev_rects = NULL;
int i;
assert (! surface->is_snapshot);
@ -1050,26 +1019,8 @@ _cairo_surface_fill_rectangles (cairo_surface_t *surface,
return CAIRO_STATUS_SUCCESS;
if (surface->backend->fill_rectangles) {
if (surface->device_x_offset != 0.0 ||
surface->device_y_offset != 0.0 ||
surface->device_x_scale != 1.0 ||
surface->device_y_scale != 1.0)
{
dev_rects = malloc(sizeof(cairo_rectangle_t) * num_rects);
for (i = 0; i < num_rects; i++) {
dev_rects[i].x = BACKEND_X(surface, rects[i].x);
dev_rects[i].y = BACKEND_Y(surface, rects[i].y);
dev_rects[i].width = BACKEND_X_SIZE(surface, rects[i].width);
dev_rects[i].height = BACKEND_Y_SIZE(surface, rects[i].height);
}
}
status = surface->backend->fill_rectangles (surface,
op,
color,
dev_rects ? dev_rects : rects, num_rects);
free (dev_rects);
status = surface->backend->fill_rectangles (surface, op, color,
rects, num_rects);
if (status != CAIRO_INT_STATUS_UNSUPPORTED)
return status;
}
@ -1084,16 +1035,24 @@ _cairo_surface_paint (cairo_surface_t *surface,
cairo_pattern_t *source)
{
cairo_status_t status;
cairo_pattern_union_t dev_source;
assert (! surface->is_snapshot);
_cairo_surface_copy_pattern_for_destination (source, surface, &dev_source.base);
if (surface->backend->paint) {
status = surface->backend->paint (surface, op, source);
status = surface->backend->paint (surface, op, &dev_source.base);
if (status != CAIRO_INT_STATUS_UNSUPPORTED)
return status;
goto FINISH;
}
return _cairo_surface_fallback_paint (surface, op, source);
status = _cairo_surface_fallback_paint (surface, op, &dev_source.base);
FINISH:
_cairo_pattern_fini (&dev_source.base);
return status;
}
cairo_status_t
@ -1103,16 +1062,27 @@ _cairo_surface_mask (cairo_surface_t *surface,
cairo_pattern_t *mask)
{
cairo_status_t status;
cairo_pattern_union_t dev_source;
cairo_pattern_union_t dev_mask;
assert (! surface->is_snapshot);
_cairo_surface_copy_pattern_for_destination (source, surface, &dev_source.base);
_cairo_surface_copy_pattern_for_destination (mask, surface, &dev_mask.base);
if (surface->backend->mask) {
status = surface->backend->mask (surface, op, source, mask);
status = surface->backend->mask (surface, op, &dev_source.base, &dev_mask.base);
if (status != CAIRO_INT_STATUS_UNSUPPORTED)
return status;
goto FINISH;
}
return _cairo_surface_fallback_mask (surface, op, source, mask);
status = _cairo_surface_fallback_mask (surface, op, &dev_source.base, &dev_mask.base);
FINISH:
_cairo_pattern_fini (&dev_source.base);
_cairo_pattern_fini (&dev_mask.base);
return status;
}
cairo_status_t
@ -1126,43 +1096,45 @@ _cairo_surface_stroke (cairo_surface_t *surface,
double tolerance,
cairo_antialias_t antialias)
{
cairo_status_t status;
cairo_pattern_union_t dev_source;
cairo_path_fixed_t *dev_path = path;
cairo_path_fixed_t real_dev_path;
assert (! surface->is_snapshot);
_cairo_surface_copy_pattern_for_destination (source, surface, &dev_source.base);
if (_cairo_surface_has_device_offset_or_scale (surface))
{
_cairo_path_fixed_init_copy (&real_dev_path, path);
_cairo_path_fixed_offset (&real_dev_path,
_cairo_fixed_from_double (surface->device_x_offset),
_cairo_fixed_from_double (surface->device_y_offset));
dev_path = &real_dev_path;
}
if (surface->backend->stroke) {
cairo_status_t status;
cairo_path_fixed_t *dev_path = path;
cairo_path_fixed_t real_dev_path;
if (surface->device_x_offset != 0.0 ||
surface->device_y_offset != 0.0 ||
surface->device_x_scale != 1.0 ||
surface->device_y_scale != 1.0)
{
_cairo_path_fixed_init_copy (&real_dev_path, path);
_cairo_path_fixed_offset_and_scale (&real_dev_path,
_cairo_fixed_from_double (surface->device_x_offset),
_cairo_fixed_from_double (surface->device_y_offset),
_cairo_fixed_from_double (surface->device_x_scale),
_cairo_fixed_from_double (surface->device_y_scale));
dev_path = &real_dev_path;
}
status = surface->backend->stroke (surface, op, source,
status = surface->backend->stroke (surface, op, &dev_source.base,
dev_path, stroke_style,
ctm, ctm_inverse,
tolerance, antialias);
if (dev_path == &real_dev_path)
_cairo_path_fixed_fini (&real_dev_path);
if (status != CAIRO_INT_STATUS_UNSUPPORTED)
return status;
goto FINISH;
}
return _cairo_surface_fallback_stroke (surface, op, source,
path, stroke_style,
ctm, ctm_inverse,
tolerance, antialias);
status = _cairo_surface_fallback_stroke (surface, op, &dev_source.base,
dev_path, stroke_style,
ctm, ctm_inverse,
tolerance, antialias);
FINISH:
if (dev_path == &real_dev_path)
_cairo_path_fixed_fini (&real_dev_path);
_cairo_pattern_fini (&dev_source.base);
return status;
}
cairo_status_t
@ -1175,40 +1147,42 @@ _cairo_surface_fill (cairo_surface_t *surface,
cairo_antialias_t antialias)
{
cairo_status_t status;
cairo_pattern_union_t dev_source;
cairo_path_fixed_t *dev_path = path;
cairo_path_fixed_t real_dev_path;
assert (! surface->is_snapshot);
if (surface->backend->fill) {
if (surface->device_x_offset != 0.0 ||
surface->device_y_offset != 0.0 ||
surface->device_x_scale != 1.0 ||
surface->device_y_scale != 1.0)
{
_cairo_path_fixed_init_copy (&real_dev_path, path);
_cairo_path_fixed_offset_and_scale (&real_dev_path,
_cairo_fixed_from_double (surface->device_x_offset),
_cairo_fixed_from_double (surface->device_y_offset),
_cairo_fixed_from_double (surface->device_x_scale),
_cairo_fixed_from_double (surface->device_y_scale));
dev_path = &real_dev_path;
}
_cairo_surface_copy_pattern_for_destination (source, surface, &dev_source.base);
status = surface->backend->fill (surface, op, source,
if (_cairo_surface_has_device_offset_or_scale (surface))
{
_cairo_path_fixed_init_copy (&real_dev_path, path);
_cairo_path_fixed_offset (&real_dev_path,
_cairo_fixed_from_double (surface->device_x_offset),
_cairo_fixed_from_double (surface->device_y_offset));
dev_path = &real_dev_path;
}
if (surface->backend->fill) {
status = surface->backend->fill (surface, op, &dev_source.base,
dev_path, fill_rule,
tolerance, antialias);
if (dev_path == &real_dev_path)
_cairo_path_fixed_fini (&real_dev_path);
if (status != CAIRO_INT_STATUS_UNSUPPORTED)
return status;
goto FINISH;
}
return _cairo_surface_fallback_fill (surface, op, source,
path, fill_rule,
tolerance, antialias);
status = _cairo_surface_fallback_fill (surface, op, &dev_source.base,
dev_path, fill_rule,
tolerance, antialias);
FINISH:
if (dev_path == &real_dev_path)
_cairo_path_fixed_fini (&real_dev_path);
_cairo_pattern_fini (&dev_source.base);
return status;
}
cairo_status_t
@ -1226,7 +1200,6 @@ _cairo_surface_composite_trapezoids (cairo_operator_t op,
int num_traps)
{
cairo_int_status_t status;
cairo_trapezoid_t *dev_traps = NULL;
assert (! dst->is_snapshot);
@ -1242,36 +1215,13 @@ _cairo_surface_composite_trapezoids (cairo_operator_t op,
return CAIRO_STATUS_SURFACE_FINISHED;
if (dst->backend->composite_trapezoids) {
if (dst->device_x_offset != 0.0 ||
dst->device_y_offset != 0.0 ||
dst->device_x_scale != 1.0 ||
dst->device_y_scale != 1.0)
{
dev_traps = malloc (sizeof (cairo_trapezoid_t) * num_traps);
if (!dev_traps)
return CAIRO_STATUS_NO_MEMORY;
_cairo_trapezoid_array_translate_and_scale
(dev_traps, traps, num_traps,
dst->device_x_offset,
dst->device_y_offset,
dst->device_x_scale,
dst->device_y_scale);
}
status = dst->backend->composite_trapezoids (op,
pattern, dst,
antialias,
src_x, src_y,
BACKEND_X(dst, dst_x),
BACKEND_Y(dst, dst_y),
// XXX what the heck do I do with width/height?
// they're not the same for src and dst!
dst_x, dst_y,
width, height,
dev_traps ? dev_traps : traps, num_traps);
free (dev_traps);
traps, num_traps);
if (status != CAIRO_INT_STATUS_UNSUPPORTED)
return status;
}
@ -1418,7 +1368,6 @@ _cairo_surface_set_clip_region (cairo_surface_t *surface,
pixman_region16_t *region,
unsigned int serial)
{
pixman_region16_t *dev_region = NULL;
cairo_status_t status;
if (surface->status)
@ -1429,48 +1378,10 @@ _cairo_surface_set_clip_region (cairo_surface_t *surface,
assert (surface->backend->set_clip_region != NULL);
if (surface->device_x_offset != 0.0 ||
surface->device_y_offset != 0.0 ||
surface->device_x_scale != 1.0 ||
surface->device_y_scale != 1.0)
{
dev_region = pixman_region_create ();
if (surface->device_x_scale == 1.0 &&
surface->device_y_scale == 1.0)
{
pixman_region_copy (dev_region, region);
pixman_region_translate (dev_region, surface->device_x_offset, surface->device_y_offset);
} else {
int i, nr = pixman_region_num_rects (region);
pixman_box16_t *rects = pixman_region_rects (region);
for (i = 0; i < nr; i++) {
pixman_box16_t tmpb;
pixman_region16_t *tmpr;
tmpb.x1 = BACKEND_X(surface, rects[i].x1);
tmpb.y1 = BACKEND_Y(surface, rects[i].y1);
tmpb.x2 = BACKEND_X(surface, rects[i].x2);
tmpb.y2 = BACKEND_Y(surface, rects[i].y2);
tmpr = pixman_region_create_simple (&tmpb);
pixman_region_append (dev_region, tmpr);
pixman_region_destroy (tmpr);
}
pixman_region_validate (dev_region, &i);
}
region = dev_region;
}
surface->current_clip_serial = serial;
status = surface->backend->set_clip_region (surface, region);
if (dev_region)
pixman_region_destroy (dev_region);
return status;
}
@ -1482,7 +1393,6 @@ _cairo_surface_intersect_clip_path (cairo_surface_t *surface,
cairo_antialias_t antialias)
{
cairo_path_fixed_t *dev_path = path;
cairo_path_fixed_t real_dev_path;
cairo_status_t status;
if (surface->status)
@ -1493,29 +1403,12 @@ _cairo_surface_intersect_clip_path (cairo_surface_t *surface,
assert (surface->backend->intersect_clip_path != NULL);
if (surface->device_x_offset != 0.0 ||
surface->device_y_offset != 0.0 ||
surface->device_x_scale != 1.0 ||
surface->device_y_scale != 1.0)
{
_cairo_path_fixed_init_copy (&real_dev_path, path);
_cairo_path_fixed_offset_and_scale (&real_dev_path,
_cairo_fixed_from_double (surface->device_x_offset),
_cairo_fixed_from_double (surface->device_y_offset),
_cairo_fixed_from_double (surface->device_x_scale),
_cairo_fixed_from_double (surface->device_y_scale));
dev_path = &real_dev_path;
}
status = surface->backend->intersect_clip_path (surface,
dev_path,
fill_rule,
tolerance,
antialias);
if (dev_path == &real_dev_path)
_cairo_path_fixed_fini (&real_dev_path);
return status;
}
@ -1649,8 +1542,10 @@ _cairo_surface_get_extents (cairo_surface_t *surface,
status = surface->backend->get_extents (surface, rectangle);
rectangle->x = SURFACE_X(surface, rectangle->x);
rectangle->y = SURFACE_Y(surface, rectangle->y);
rectangle->x = SURFACE_TO_BACKEND_X(surface, rectangle->x);
rectangle->y = SURFACE_TO_BACKEND_Y(surface, rectangle->y);
rectangle->width = rectangle->width - surface->device_x_offset;
rectangle->height = rectangle->height - surface->device_y_offset;
return status;
}
@ -1664,41 +1559,48 @@ _cairo_surface_show_glyphs (cairo_surface_t *surface,
cairo_scaled_font_t *scaled_font)
{
cairo_status_t status;
cairo_glyph_t *dev_glyphs = NULL;
cairo_glyph_t *dev_glyphs = (cairo_glyph_t*) glyphs;
cairo_pattern_union_t dev_source;
assert (! surface->is_snapshot);
if (surface->backend->show_glyphs) {
if (surface->device_x_offset != 0.0 ||
surface->device_y_offset != 0.0 ||
surface->device_x_scale != 1.0 ||
surface->device_y_scale != 1.0)
{
int i;
_cairo_surface_copy_pattern_for_destination (source,
surface,
&dev_source.base);
dev_glyphs = malloc (sizeof(cairo_glyph_t) * num_glyphs);
if (!dev_glyphs)
return CAIRO_STATUS_NO_MEMORY;
if (_cairo_surface_has_device_offset_or_scale (surface))
{
int i;
for (i = 0; i < num_glyphs; i++) {
dev_glyphs[i].index = glyphs[i].index;
// err, we really should scale the size of the glyphs, no?
dev_glyphs[i].x = BACKEND_X(surface, glyphs[i].x);
dev_glyphs[i].y = BACKEND_Y(surface, glyphs[i].y);
}
dev_glyphs = malloc (sizeof(cairo_glyph_t) * num_glyphs);
if (!dev_glyphs)
return CAIRO_STATUS_NO_MEMORY;
for (i = 0; i < num_glyphs; i++) {
dev_glyphs[i].index = glyphs[i].index;
/* XXX: err, we really should scale the size of the glyphs, no? */
dev_glyphs[i].x = SURFACE_TO_BACKEND_X(surface, glyphs[i].x);
dev_glyphs[i].y = SURFACE_TO_BACKEND_Y(surface, glyphs[i].y);
}
status = surface->backend->show_glyphs (surface, op, source,
dev_glyphs ? dev_glyphs : glyphs,
num_glyphs, scaled_font);
free (dev_glyphs);
if (status != CAIRO_INT_STATUS_UNSUPPORTED)
return status;
}
return _cairo_surface_fallback_show_glyphs (surface, op, source,
glyphs, num_glyphs,
scaled_font);
if (surface->backend->show_glyphs) {
status = surface->backend->show_glyphs (surface, op, &dev_source.base,
dev_glyphs, num_glyphs,
scaled_font);
if (status != CAIRO_INT_STATUS_UNSUPPORTED)
goto FINISH;
}
status = _cairo_surface_fallback_show_glyphs (surface, op, &dev_source.base,
dev_glyphs, num_glyphs,
scaled_font);
FINISH:
if (dev_glyphs != glyphs)
free (dev_glyphs);
return status;
}
/* XXX: Previously, we had a function named _cairo_surface_show_glyphs
@ -1721,7 +1623,6 @@ _cairo_surface_old_show_glyphs (cairo_scaled_font_t *scaled_font,
int num_glyphs)
{
cairo_status_t status;
cairo_glyph_t *dev_glyphs = NULL;
assert (! dst->is_snapshot);
@ -1731,35 +1632,14 @@ _cairo_surface_old_show_glyphs (cairo_scaled_font_t *scaled_font,
if (dst->finished)
return CAIRO_STATUS_SURFACE_FINISHED;
if (dst->backend->old_show_glyphs) {
if (dst->device_x_offset != 0.0 ||
dst->device_y_offset != 0.0 ||
dst->device_x_scale != 1.0 ||
dst->device_y_scale != 1.0)
{
int i;
dev_glyphs = malloc(sizeof(cairo_glyph_t) * num_glyphs);
for (i = 0; i < num_glyphs; i++) {
dev_glyphs[i] = glyphs[i];
// err, we really should scale the size of the glyphs, no?
dev_glyphs[i].x = BACKEND_X(dst, dev_glyphs[i].x);
dev_glyphs[i].y = BACKEND_Y(dst, dev_glyphs[i].y);
}
glyphs = dev_glyphs;
}
if (dst->backend->old_show_glyphs)
status = dst->backend->old_show_glyphs (scaled_font,
op, pattern, dst,
source_x, source_y,
BACKEND_X(dst, dest_x),
BACKEND_Y(dst, dest_y),
dest_x, dest_y,
width, height,
glyphs, num_glyphs);
free (dev_glyphs);
} else
else
status = CAIRO_INT_STATUS_UNSUPPORTED;
return status;
@ -1869,15 +1749,7 @@ _cairo_surface_composite_fixup_unbounded (cairo_surface_t *dst,
cairo_rectangle_t *mask_rectangle = NULL;
assert (! dst->is_snapshot);
/* This is a little odd; this function is called from the xlib/image surfaces,
* where the coordinates have already been transformed by the device_xy_offset.
* We need to undo this before running through this function,
* otherwise those offsets get applied twice.
*/
dst_x = SURFACE_X(dst, dst_x);
dst_y = SURFACE_Y(dst, dst_y);
/* The RENDER/libpixman operators are clipped to the bounds of the untransformed,
* non-repeating sources and masks. Other sources and masks can be ignored.
*/
@ -1952,10 +1824,6 @@ _cairo_surface_composite_shape_fixup_unbounded (cairo_surface_t *dst,
cairo_rectangle_t *mask_rectangle = NULL;
assert (! dst->is_snapshot);
/* See comment at start of _cairo_surface_composite_fixup_unbounded */
dst_x = SURFACE_X(dst, dst_x);
dst_y = SURFACE_Y(dst, dst_y);
/* The RENDER/libpixman operators are clipped to the bounds of the untransformed,
* non-repeating sources and masks. Other sources and masks can be ignored.
@ -1981,3 +1849,29 @@ _cairo_surface_composite_shape_fixup_unbounded (cairo_surface_t *dst,
return _cairo_surface_composite_fixup_unbounded_internal (dst, src_rectangle, mask_rectangle,
dst_x, dst_y, width, height);
}
/**
* _cairo_surface_copy_pattern_for_destination
* @pattern: the pattern to copy
* @destination: the destination surface for which the pattern is being copied
* @pattern_out: the location to hold the copy
*
* Copies the given pattern, taking into account device scale and offsets
* of the destination surface.
*/
void
_cairo_surface_copy_pattern_for_destination (const cairo_pattern_t *pattern,
cairo_surface_t *destination,
cairo_pattern_t *pattern_out)
{
_cairo_pattern_init_copy (pattern_out, pattern);
if (_cairo_surface_has_device_offset_or_scale (destination)) {
cairo_matrix_t device_to_surface;
cairo_matrix_init_translate (&device_to_surface,
- destination->device_x_offset,
- destination->device_y_offset);
_cairo_pattern_transform (pattern_out, &device_to_surface);
}
}

Просмотреть файл

@ -74,6 +74,7 @@ struct cairo_svg_document {
unsigned int pattern_id;
unsigned int filter_id;
unsigned int clip_id;
unsigned int mask_id;
};
struct cairo_svg_surface {
@ -87,8 +88,12 @@ struct cairo_svg_surface {
cairo_svg_document_t *document;
xmlNodePtr xml_node;
xmlNodePtr xml_root_node;
unsigned int clip_level;
cairo_bool_t modified;
unsigned int previous_id;
};
static cairo_svg_document_t *
@ -208,15 +213,16 @@ _cairo_svg_surface_create_for_document (cairo_svg_document_t *document,
_cairo_dtostr (buffer, sizeof buffer, height);
xmlSetProp (clip_rect, CC2XML ("height"), C2XML (buffer));
surface->xml_node = xmlNewChild (surface->id == 0 ?
document->xml_node_main :
document->xml_node_defs,
NULL, CC2XML ("g"), NULL);
surface->xml_node = xmlNewNode (NULL, CC2XML ("g"));
surface->xml_root_node = surface->xml_node;
snprintf (buffer, sizeof buffer, "surface%d", surface->id);
xmlSetProp (surface->xml_node, CC2XML ("id"), C2XML (buffer));
snprintf (buffer, sizeof buffer, "url(#clip%d)", clip_id);
xmlSetProp (surface->xml_node, CC2XML ("clip-path"), C2XML (buffer));
surface->modified = TRUE;
surface->previous_id = surface->id;
return &surface->base;
}
@ -239,14 +245,19 @@ _cairo_svg_surface_finish (void *abstract_surface)
cairo_status_t status;
cairo_svg_surface_t *surface = abstract_surface;
cairo_svg_document_t *document = surface->document;
if (document->owner == &surface->base)
if (document->owner == &surface->base) {
xmlAddChild (document->xml_node_main, xmlCopyNode (surface->xml_root_node, 1));
status = _cairo_svg_document_finish (document);
else
} else
status = CAIRO_STATUS_SUCCESS;
_cairo_svg_document_destroy (document);
xmlFreeNode (surface->xml_root_node);
surface->xml_node = NULL;
return status;
}
@ -262,22 +273,22 @@ emit_transform (xmlNodePtr node,
xmlBufferCat (matrix_buffer, CC2XML ("matrix("));
_cairo_dtostr (buffer, sizeof buffer, matrix->xx);
xmlBufferCat (matrix_buffer, C2XML (buffer));
xmlBufferCat (matrix_buffer, ",");
xmlBufferCat (matrix_buffer, CC2XML (","));
_cairo_dtostr (buffer, sizeof buffer, matrix->yx);
xmlBufferCat (matrix_buffer, C2XML (buffer));
xmlBufferCat (matrix_buffer, ",");
xmlBufferCat (matrix_buffer, CC2XML (","));
_cairo_dtostr (buffer, sizeof buffer, matrix->xy);
xmlBufferCat (matrix_buffer, C2XML (buffer));
xmlBufferCat (matrix_buffer, ",");
xmlBufferCat (matrix_buffer, CC2XML (","));
_cairo_dtostr (buffer, sizeof buffer, matrix->yy);
xmlBufferCat (matrix_buffer, C2XML (buffer));
xmlBufferCat (matrix_buffer, ",");
xmlBufferCat (matrix_buffer, CC2XML (","));
_cairo_dtostr (buffer, sizeof buffer, matrix->x0);
xmlBufferCat (matrix_buffer, C2XML (buffer));
xmlBufferCat (matrix_buffer, ",");
xmlBufferCat (matrix_buffer, CC2XML(","));
_cairo_dtostr (buffer, sizeof buffer, matrix->y0);
xmlBufferCat (matrix_buffer, C2XML (buffer));
xmlBufferCat (matrix_buffer, ")");
xmlBufferCat (matrix_buffer, CC2XML (")"));
xmlSetProp (node, CC2XML (attribute_str), C2XML (xmlBufferContent (matrix_buffer)));
xmlBufferFree (matrix_buffer);
}
@ -291,7 +302,7 @@ typedef struct {
unsigned int trailing;
} base64_write_closure_t;
static unsigned char const *base64_table =
static char const *base64_table =
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
static cairo_status_t
@ -324,7 +335,7 @@ base64_write_func (void *closure,
info->count++;
if (info->count >= 18) {
info->count = 0;
xmlBufferCat (info->buffer, "\r\n");
xmlBufferCat (info->buffer, CC2XML ("\r\n"));
}
dst[0] = base64_table[src[0] >> 2];
dst[1] = base64_table[(src[0] & 0x03) << 4 | src[1] >> 4];
@ -392,7 +403,7 @@ _cairo_surface_base64_encode (cairo_surface_t *surface,
return CAIRO_STATUS_SUCCESS;
}
static cairo_int_status_t
static xmlNodePtr
emit_composite_image_pattern (xmlNodePtr node,
cairo_surface_pattern_t *pattern,
double *width,
@ -410,11 +421,11 @@ emit_composite_image_pattern (xmlNodePtr node,
status = _cairo_surface_acquire_source_image (surface, &image, &image_extra);
if (status)
return status;
return NULL;
status = _cairo_surface_base64_encode (surface, &image_buffer);
if (status)
return status;
return NULL;
child = xmlNewChild (node, NULL, CC2XML ("image"), NULL);
_cairo_dtostr (buffer, sizeof buffer, image->width);
@ -438,10 +449,10 @@ emit_composite_image_pattern (xmlNodePtr node,
_cairo_surface_release_source_image (pattern->surface, image, image_extra);
return status;
return child;
}
static cairo_int_status_t
static xmlNodePtr
emit_composite_svg_pattern (xmlNodePtr node,
cairo_surface_pattern_t *pattern,
double *width,
@ -449,16 +460,16 @@ emit_composite_svg_pattern (xmlNodePtr node,
cairo_bool_t is_pattern)
{
cairo_svg_surface_t *surface = (cairo_svg_surface_t *) pattern->surface;
cairo_svg_document_t *document = surface->document;
cairo_matrix_t p2u;
xmlNodePtr child;
char buffer[CAIRO_SVG_DTOSTR_BUFFER_LEN];
/* FIXME: self copy is not supported yet */
if (surface->id == 0)
return CAIRO_STATUS_SUCCESS;
if (surface->modified)
xmlAddChild (document->xml_node_defs, xmlCopyNode (surface->xml_root_node, 1));
child = xmlNewChild (node, NULL, CC2XML("use"), NULL);
snprintf (buffer, sizeof buffer, "#surface%d", surface->id);
snprintf (buffer, sizeof buffer, "#surface%d", surface->previous_id);
xmlSetProp (child, CC2XML ("xlink:href"), C2XML (buffer));
if (!is_pattern) {
@ -472,10 +483,18 @@ emit_composite_svg_pattern (xmlNodePtr node,
if (height != NULL)
*height = surface->height;
return CAIRO_STATUS_SUCCESS;
if (surface->modified) {
surface->modified = FALSE;
surface->previous_id = surface->id;
surface->id = document->surface_id++;
snprintf (buffer, sizeof buffer, "surface%d", surface->id);
xmlSetProp (surface->xml_root_node, CC2XML ("id"), C2XML (buffer));
}
return child;
}
static cairo_int_status_t
static xmlNodePtr
emit_composite_pattern (xmlNodePtr node,
cairo_surface_pattern_t *pattern,
double *width,
@ -488,69 +507,27 @@ emit_composite_pattern (xmlNodePtr node,
return emit_composite_image_pattern (node, pattern, width, height, is_pattern);
}
static cairo_int_status_t
_cairo_svg_surface_composite (cairo_operator_t op,
cairo_pattern_t *src_pattern,
cairo_pattern_t *mask_pattern,
void *abstract_dst,
int src_x,
int src_y,
int mask_x,
int mask_y,
int dst_x,
int dst_y,
unsigned int width,
unsigned int height)
{
cairo_svg_surface_t *dst = abstract_dst;
cairo_surface_pattern_t *src = (cairo_surface_pattern_t *) src_pattern;
if (mask_pattern)
return CAIRO_STATUS_SUCCESS;
if (src_pattern->type != CAIRO_PATTERN_SURFACE)
return CAIRO_STATUS_SUCCESS;
return emit_composite_pattern (dst->xml_node, src, NULL, NULL, FALSE);
}
/* FIXME: Here we use a SVG 1.2 feature. We should probably have
* an API to limit output SVG version, and fallback to image when
* necessary. */
static void
emit_operator (cairo_operator_t op, cairo_svg_surface_t *surface,
xmlBufferPtr style)
emit_operator (xmlNodePtr node, cairo_operator_t op)
{
char const *op_str[] = {
NULL,
NULL, NULL, "in", "out", "atop",
NULL, NULL, NULL, NULL, NULL,
"xor", NULL, NULL };
cairo_svg_document_t *document = surface->document;
xmlNodePtr child, primitive;
xmlBufferPtr id;
char buffer[CAIRO_SVG_DTOSTR_BUFFER_LEN];
"clear",
"src", "src-over", "src-in",
"src-out", "src-atop",
"dst", "dst-over", "dst-in",
"dst-out", "dst-atop",
"xor", "plus",
"color-dodge" /* FIXME: saturate ? */
};
if (op_str[op] == NULL)
return;
child = xmlNewChild (document->xml_node_defs, NULL, CC2XML ("filter"), NULL);
primitive = xmlNewChild (child, NULL, CC2XML ("feComposite"), NULL);
xmlSetProp (primitive, CC2XML ("operator"), CC2XML (op_str[op]));
xmlSetProp (primitive, CC2XML ("in"), CC2XML ("SourceGraphic"));
xmlSetProp (primitive, CC2XML ("in2"), CC2XML ("BackgroundImage"));
id = xmlBufferCreate ();
xmlBufferCat (id, CC2XML ("filter"));
snprintf (buffer, sizeof buffer, "%d", document->filter_id);
xmlBufferCat (id, C2XML (buffer));
xmlSetProp (child, CC2XML ("id"), C2XML (xmlBufferContent (id)));
xmlBufferCat (style, CC2XML ("filter: url(#"));
xmlBufferCat (style, xmlBufferContent (id));
xmlBufferCat (style, CC2XML (");"));
xmlBufferFree (id);
document->filter_id++;
xmlSetProp (node, CC2XML ("comp-op"), C2XML (op_str[op]));
}
static void
@ -803,19 +780,19 @@ emit_pattern (cairo_svg_surface_t *surface, cairo_pattern_t *pattern,
xmlBufferPtr style, int is_stroke)
{
switch (pattern->type) {
case CAIRO_PATTERN_SOLID:
case CAIRO_PATTERN_TYPE_SOLID:
emit_solid_pattern (surface, (cairo_solid_pattern_t *) pattern, style, is_stroke);
break;
case CAIRO_PATTERN_SURFACE:
case CAIRO_PATTERN_TYPE_SURFACE:
emit_surface_pattern (surface, (cairo_surface_pattern_t *) pattern, style, is_stroke);
break;
case CAIRO_PATTERN_LINEAR:
case CAIRO_PATTERN_TYPE_LINEAR:
emit_linear_pattern (surface, (cairo_linear_pattern_t *) pattern, style, is_stroke);
break;
case CAIRO_PATTERN_RADIAL:
case CAIRO_PATTERN_TYPE_RADIAL:
emit_radial_pattern (surface, (cairo_radial_pattern_t *) pattern, style, is_stroke);
break;
}
@ -828,7 +805,7 @@ typedef struct
xmlBufferPtr path;
} svg_path_info_t;
static cairo_status_t
static cairo_status_t
_cairo_svg_path_move_to (void *closure, cairo_point_t *point)
{
svg_path_info_t *info = closure;
@ -917,42 +894,6 @@ _cairo_svg_path_close_path (void *closure)
return CAIRO_STATUS_SUCCESS;
}
static cairo_int_status_t
_cairo_svg_surface_fill_rectangles (void *abstract_surface,
cairo_operator_t op,
const cairo_color_t *color,
cairo_rectangle_t *rects,
int num_rects)
{
cairo_svg_surface_t *surface = abstract_surface;
xmlNodePtr child;
xmlBufferPtr style;
char buffer[CAIRO_SVG_DTOSTR_BUFFER_LEN];
int i;
style = xmlBufferCreate ();
emit_color (color, style, "fill", "opacity");
xmlBufferCat (style, " stroke: none;");
emit_operator (op, surface, style);
for (i = 0; i < num_rects; i++) {
child = xmlNewChild (surface->xml_node, NULL, CC2XML ("rect"), NULL);
_cairo_dtostr (buffer, sizeof buffer, rects[i].x);
xmlSetProp (child, CC2XML ("x"), C2XML (buffer));
_cairo_dtostr (buffer, sizeof buffer, rects[i].y);
xmlSetProp (child, CC2XML ("y"), C2XML (buffer));
_cairo_dtostr (buffer, sizeof buffer, rects[i].width);
xmlSetProp (child, CC2XML ("width"), C2XML (buffer));
_cairo_dtostr (buffer, sizeof buffer, rects[i].height);
xmlSetProp (child, CC2XML ("height"), C2XML (buffer));
xmlSetProp (child, CC2XML ("style"), xmlBufferContent (style));
}
xmlBufferFree (style);
return CAIRO_STATUS_SUCCESS;
}
static cairo_int_status_t
_cairo_svg_surface_fill (void *abstract_surface,
cairo_operator_t op,
@ -975,10 +916,9 @@ _cairo_svg_surface_fill (void *abstract_surface,
style = xmlBufferCreate ();
emit_pattern (surface, source, style, 0);
xmlBufferCat (style, " stroke: none;");
xmlBufferCat (style, " fill-rule: ");
xmlBufferCat (style, fill_rule == CAIRO_FILL_RULE_EVEN_ODD ? "evenodd;" : "nonzero;");
emit_operator (op, surface, style);
xmlBufferCat (style, CC2XML (" stroke: none;"));
xmlBufferCat (style, CC2XML (" fill-rule: "));
xmlBufferCat (style, fill_rule == CAIRO_FILL_RULE_EVEN_ODD ? CC2XML("evenodd;") : CC2XML ("nonzero;"));
status = _cairo_path_fixed_interpret (path,
CAIRO_DIRECTION_FORWARD,
@ -991,98 +931,15 @@ _cairo_svg_surface_fill (void *abstract_surface,
child = xmlNewChild (surface->xml_node, NULL, CC2XML ("path"), NULL);
xmlSetProp (child, CC2XML ("d"), xmlBufferContent (info.path));
xmlSetProp (child, CC2XML ("style"), xmlBufferContent (style));
emit_operator (child, op);
xmlBufferFree (info.path);
xmlBufferFree (style);
surface->modified = TRUE;
return status;
}
static double
intersect (cairo_line_t *line, cairo_fixed_t y)
{
return _cairo_fixed_to_double (line->p1.x) +
_cairo_fixed_to_double (line->p2.x - line->p1.x) *
_cairo_fixed_to_double (y - line->p1.y) /
_cairo_fixed_to_double (line->p2.y - line->p1.y);
}
static cairo_int_status_t
_cairo_svg_surface_composite_trapezoids (cairo_operator_t op,
cairo_pattern_t *pattern,
void *abstract_dst,
cairo_antialias_t antialias,
int x_src,
int y_src,
int x_dst,
int y_dst,
unsigned int width,
unsigned int height,
cairo_trapezoid_t *traps,
int num_traps)
{
cairo_svg_surface_t *surface = abstract_dst;
xmlBufferPtr style, path;
xmlNodePtr child;
double left_x1, left_x2, right_x1, right_x2;
char buffer[CAIRO_SVG_DTOSTR_BUFFER_LEN];
int i;
style = xmlBufferCreate ();
emit_pattern (surface, pattern, style, 0);
xmlBufferCat (style, "stroke: none;");
path = xmlBufferCreate ();
for (i = 0; i < num_traps; i++) {
left_x1 = intersect (&traps[i].left, traps[i].top);
left_x2 = intersect (&traps[i].left, traps[i].bottom);
right_x1 = intersect (&traps[i].right, traps[i].top);
right_x2 = intersect (&traps[i].right, traps[i].bottom);
xmlBufferCat (path, CC2XML ("M "));
_cairo_dtostr (buffer, sizeof buffer, left_x1);
xmlBufferCat (path, CC2XML (buffer));
xmlBufferCat (path, CC2XML (" "));
_cairo_dtostr (buffer, sizeof buffer,
_cairo_fixed_to_double (traps[i].top));
xmlBufferCat (path, CC2XML (buffer));
xmlBufferCat (path, CC2XML (" L "));
_cairo_dtostr (buffer, sizeof buffer, left_x2);
xmlBufferCat (path, CC2XML (buffer));
xmlBufferCat (path, CC2XML (" "));
_cairo_dtostr (buffer, sizeof buffer,
_cairo_fixed_to_double (traps[i].bottom));
xmlBufferCat (path, CC2XML (buffer));
xmlBufferCat (path, CC2XML (" L "));
_cairo_dtostr (buffer, sizeof buffer, right_x2);
xmlBufferCat (path, CC2XML (buffer));
xmlBufferCat (path, CC2XML (" "));
_cairo_dtostr (buffer, sizeof buffer,
_cairo_fixed_to_double (traps[i].bottom));
xmlBufferCat (path, CC2XML (buffer));
xmlBufferCat (path, CC2XML (" L "));
_cairo_dtostr (buffer, sizeof buffer, right_x1);
xmlBufferCat (path, CC2XML (buffer));
xmlBufferCat (path, CC2XML (" "));
_cairo_dtostr (buffer, sizeof buffer,
_cairo_fixed_to_double (traps[i].top));
xmlBufferCat (path, CC2XML (buffer));
xmlBufferCat (path, CC2XML (" Z"));
}
child = xmlNewChild (surface->xml_node, NULL, CC2XML ("path"), NULL);
xmlSetProp (child, CC2XML ("d"), xmlBufferContent (path));
xmlSetProp (child, CC2XML ("style"), xmlBufferContent (style));
xmlBufferFree (path);
xmlBufferFree (style);
return CAIRO_STATUS_SUCCESS;
}
static cairo_int_status_t
_cairo_svg_surface_get_extents (void *abstract_surface,
cairo_rectangle_t *rectangle)
@ -1102,26 +959,26 @@ _cairo_svg_surface_get_extents (void *abstract_surface,
return CAIRO_STATUS_SUCCESS;
}
/* First attempt of paint implementation, but obviously I didn't
* understand how it's supposed to work */
#if 0
static cairo_int_status_t
_cairo_svg_surface_paint (void *abstract_surface,
cairo_operator_t op,
cairo_pattern_t *source)
static xmlNodePtr
emit_paint (xmlNodePtr node,
cairo_svg_surface_t *surface,
cairo_operator_t op,
cairo_pattern_t *source)
{
cairo_svg_surface_t *surface = abstract_surface;
xmlNodePtr child;
xmlBufferPtr style;
char buffer[CAIRO_SVG_DTOSTR_BUFFER_LEN];
if (source->type == CAIRO_PATTERN_TYPE_SURFACE)
return emit_composite_pattern (node,
(cairo_surface_pattern_t *) source,
NULL, NULL, FALSE);
style = xmlBufferCreate ();
emit_pattern (surface, source, style, 0);
xmlBufferCat (style, " stroke: none;");
emit_operator (op, surface, style);
xmlBufferCat (style, CC2XML (" stroke: none;"));
child = xmlNewChild (surface->xml_node, NULL, CC2XML ("rect"), NULL);
child = xmlNewChild (node, NULL, CC2XML ("rect"), NULL);
xmlSetProp (child, CC2XML ("x"), CC2XML ("0"));
xmlSetProp (child, CC2XML ("y"), CC2XML ("0"));
_cairo_dtostr (buffer, sizeof buffer, surface->width);
@ -1129,12 +986,54 @@ _cairo_svg_surface_paint (void *abstract_surface,
_cairo_dtostr (buffer, sizeof buffer, surface->height);
xmlSetProp (child, CC2XML ("height"), C2XML (buffer));
xmlSetProp (child, CC2XML ("style"), xmlBufferContent (style));
emit_operator (child, op);
xmlBufferFree (style);
return child;
}
static cairo_int_status_t
_cairo_svg_surface_paint (void *abstract_surface,
cairo_operator_t op,
cairo_pattern_t *source)
{
cairo_svg_surface_t *surface = abstract_surface;
emit_paint (surface->xml_node, surface, op, source);
surface->modified = TRUE;
return CAIRO_STATUS_SUCCESS;
}
static cairo_int_status_t
_cairo_svg_surface_mask (void *abstract_surface,
cairo_operator_t op,
cairo_pattern_t *source,
cairo_pattern_t *mask)
{
cairo_svg_surface_t *surface = abstract_surface;
cairo_svg_document_t *document = surface->document;
xmlNodePtr child, mask_node;
char buffer[CAIRO_SVG_DTOSTR_BUFFER_LEN];
mask_node = xmlNewChild (document->xml_node_defs, NULL, CC2XML ("mask"), NULL);
snprintf (buffer, sizeof buffer, "mask%d", document->mask_id);
xmlSetProp (mask_node, CC2XML ("id"), C2XML (buffer));
emit_paint (mask_node, surface, op, mask);
child = emit_paint (surface->xml_node, surface, op, source);
if (child) {
snprintf (buffer, sizeof buffer, "url(#mask%d)", document->mask_id);
xmlSetProp (child, CC2XML ("mask"), C2XML (buffer));
}
document->mask_id++;
surface->modified = TRUE;
return CAIRO_STATUS_SUCCESS;
}
#endif
static cairo_int_status_t
_cairo_svg_surface_stroke (void *abstract_dst,
@ -1199,21 +1098,21 @@ _cairo_svg_surface_stroke (void *abstract_dst,
xmlBufferCat (style, CC2XML (" stroke-dasharray: "));
for (i = 0; i < stroke_style->num_dashes; i++) {
if (i != 0)
xmlBufferCat (style, ",");
xmlBufferCat (style, CC2XML (","));
/* FIXME: Is is really what we want ? */
rx = ry = stroke_style->dash[i];
cairo_matrix_transform_distance (ctm, &rx, &ry);
_cairo_dtostr (buffer, sizeof buffer, sqrt ((rx * rx + ry * ry) / 2.0));
xmlBufferCat (style, C2XML (buffer));
}
xmlBufferCat (style, ";");
xmlBufferCat (style, CC2XML (";"));
if (stroke_style->dash_offset != 0.0) {
xmlBufferCat (style, CC2XML (" stroke-dashoffset: "));
rx = ry = stroke_style->dash_offset;
cairo_matrix_transform_distance (ctm, &rx, &ry);
_cairo_dtostr (buffer, sizeof buffer, sqrt ((rx * rx + ry * ry) / 2.0));
xmlBufferCat (style, C2XML (buffer));
xmlBufferCat (style, ";");
xmlBufferCat (style, CC2XML (";"));
}
}
@ -1231,30 +1130,26 @@ _cairo_svg_surface_stroke (void *abstract_dst,
&info);
child = xmlNewChild (surface->xml_node, NULL, CC2XML ("path"), NULL);
xmlSetProp (child, CC2XML ("d"), xmlBufferContent (info.path));
xmlSetProp (child, CC2XML ("style"), xmlBufferContent (style));
emit_operator (child, op);
xmlBufferFree (info.path);
xmlBufferFree (style);
surface->modified = TRUE;
return status;
}
static cairo_int_status_t
_cairo_svg_surface_old_show_glyphs (cairo_scaled_font_t *scaled_font,
cairo_operator_t op,
cairo_pattern_t *pattern,
void *abstract_surface,
int source_x,
int source_y,
int dest_x,
int dest_y,
unsigned int width,
unsigned int height,
const cairo_glyph_t *glyphs,
int num_glyphs)
_cairo_svg_surface_show_glyphs (void *abstract_surface,
cairo_operator_t op,
cairo_pattern_t *pattern,
const cairo_glyph_t *glyphs,
int num_glyphs,
cairo_scaled_font_t *scaled_font)
{
cairo_svg_surface_t *surface = abstract_surface;
cairo_path_fixed_t path;
cairo_status_t status;
@ -1278,6 +1173,7 @@ _cairo_svg_surface_old_show_glyphs (cairo_scaled_font_t *scaled_font,
_cairo_path_fixed_fini (&path);
surface->modified = TRUE;
return status;
}
@ -1296,10 +1192,8 @@ _cairo_svg_surface_intersect_clip_path (void *dst,
char buffer[CAIRO_SVG_DTOSTR_BUFFER_LEN];
if (path == NULL) {
while (surface->clip_level > 0) {
surface->xml_node = surface->xml_node->parent;
surface->clip_level--;
}
surface->xml_node = surface->xml_root_node;
surface->clip_level = 0;
return CAIRO_STATUS_SUCCESS;
}
@ -1350,6 +1244,7 @@ _cairo_svg_surface_get_font_options (void *abstract_surface,
static const cairo_surface_backend_t cairo_svg_surface_backend = {
CAIRO_SURFACE_TYPE_SVG,
_cairo_svg_surface_create_similar,
_cairo_svg_surface_finish,
NULL, /* acquire_source_image */
@ -1357,25 +1252,25 @@ static const cairo_surface_backend_t cairo_svg_surface_backend = {
NULL, /* acquire_dest_image */
NULL, /* release_dest_image */
NULL, /* clone_similar */
_cairo_svg_surface_composite,
_cairo_svg_surface_fill_rectangles,
_cairo_svg_surface_composite_trapezoids,
NULL, /* _cairo_svg_surface_composite, */
NULL, /* _cairo_svg_surface_fill_rectangles, */
NULL, /* _cairo_svg_surface_composite_trapezoids,*/
NULL, /* copy_page */
NULL, /* show_page */
NULL, /* set_clip_region */
_cairo_svg_surface_intersect_clip_path,
_cairo_svg_surface_get_extents,
_cairo_svg_surface_old_show_glyphs,
NULL, /* _cairo_svg_surface_old_show_glyphs, */
_cairo_svg_surface_get_font_options,
NULL, /* flush */
NULL, /* mark dirty rectangle */
NULL, /* scaled font fini */
NULL, /* scaled glyph fini */
NULL, /*_cairo_svg_surface_paint,*/
NULL, /* mask */
_cairo_svg_surface_paint,
_cairo_svg_surface_mask,
_cairo_svg_surface_stroke,
_cairo_svg_surface_fill,
NULL /* show_glyphs */
_cairo_svg_surface_show_glyphs
};
static cairo_svg_document_t *
@ -1407,6 +1302,7 @@ _cairo_svg_document_create (cairo_output_stream_t *output_stream,
document->pattern_id = 0;
document->filter_id = 0;
document->clip_id = 0;
document->mask_id = 0;
doc = xmlNewDoc (CC2XML ("1.0"));
node = xmlNewNode (NULL, CC2XML ("svg"));
@ -1423,7 +1319,7 @@ _cairo_svg_document_create (cairo_output_stream_t *output_stream,
xmlSetProp (node, CC2XML ("height"), CC2XML (buffer));
xmlSetProp (node, CC2XML ("xmlns"), CC2XML ("http://www.w3.org/2000/svg"));
xmlSetProp (node, CC2XML ("xmlns:xlink"), CC2XML ("http://www.w3.org/1999/xlink"));
xmlSetProp (node, CC2XML ("version"), CC2XML ("1.1"));
xmlSetProp (node, CC2XML ("version"), CC2XML ("1.2"));
return document;
}
@ -1446,21 +1342,32 @@ _cairo_svg_document_destroy (cairo_svg_document_t *document)
free (document);
}
static int
_cairo_svg_document_write (cairo_output_stream_t *output_stream,
const char * buffer,
int len)
{
if (_cairo_output_stream_write (output_stream, buffer, len) != CAIRO_STATUS_SUCCESS)
return -1;
}
static cairo_status_t
_cairo_svg_document_finish (cairo_svg_document_t *document)
{
cairo_status_t status;
cairo_output_stream_t *output = document->output_stream;
xmlChar *xml_buffer;
int xml_buffer_size;
xmlOutputBufferPtr xml_output_buffer;
if (document->finished)
return CAIRO_STATUS_SUCCESS;
/* FIXME: Dumping xml tree in memory is silly. */
xmlDocDumpFormatMemoryEnc (document->xml_doc, &xml_buffer, &xml_buffer_size, "UTF-8", 1);
_cairo_output_stream_write (document->output_stream, xml_buffer, xml_buffer_size);
xmlFree(xml_buffer);
xml_output_buffer = xmlOutputBufferCreateIO ((xmlOutputWriteCallback) _cairo_svg_document_write,
(xmlOutputCloseCallback) NULL,
(void *) document->output_stream,
NULL);
xmlSaveFormatFileTo (xml_output_buffer, document->xml_doc, "UTF-8", 1);
xmlFreeDoc (document->xml_doc);
status = _cairo_output_stream_get_status (output);

Просмотреть файл

@ -1,5 +1,4 @@
/*
* $Id: cairo-wideint.c,v 1.8 2006/03/17 07:44:28 vladimir%pobox.com Exp $
/* cairo - a vector graphics library with display and print output
*
* Copyright © 2004 Keith Packard
*

Просмотреть файл

@ -1,5 +1,4 @@
/*
* $Id: cairo-wideint.h,v 1.13 2006/03/17 07:44:28 vladimir%pobox.com Exp $
/* cairo - a vector graphics library with display and print output
*
* Copyright © 2004 Keith Packard
*

Просмотреть файл

@ -1146,8 +1146,7 @@ _cairo_win32_scaled_font_show_glyphs (void *abstract_font,
((int)solid_pattern->color.blue_short) >> 8);
status = _draw_glyphs_on_surface (surface, scaled_font, new_color,
- surface->base.device_x_offset,
- surface->base.device_y_offset,
0, 0,
glyphs, num_glyphs);
return status;
@ -1163,7 +1162,7 @@ _cairo_win32_scaled_font_show_glyphs (void *abstract_font,
cairo_surface_pattern_t mask;
RECT r;
tmp_surface = (cairo_win32_surface_t *)cairo_win32_surface_create_dib (CAIRO_FORMAT_ARGB32, width, height);
tmp_surface = (cairo_win32_surface_t *)cairo_win32_surface_create_with_dib (CAIRO_FORMAT_ARGB32, width, height);
if (tmp_surface->base.status)
return CAIRO_STATUS_NO_MEMORY;
@ -1359,6 +1358,7 @@ CLEANUP_FONT:
}
const cairo_scaled_font_backend_t cairo_win32_scaled_font_backend = {
CAIRO_FONT_TYPE_WIN32,
_cairo_win32_scaled_font_create_toy,
_cairo_win32_scaled_font_fini,
_cairo_win32_scaled_font_glyph_init,
@ -1404,6 +1404,7 @@ _cairo_win32_font_face_scaled_font_create (void *abstract_face,
}
static const cairo_font_face_backend_t _cairo_win32_font_face_backend = {
CAIRO_FONT_TYPE_WIN32,
_cairo_win32_font_face_destroy,
_cairo_win32_font_face_scaled_font_create
};

Просмотреть файл

@ -32,6 +32,7 @@
* Contributor(s):
* Owen Taylor <otaylor@redhat.com>
* Stuart Parmenter <stuart@mozilla.com>
* Vladimir Vukicevic <vladimir@pobox.com>
*/
#include <stdio.h>
@ -39,6 +40,7 @@
#include "cairo-clip-private.h"
#include "cairo-win32-private.h"
/* for older SDKs */
#ifndef SHADEBLENDCAPS
#define SHADEBLENDCAPS 120
#endif
@ -144,7 +146,7 @@ _create_dc_and_bitmap (cairo_win32_surface_t *surface,
/* We can't create real RGB24 bitmaps because something seems to
* break if we do, especially if we don't set up an image
* fallback. It could be a bug with using a 24bpp pixman image
* (and creating one with masks).
* (and creating one with masks). So treat them like 32bpp.
*/
case CAIRO_FORMAT_RGB24:
case CAIRO_FORMAT_ARGB32:
@ -332,27 +334,6 @@ _cairo_win32_surface_create_similar (void *abstract_src,
return _cairo_win32_surface_create_for_dc (src->dc, format, width, height);
}
/**
* _cairo_win32_surface_create_dib:
* @format: format of pixels in the surface to create
* @width: width of the surface, in pixels
* @height: height of the surface, in pixels
*
* Creates a device-independent-bitmap surface not associated with
* any particular existing surface or device context. The created
* bitmap will be unititialized.
*
* Return value: the newly created surface, or %NULL if it couldn't
* be created (probably because of lack of memory)
**/
cairo_surface_t *
cairo_win32_surface_create_dib (cairo_format_t format,
int width,
int height)
{
return _cairo_win32_surface_create_for_dc (NULL, format, width, height);
}
static cairo_status_t
_cairo_win32_surface_finish (void *abstract_surface)
{
@ -412,8 +393,6 @@ _cairo_win32_surface_get_subimage (cairo_win32_surface_t *surface,
FillRect(local->dc, &r, (HBRUSH)GetStockObject(WHITE_BRUSH));
}
GdiFlush();
*local_out = local;
return CAIRO_STATUS_SUCCESS;
@ -437,8 +416,6 @@ _cairo_win32_surface_acquire_source_image (void *abstract_sur
cairo_status_t status;
if (surface->image) {
GdiFlush();
*image_out = (cairo_image_surface_t *)surface->image;
*image_extra = NULL;
@ -646,7 +623,7 @@ _composite_alpha_blend (cairo_win32_surface_t *dst,
src_x, src_y,
width, height,
blend_function))
return _cairo_win32_print_gdi_error ("_cairo_win32_surface_composite(AlphaBlend)");
return _cairo_win32_print_gdi_error ("_cairo_win32_surface_composite");
return CAIRO_STATUS_SUCCESS;
}
@ -672,7 +649,7 @@ _cairo_win32_surface_composite (cairo_operator_t op,
int integer_transform;
int itx, ity;
if (pattern->type != CAIRO_PATTERN_SURFACE ||
if (pattern->type != CAIRO_PATTERN_TYPE_SURFACE ||
pattern->extend != CAIRO_EXTEND_NONE)
return CAIRO_INT_STATUS_UNSUPPORTED;
@ -680,7 +657,7 @@ _cairo_win32_surface_composite (cairo_operator_t op,
/* FIXME: When we fully support RENDER style 4-channel
* masks we need to check r/g/b != 1.0.
*/
if (mask_pattern->type != CAIRO_PATTERN_SOLID)
if (mask_pattern->type != CAIRO_PATTERN_TYPE_SOLID)
return CAIRO_INT_STATUS_UNSUPPORTED;
alpha = ((cairo_solid_pattern_t *)mask_pattern)->color.alpha_short >> 8;
@ -735,7 +712,7 @@ _cairo_win32_surface_composite (cairo_operator_t op,
src->dc,
src_x, src_y,
SRCCOPY))
return _cairo_win32_print_gdi_error ("_cairo_win32_surface_composite(BitBlt)");
return _cairo_win32_print_gdi_error ("_cairo_win32_surface_composite");
return CAIRO_STATUS_SUCCESS;
@ -1001,6 +978,8 @@ _cairo_win32_surface_flush (void *abstract_surface)
return _cairo_surface_reset_clip (abstract_surface);
}
#define STACK_GLYPH_SIZE 256
static cairo_int_status_t
_cairo_win32_surface_show_glyphs (void *surface,
cairo_operator_t op,
@ -1009,28 +988,43 @@ _cairo_win32_surface_show_glyphs (void *surface,
int num_glyphs,
cairo_scaled_font_t *scaled_font)
{
#define STACK_GLYPH_SIZE 256
cairo_win32_surface_t *dst = surface;
cairo_solid_pattern_t *solid_pattern = (cairo_solid_pattern_t *)source;
WORD glyph_buf_stack[STACK_GLYPH_SIZE];
WORD *glyph_buf = glyph_buf_stack;
int dx_buf_stack[STACK_GLYPH_SIZE];
int *dx_buf = dx_buf_stack;
BOOL result = 0;
BOOL win_result = 0;
int i;
double last_y = glyphs[0].y;
cairo_solid_pattern_t *solid_pattern;
COLORREF color;
int output_count = 0;
if ((op != CAIRO_OPERATOR_SOURCE && op != CAIRO_OPERATOR_OVER) ||
(dst->format != CAIRO_FORMAT_RGB24) ||
(!_cairo_pattern_is_opaque_solid(source)) ||
(dst->base.clip &&
(dst->base.clip->mode != CAIRO_CLIP_MODE_REGION ||
dst->base.clip->surface != NULL)))
/* We can only handle win32 fonts */
if (cairo_scaled_font_get_type (scaled_font) != CAIRO_FONT_TYPE_WIN32)
return CAIRO_INT_STATUS_UNSUPPORTED;
/* We can only handle opaque solid color sources */
if (!_cairo_pattern_is_opaque_solid(source))
return CAIRO_INT_STATUS_UNSUPPORTED;
/* We can only handle operator SOURCE or OVER with the destination
* having no alpha */
if ((op != CAIRO_OPERATOR_SOURCE && op != CAIRO_OPERATOR_OVER) ||
(dst->format != CAIRO_FORMAT_RGB24))
return CAIRO_INT_STATUS_UNSUPPORTED;
/* If we have a fallback mask clip set on the dst, we have
* to go through the fallback path */
if (dst->base.clip &&
(dst->base.clip->mode != CAIRO_CLIP_MODE_REGION ||
dst->base.clip->surface != NULL))
return CAIRO_INT_STATUS_UNSUPPORTED;
solid_pattern = (cairo_solid_pattern_t *)source;
color = RGB(((int)solid_pattern->color.red_short) >> 8,
((int)solid_pattern->color.green_short) >> 8,
((int)solid_pattern->color.blue_short) >> 8);
@ -1058,16 +1052,16 @@ _cairo_win32_surface_show_glyphs (void *surface,
if (i == num_glyphs - 1 || glyphs[i].y != glyphs[i+1].y) {
const int offset = (i - output_count) + 1;
result = ExtTextOutW(dst->dc,
glyphs[offset].x * WIN32_FONT_LOGICAL_SCALE,
last_y * WIN32_FONT_LOGICAL_SCALE,
ETO_GLYPH_INDEX,
NULL,
glyph_buf + offset,
output_count,
dx_buf + offset);
if (!result) {
const int offset = (i - output_count) + 1;
win_result = ExtTextOutW(dst->dc,
glyphs[offset].x * WIN32_FONT_LOGICAL_SCALE,
last_y * WIN32_FONT_LOGICAL_SCALE,
ETO_GLYPH_INDEX,
NULL,
glyph_buf + offset,
output_count,
dx_buf + offset);
if (!win_result) {
_cairo_win32_print_gdi_error("_cairo_win32_surface_show_glyphs(ExtTextOutW failed)");
goto FAIL;
}
@ -1085,11 +1079,23 @@ FAIL:
free(glyph_buf);
free(dx_buf);
}
return (result) ? CAIRO_STATUS_SUCCESS : CAIRO_INT_STATUS_UNSUPPORTED;
#undef STACK_GLYPH_SIZE
return (win_result) ? CAIRO_STATUS_SUCCESS : CAIRO_INT_STATUS_UNSUPPORTED;
}
#undef STACK_GLYPH_SIZE
/**
* cairo_win32_surface_create:
* @hdc: the DC to create a surface for
*
* Creates a cairo surface that targets the given DC. The DC will be
* queried for its initial clip extents, and this will be used as the
* size of the cairo surface. Also, if the DC is a raster DC, it will
* be queried for its pixel format and the cairo surface format will
* be set appropriately.
*
* Return value: the newly created surface
**/
cairo_surface_t *
cairo_win32_surface_create (HDC hdc)
{
@ -1165,6 +1171,28 @@ cairo_win32_surface_create (HDC hdc)
return (cairo_surface_t *)surface;
}
/**
* cairo_win32_surface_create_with_dib:
* @format: format of pixels in the surface to create
* @width: width of the surface, in pixels
* @height: height of the surface, in pixels
*
* Creates a device-independent-bitmap surface not associated with
* any particular existing surface or device context. The created
* bitmap will be unititialized.
*
* Return value: the newly created surface
*
**/
cairo_surface_t *
cairo_win32_surface_create_with_dib (cairo_format_t format,
int width,
int height)
{
return _cairo_win32_surface_create_for_dc (NULL, format, width, height);
}
/**
* _cairo_surface_is_win32:
* @surface: a #cairo_surface_t
@ -1205,6 +1233,7 @@ cairo_win32_surface_get_dc (cairo_surface_t *surface)
}
static const cairo_surface_backend_t cairo_win32_surface_backend = {
CAIRO_SURFACE_TYPE_WIN32,
_cairo_win32_surface_create_similar,
_cairo_win32_surface_finish,
_cairo_win32_surface_acquire_source_image,
@ -1233,7 +1262,7 @@ static const cairo_surface_backend_t cairo_win32_surface_backend = {
NULL, /* fill */
_cairo_win32_surface_show_glyphs,
NULL, /* snapshot */
NULL /* snapshot */
};
/*

Просмотреть файл

@ -48,9 +48,9 @@ cairo_public cairo_surface_t *
cairo_win32_surface_create (HDC hdc);
cairo_public cairo_surface_t *
cairo_win32_surface_create_dib (cairo_format_t format,
int width,
int height);
cairo_win32_surface_create_with_dib (cairo_format_t format,
int width,
int height);
cairo_public HDC
cairo_win32_surface_get_dc (cairo_surface_t *surface);

Просмотреть файл

@ -321,7 +321,7 @@ _CAIRO_MASK_FORMAT (cairo_format_masks_t *masks, cairo_format_t *format)
masks->blue_mask == 0x000000ff)
{
*format = CAIRO_FORMAT_ARGB32;
return 1;
return TRUE;
}
if (masks->alpha_mask == 0x00000000 &&
masks->red_mask == 0x00ff0000 &&
@ -329,25 +329,25 @@ _CAIRO_MASK_FORMAT (cairo_format_masks_t *masks, cairo_format_t *format)
masks->blue_mask == 0x000000ff)
{
*format = CAIRO_FORMAT_RGB24;
return 1;
return TRUE;
}
break;
case 8:
if (masks->alpha_mask == 0xff)
{
*format = CAIRO_FORMAT_A8;
return 1;
return TRUE;
}
break;
case 1:
if (masks->alpha_mask == 0x1)
{
*format = CAIRO_FORMAT_A1;
return 1;
return TRUE;
}
break;
}
return 0;
return FALSE;
}
static cairo_status_t
@ -1025,6 +1025,7 @@ _cairo_xcb_surface_get_extents (void *abstract_surface,
}
static const cairo_surface_backend_t cairo_xcb_surface_backend = {
CAIRO_SURFACE_TYPE_XCB,
_cairo_xcb_surface_create_similar,
_cairo_xcb_surface_finish,
_cairo_xcb_surface_acquire_source_image,

Просмотреть файл

@ -40,7 +40,9 @@
#include "cairo-xlib-xrender.h"
#include "cairo-xlib-test.h"
#include "cairo-xlib-private.h"
#include "cairo-clip-private.h"
#include <X11/extensions/Xrender.h>
#include <X11/extensions/renderproto.h>
/* Xlib doesn't define a typedef, so define one ourselves */
typedef int (*cairo_xlib_error_func_t) (Display *display,
@ -63,6 +65,14 @@ _cairo_surface_is_xlib (cairo_surface_t *surface);
static cairo_bool_t
_native_byte_order_lsb (void);
static cairo_int_status_t
_cairo_xlib_surface_show_glyphs (void *abstract_dst,
cairo_operator_t op,
cairo_pattern_t *src_pattern,
const cairo_glyph_t *glyphs,
int num_glyphs,
cairo_scaled_font_t *scaled_font);
/*
* Instead of taking two round trips for each blending request,
* assume that if a particular drawable fails GetImage that it will
@ -291,7 +301,7 @@ _cairo_xlib_surface_create_similar (void *abstract_src,
}
return _cairo_xlib_surface_create_similar_with_format (abstract_src,
format, width, height);
format, width, height);
}
static cairo_status_t
@ -1095,7 +1105,7 @@ _categorize_composite_operation (cairo_xlib_surface_t *dst,
if (!dst->buggy_repeat)
return DO_RENDER;
if (src_pattern->type == CAIRO_PATTERN_SURFACE)
if (src_pattern->type == CAIRO_PATTERN_TYPE_SURFACE)
{
cairo_surface_pattern_t *surface_pattern = (cairo_surface_pattern_t *)src_pattern;
@ -1701,20 +1711,6 @@ _cairo_xlib_surface_get_font_options (void *abstract_surface,
options->antialias = CAIRO_ANTIALIAS_GRAY;
}
static cairo_int_status_t
_cairo_xlib_surface_old_show_glyphs (cairo_scaled_font_t *scaled_font,
cairo_operator_t op,
cairo_pattern_t *pattern,
void *abstract_surface,
int source_x,
int source_y,
int dest_x,
int dest_y,
unsigned int width,
unsigned int height,
const cairo_glyph_t *glyphs,
int num_glyphs);
static void
_cairo_xlib_surface_scaled_font_fini (cairo_scaled_font_t *scaled_font);
@ -1723,6 +1719,7 @@ _cairo_xlib_surface_scaled_glyph_fini (cairo_scaled_glyph_t *scaled_glyph,
cairo_scaled_font_t *scaled_font);
static const cairo_surface_backend_t cairo_xlib_surface_backend = {
CAIRO_SURFACE_TYPE_XLIB,
_cairo_xlib_surface_create_similar,
_cairo_xlib_surface_finish,
_cairo_xlib_surface_acquire_source_image,
@ -1738,12 +1735,19 @@ static const cairo_surface_backend_t cairo_xlib_surface_backend = {
_cairo_xlib_surface_set_clip_region,
NULL, /* intersect_clip_path */
_cairo_xlib_surface_get_extents,
_cairo_xlib_surface_old_show_glyphs,
NULL, /* old_show_glyphs */
_cairo_xlib_surface_get_font_options,
NULL, /* flush */
NULL, /* mark_dirty_rectangle */
_cairo_xlib_surface_scaled_font_fini,
_cairo_xlib_surface_scaled_glyph_fini,
NULL, /* paint */
NULL, /* mask */
NULL, /* stroke */
NULL, /* fill */
_cairo_xlib_surface_show_glyphs,
NULL /* snapshot */
};
/**
@ -2232,8 +2236,8 @@ _cairo_xlib_surface_add_glyph (Display *dpy,
* sitting around for x and y.
*/
glyph_info.x = -(int) glyph_surface->base.device_x_offset;
glyph_info.y = -(int) glyph_surface->base.device_y_offset;
glyph_info.x = - (int) floor(glyph_surface->base.device_x_offset + 0.5);
glyph_info.y = - (int) floor(glyph_surface->base.device_y_offset + 0.5);
glyph_info.width = glyph_surface->width;
glyph_info.height = glyph_surface->height;
glyph_info.xOff = 0;
@ -2314,14 +2318,13 @@ _cairo_xlib_surface_add_glyph (Display *dpy,
#define N_STACK_BUF 1024
static cairo_status_t
_cairo_xlib_surface_old_show_glyphs8 (cairo_scaled_font_t *scaled_font,
cairo_operator_t op,
cairo_xlib_surface_t *src,
cairo_xlib_surface_t *self,
int source_x,
int source_y,
const cairo_glyph_t *glyphs,
int num_glyphs)
_cairo_xlib_surface_show_glyphs8 (cairo_xlib_surface_t *dst,
cairo_operator_t op,
cairo_xlib_surface_t *src,
int src_x_offset, int src_y_offset,
const cairo_glyph_t *glyphs,
int num_glyphs,
cairo_scaled_font_t *scaled_font)
{
cairo_xlib_surface_font_private_t *font_private = scaled_font->surface_private;
XGlyphElt8 *elts = NULL;
@ -2360,13 +2363,13 @@ _cairo_xlib_surface_old_show_glyphs8 (cairo_scaled_font_t *scaled_font,
lastY = thisY;
}
XRenderCompositeText8 (self->dpy,
XRenderCompositeText8 (dst->dpy,
_render_operator (op),
src->src_picture,
self->dst_picture,
dst->dst_picture,
font_private->format,
source_x + elts[0].xOff, source_y + elts[0].yOff,
0, 0,
src_x_offset + elts[0].xOff, src_y_offset + elts[0].yOff,
elts[0].xOff, elts[0].yOff,
elts, num_glyphs);
if (elts != stack_elts)
@ -2376,14 +2379,13 @@ _cairo_xlib_surface_old_show_glyphs8 (cairo_scaled_font_t *scaled_font,
}
static cairo_status_t
_cairo_xlib_surface_old_show_glyphs16 (cairo_scaled_font_t *scaled_font,
cairo_operator_t op,
cairo_xlib_surface_t *src,
cairo_xlib_surface_t *self,
int source_x,
int source_y,
const cairo_glyph_t *glyphs,
int num_glyphs)
_cairo_xlib_surface_show_glyphs16 (cairo_xlib_surface_t *dst,
cairo_operator_t op,
cairo_xlib_surface_t *src,
int src_x_offset, int src_y_offset,
const cairo_glyph_t *glyphs,
int num_glyphs,
cairo_scaled_font_t *scaled_font)
{
cairo_xlib_surface_font_private_t *font_private = scaled_font->surface_private;
XGlyphElt16 *elts = NULL;
@ -2422,13 +2424,13 @@ _cairo_xlib_surface_old_show_glyphs16 (cairo_scaled_font_t *scaled_font,
lastY = thisY;
}
XRenderCompositeText16 (self->dpy,
XRenderCompositeText16 (dst->dpy,
_render_operator (op),
src->src_picture,
self->dst_picture,
dst->dst_picture,
font_private->format,
source_x + elts[0].xOff, source_y + elts[0].yOff,
0, 0,
src_x_offset + elts[0].xOff, src_y_offset + elts[0].yOff,
elts[0].xOff, elts[0].yOff,
elts, num_glyphs);
if (elts != stack_elts)
@ -2438,14 +2440,13 @@ _cairo_xlib_surface_old_show_glyphs16 (cairo_scaled_font_t *scaled_font,
}
static cairo_status_t
_cairo_xlib_surface_old_show_glyphs32 (cairo_scaled_font_t *scaled_font,
cairo_operator_t op,
cairo_xlib_surface_t *src,
cairo_xlib_surface_t *self,
int source_x,
int source_y,
const cairo_glyph_t *glyphs,
int num_glyphs)
_cairo_xlib_surface_show_glyphs32 (cairo_xlib_surface_t *dst,
cairo_operator_t op,
cairo_xlib_surface_t *src,
int src_x_offset, int src_y_offset,
const cairo_glyph_t *glyphs,
int num_glyphs,
cairo_scaled_font_t *scaled_font)
{
cairo_xlib_surface_font_private_t *font_private = scaled_font->surface_private;
XGlyphElt32 *elts = NULL;
@ -2484,13 +2485,13 @@ _cairo_xlib_surface_old_show_glyphs32 (cairo_scaled_font_t *scaled_font,
lastY = thisY;
}
XRenderCompositeText32 (self->dpy,
XRenderCompositeText32 (dst->dpy,
_render_operator (op),
src->src_picture,
self->dst_picture,
dst->dst_picture,
font_private->format,
source_x + elts[0].xOff, source_y + elts[0].yOff,
0, 0,
src_x_offset + elts[0].xOff, src_y_offset + elts[0].yOff,
elts[0].xOff, elts[0].yOff,
elts, num_glyphs);
if (elts != stack_elts)
@ -2499,62 +2500,113 @@ _cairo_xlib_surface_old_show_glyphs32 (cairo_scaled_font_t *scaled_font,
return CAIRO_STATUS_SUCCESS;
}
typedef cairo_status_t (*cairo_xlib_surface_show_glyphs_func_t)
(cairo_xlib_surface_t *, cairo_operator_t, cairo_xlib_surface_t *, int, int,
const cairo_glyph_t *, int, cairo_scaled_font_t *);
static cairo_int_status_t
_cairo_xlib_surface_old_show_glyphs (cairo_scaled_font_t *scaled_font,
cairo_operator_t op,
cairo_pattern_t *pattern,
void *abstract_surface,
int source_x,
int source_y,
int dest_x,
int dest_y,
unsigned int width,
unsigned int height,
const cairo_glyph_t *glyphs,
int num_glyphs)
_cairo_xlib_surface_show_glyphs (void *abstract_dst,
cairo_operator_t op,
cairo_pattern_t *src_pattern,
const cairo_glyph_t *glyphs,
int num_glyphs,
cairo_scaled_font_t *scaled_font)
{
cairo_surface_attributes_t attributes;
cairo_int_status_t status;
cairo_xlib_surface_t *self = abstract_surface;
cairo_xlib_surface_t *src;
cairo_int_status_t status;
cairo_xlib_surface_t *dst = (cairo_xlib_surface_t*) abstract_dst;
composite_operation_t operation;
cairo_surface_attributes_t attributes;
cairo_xlib_surface_t *src = NULL;
const cairo_glyph_t *glyphs_chunk;
int glyphs_remaining, chunk_size, max_chunk_size;
cairo_scaled_glyph_t *scaled_glyph;
cairo_xlib_surface_font_private_t *font_private;
cairo_rectangle_t glyph_extents;
int i;
unsigned long max_index = 0;
if (!CAIRO_SURFACE_RENDER_HAS_COMPOSITE_TEXT (self) || !self->format)
cairo_xlib_surface_show_glyphs_func_t show_glyphs_func;
cairo_pattern_union_t solid_pattern;
if (!CAIRO_SURFACE_RENDER_HAS_COMPOSITE_TEXT (dst) || !dst->format)
return CAIRO_INT_STATUS_UNSUPPORTED;
operation = _categorize_composite_operation (self, op, pattern, TRUE);
/* Just let unbounded operators go through the fallback code
* instead of trying to do the fixups here */
if (!_cairo_operator_bounded_by_mask (op))
return CAIRO_INT_STATUS_UNSUPPORTED;
/* Render <= 0.10 seems to have a bug with PictOpSrc and glyphs --
* the solid source seems to be multiplied by the glyph mask, and
* then the entire thing is copied to the destination surface,
* including the fully transparent "background" of the rectangular
* glyph surface. */
if (op == CAIRO_OPERATOR_SOURCE &&
!CAIRO_SURFACE_RENDER_AT_LEAST(dst, 0, 11))
return CAIRO_INT_STATUS_UNSUPPORTED;
/* We can only use our code if we either have no clip or
* have a real native clip region set. If we're using
* fallback clip masking, we have to go through the full
* fallback path.
*/
if (dst->base.clip &&
(dst->base.clip->mode != CAIRO_CLIP_MODE_REGION ||
dst->base.clip->surface != NULL))
return CAIRO_INT_STATUS_UNSUPPORTED;
operation = _categorize_composite_operation (dst, op, src_pattern, TRUE);
if (operation == DO_UNSUPPORTED)
return CAIRO_INT_STATUS_UNSUPPORTED;
font_private = scaled_font->surface_private;
if ((scaled_font->surface_backend != NULL &&
scaled_font->surface_backend != &cairo_xlib_surface_backend) ||
(font_private != NULL && font_private->dpy != self->dpy))
(font_private != NULL && font_private->dpy != dst->dpy))
return CAIRO_INT_STATUS_UNSUPPORTED;
status = _cairo_pattern_acquire_surface (pattern, &self->base,
source_x, source_y, width, height,
(cairo_surface_t **) &src,
&attributes);
status = _cairo_scaled_font_glyph_device_extents (scaled_font,
glyphs,
num_glyphs,
&glyph_extents);
if (status)
return status;
return status;
operation = _recategorize_composite_operation (self, op, src, &attributes, TRUE);
/* PictOpClear doesn't seem to work with CompositeText; it seems to ignore
* the mask (the glyphs). This code below was executed as a side effect
* of going through the _clip_and_composite fallback code for old_show_glyphs,
* so PictOpClear was never used with CompositeText before.
*/
if (op == CAIRO_OPERATOR_CLEAR) {
_cairo_pattern_init_solid (&solid_pattern.solid, CAIRO_COLOR_WHITE);
src_pattern = &solid_pattern.base;
op = CAIRO_OPERATOR_DEST_OUT;
}
status = _cairo_pattern_acquire_surface (src_pattern, &dst->base,
glyph_extents.x, glyph_extents.y,
glyph_extents.width, glyph_extents.height,
(cairo_surface_t **) &src,
&attributes);
if (status)
goto FAIL;
operation = _recategorize_composite_operation (dst, op, src, &attributes, TRUE);
if (operation == DO_UNSUPPORTED) {
status = CAIRO_INT_STATUS_UNSUPPORTED;
goto FAIL;
}
status = _cairo_xlib_surface_set_attributes (src, &attributes);
if (status)
goto FAIL;
/* Send all unsent glyphs to the server */
goto FAIL;
/* Send all unsent glyphs to the server, and count the max of the glyph indices */
for (i = 0; i < num_glyphs; i++) {
if (glyphs[i].index > max_index)
max_index = glyphs[i].index;
@ -2565,47 +2617,44 @@ _cairo_xlib_surface_old_show_glyphs (cairo_scaled_font_t *scaled_font,
if (status != CAIRO_STATUS_SUCCESS)
return status;
if (scaled_glyph->surface_private == NULL) {
_cairo_xlib_surface_add_glyph (self->dpy, scaled_font, scaled_glyph);
_cairo_xlib_surface_add_glyph (dst->dpy, scaled_font, scaled_glyph);
scaled_glyph->surface_private = (void *) 1;
}
}
_cairo_xlib_surface_ensure_dst_picture (self);
/* Call the appropriate sub-function. */
if (max_index < 256)
status = _cairo_xlib_surface_old_show_glyphs8 (scaled_font, op, src, self,
source_x + attributes.x_offset - dest_x,
source_y + attributes.y_offset - dest_y,
glyphs, num_glyphs);
else if (max_index < 65536)
status = _cairo_xlib_surface_old_show_glyphs16 (scaled_font, op, src, self,
source_x + attributes.x_offset - dest_x,
source_y + attributes.y_offset - dest_y,
glyphs, num_glyphs);
else
status = _cairo_xlib_surface_old_show_glyphs32 (scaled_font, op, src, self,
source_x + attributes.x_offset - dest_x,
source_y + attributes.y_offset - dest_y,
glyphs, num_glyphs);
_cairo_xlib_surface_ensure_dst_picture (dst);
if (status == CAIRO_STATUS_SUCCESS && !_cairo_operator_bounded_by_mask (op)) {
cairo_rectangle_t extents;
status = _cairo_scaled_font_glyph_device_extents (scaled_font,
glyphs,
num_glyphs,
&extents);
if (status == CAIRO_STATUS_SUCCESS)
status = _cairo_surface_composite_shape_fixup_unbounded
(&self->base, &attributes, src->width, src->height,
extents.width, extents.height,
source_x, source_y,
dest_x - extents.x, dest_y - extents.y,
dest_x, dest_y,
width, height);
max_chunk_size = XMaxRequestSize (dst->dpy);
if (max_index < 256) {
max_chunk_size -= sz_xRenderCompositeGlyphs8Req;
show_glyphs_func = _cairo_xlib_surface_show_glyphs8;
} else if (max_index < 65536) {
max_chunk_size -= sz_xRenderCompositeGlyphs16Req;
show_glyphs_func = _cairo_xlib_surface_show_glyphs16;
} else {
max_chunk_size -= sz_xRenderCompositeGlyphs32Req;
show_glyphs_func = _cairo_xlib_surface_show_glyphs32;
}
FAIL:
_cairo_pattern_release_surface (pattern, &src->base, &attributes);
max_chunk_size /= sz_xGlyphElt;
for (glyphs_remaining = num_glyphs, glyphs_chunk = glyphs;
glyphs_remaining;
glyphs_remaining -= chunk_size, glyphs_chunk += chunk_size)
{
chunk_size = MIN (glyphs_remaining, max_chunk_size);
status = show_glyphs_func (dst, op, src,
attributes.x_offset, attributes.y_offset,
glyphs_chunk, chunk_size, scaled_font);
if (status != CAIRO_STATUS_SUCCESS)
break;
}
FAIL:
if (src)
_cairo_pattern_release_surface (src_pattern, &src->base, &attributes);
if (src_pattern == &solid_pattern.base)
_cairo_pattern_fini (&solid_pattern.base);
return status;
}

Просмотреть файл

@ -324,29 +324,6 @@ cairo_restore (cairo_t *cr)
}
slim_hidden_def(cairo_restore);
/**
* moz_cairo_set_target:
* @cr: a #cairo_t
* @target: a #cairo_surface_t
*
* Change the destination surface of rendering to @cr to @target.
* @target must not be %NULL, or an error will be set on @cr.
*/
void
moz_cairo_set_target (cairo_t *cr, cairo_surface_t *target)
{
if (cr->status)
return;
if (target == NULL) {
_cairo_set_error (cr, CAIRO_STATUS_NULL_POINTER);
return;
}
_moz_cairo_gstate_set_target (cr->gstate, target);
}
slim_hidden_def(moz_cairo_set_target);
/**
* cairo_push_group:
* @cr: a cairo context
@ -402,8 +379,13 @@ cairo_push_group_with_content (cairo_t *cr, cairo_content_t content)
goto bail;
/* Set device offsets on the new surface so that logically it appears at
* the same location on the parent surface. */
cairo_surface_set_device_offset (group_surface, -extents.x, -extents.y);
* the same location on the parent surface -- when we pop_group this,
* the source pattern will get fixed up for the appropriate target surface
* device offsets, so we want to set our own surface offsets from /that/,
* and not from the device origin. */
cairo_surface_set_device_offset (group_surface,
cr->gstate->target->device_x_offset - extents.x,
cr->gstate->target->device_y_offset - extents.y);
/* create a new gstate for the redirect */
cairo_save (cr);
@ -2278,6 +2260,9 @@ cairo_show_glyphs (cairo_t *cr, cairo_glyph_t *glyphs, int num_glyphs)
if (cr->status)
return;
if (num_glyphs == 0)
return;
cr->status = _cairo_gstate_show_glyphs (cr->gstate, glyphs, num_glyphs);
if (cr->status)
_cairo_set_error (cr, cr->status);
@ -2527,10 +2512,14 @@ cairo_get_target (cairo_t *cr)
/**
* cairo_get_group_target:
* @cr: a cairo context
*
* @dx: device offset x value from cr's original target
* @dy: device offset y value from cr's original target
*
* Gets the target surface for the current transparency group
* started by the last cairo_push_group() call on the cairo
* context.
* context. The offset between this surface and the cairo
* context's original target surface is also returned if
* dx and/or dy are not NULL.
*
* This function may return NULL if there is no transparency
* group on the target.
@ -2540,12 +2529,21 @@ cairo_get_target (cairo_t *cr)
* cairo_surface_reference().
**/
cairo_surface_t *
cairo_get_group_target (cairo_t *cr)
cairo_get_group_target (cairo_t *cr, double *dx, double *dy)
{
cairo_surface_t *gsurf;
if (cr->status)
return (cairo_surface_t*) &_cairo_surface_nil;
return _cairo_gstate_get_target (cr->gstate);
gsurf = _cairo_gstate_get_target (cr->gstate);
if (!gsurf)
return NULL;
if (dx || dy)
_cairo_gstate_get_target_offsets_from_original (cr->gstate, dx, dy);
return gsurf;
}
/**

Просмотреть файл

@ -272,9 +272,6 @@ cairo_save (cairo_t *cr);
cairo_public void
cairo_restore (cairo_t *cr);
cairo_public void
moz_cairo_set_target (cairo_t *cr, cairo_surface_t *target);
cairo_public void
cairo_push_group (cairo_t *cr);
@ -923,6 +920,47 @@ cairo_font_face_destroy (cairo_font_face_t *font_face);
cairo_public cairo_status_t
cairo_font_face_status (cairo_font_face_t *font_face);
/**
* cairo_font_type_t
* @CAIRO_FONT_TYPE_FT: The font is of type ft
* @CAIRO_FONT_TYPE_WIN32: The font is of type win32
* @CAIRO_FONT_TYPE_ATSUI: The font is of type atsui
*
* @cairo_font_type_t is used to describe the type of a given font
* face or scaled font. The font types are also known as "font
* backends" within cairo.
*
* The type of a font face is determined by the function used to
* create it, which will generally be of the form
* cairo_<type>_font_face_create. The font face type can be queried
* with cairo_font_face_get_type()
*
* The various cairo_font_face functions can be used with a font face
* of any type.
*
* The type of a scaled font is determined by the type of the font
* face passed to cairo_scaled_font_create. The scaled font type can
* be queried with cairo_scaled_font_get_type()
*
* The various cairo_scaled_font functions can be used with scaled
* fonts of any type, but some font backends also provide
* type-specific functions that must only be called with a scaled font
* of the appropriate type. These functions have names that begin with
* cairo_<type>_scaled_font such as cairo_ft_scaled_font_lock_face.
*
* The behavior of calling a type-specific function with a scaled font
* of the wrong type is undefined.
*/
typedef enum _cairo_font_type {
CAIRO_FONT_TYPE_TOY,
CAIRO_FONT_TYPE_FT,
CAIRO_FONT_TYPE_WIN32,
CAIRO_FONT_TYPE_ATSUI
} cairo_font_type_t;
cairo_public cairo_font_type_t
cairo_font_face_get_type (cairo_font_face_t *font_face);
cairo_public void *
cairo_font_face_get_user_data (cairo_font_face_t *font_face,
const cairo_user_data_key_t *key);
@ -950,6 +988,9 @@ cairo_scaled_font_destroy (cairo_scaled_font_t *scaled_font);
cairo_public cairo_status_t
cairo_scaled_font_status (cairo_scaled_font_t *scaled_font);
cairo_public cairo_font_type_t
cairo_scaled_font_get_type (cairo_scaled_font_t *scaled_font);
cairo_public void
cairo_scaled_font_extents (cairo_scaled_font_t *scaled_font,
cairo_font_extents_t *extents);
@ -1021,7 +1062,7 @@ cairo_public cairo_surface_t *
cairo_get_target (cairo_t *cr);
cairo_public cairo_surface_t *
cairo_get_group_target (cairo_t *cr);
cairo_get_group_target (cairo_t *cr, double *dx, double *dy);
typedef enum _cairo_path_data_type {
CAIRO_PATH_MOVE_TO,
@ -1144,7 +1185,7 @@ cairo_path_destroy (cairo_path_t *path);
* A data structure for holding clip rectangles.
*/
typedef struct _cairo_clip_rect {
double x, y, width, height;
double x, y, width, height;
} cairo_clip_rect_t;
cairo_public cairo_bool_t
@ -1175,14 +1216,66 @@ cairo_surface_create_similar (cairo_surface_t *other,
cairo_public cairo_surface_t *
cairo_surface_reference (cairo_surface_t *surface);
cairo_public void
cairo_surface_finish (cairo_surface_t *surface);
cairo_public void
cairo_surface_destroy (cairo_surface_t *surface);
cairo_public cairo_status_t
cairo_surface_status (cairo_surface_t *surface);
cairo_public void
cairo_surface_finish (cairo_surface_t *surface);
/**
* cairo_surface_type_t
* @CAIRO_SURFACE_TYPE_IMAGE: The surface is of type image
* @CAIRO_SURFACE_TYPE_PDF: The surface is of type pdf
* @CAIRO_SURFACE_TYPE_PS: The surface is of type ps
* @CAIRO_SURFACE_TYPE_XLIB: The surface is of type xlib
* @CAIRO_SURFACE_TYPE_XCB: The surface is of type xcb
* @CAIRO_SURFACE_TYPE_GLITZ: The surface is of type glitz
* @CAIRO_SURFACE_TYPE_QUARTZ: The surface is of type quartz
* @CAIRO_SURFACE_TYPE_WIN32: The surface is of type win32
* @CAIRO_SURFACE_TYPE_BEOS: The surface is of type beos
* @CAIRO_SURFACE_TYPE_DIRECTFB: The surface is of type directfb
* @CAIRO_SURFACE_TYPE_SVG: The surface is of type svg
* @CAIRO_SURFACE_TYPE_QUARTZ2: The surface is of type quartz2
*
* @cairo_surface_type_t is used to describe the type of a given
* surface. The surface types are also known as "backends" or "surface
* backends" within cairo.
*
* The type of a surface is determined by the function used to create
* it, which will generally be of the form cairo_<type>_surface_create,
* (though see cairo_surface_create_similar as well).
*
* The surface type can be queried with cairo_surface_get_type()
*
* The various cairo_surface functions can be used with surfaces of
* any type, but some backends also provide type-specific functions
* that must only be called with a surface of the appropriate
* type. These functions have names that begin with
* cairo_<type>_surface such as cairo_image_surface_get_width().
*
* The behavior of calling a type-specific function with a surface of
* the wrong type is undefined.
*/
typedef enum _cairo_surface_type {
CAIRO_SURFACE_TYPE_IMAGE,
CAIRO_SURFACE_TYPE_PDF,
CAIRO_SURFACE_TYPE_PS,
CAIRO_SURFACE_TYPE_XLIB,
CAIRO_SURFACE_TYPE_XCB,
CAIRO_SURFACE_TYPE_GLITZ,
CAIRO_SURFACE_TYPE_QUARTZ,
CAIRO_SURFACE_TYPE_WIN32,
CAIRO_SURFACE_TYPE_BEOS,
CAIRO_SURFACE_TYPE_DIRECTFB,
CAIRO_SURFACE_TYPE_SVG,
CAIRO_SURFACE_TYPE_QUARTZ2
} cairo_surface_type_t;
cairo_public cairo_surface_type_t
cairo_surface_get_type (cairo_surface_t *surface);
#if CAIRO_HAS_PNG_FUNCTIONS
@ -1323,6 +1416,43 @@ cairo_pattern_destroy (cairo_pattern_t *pattern);
cairo_public cairo_status_t
cairo_pattern_status (cairo_pattern_t *pattern);
/**
* cairo_pattern_type_t
* @CAIRO_PATTERN_TYPE_SOLID: The pattern is a solid (uniform)
* color. It may be opaque or translucent.
* @CAIRO_PATTERN_TYPE_SURFACE: The pattern is a based on a surface (an image).
* @CAIRO_PATTERN_TYPE_LINEAR: The pattern is a linear gradient.
* @CAIRO_PATTERN_TYPE_RADIAL: The pattern is a radial gradient.
*
* @cairo_pattern_type_t us used to describe the type of a given pattern.
*
* The type of a pattern is determined by the function used to create
* it. The cairo_pattern_create_rgb() and cairo_pattern_create_rgba()
* functions create SOLID patterns. The remaining
* cairo_pattern_create functions map to pattern types in obvious
* ways.
*
* The pattern type can be queried with cairo_pattern_get_type()
*
* Most cairo_pattern functions can be called with a pattern of any
* type, (though trying to change the extend or filter for a solid
* pattern will have no effect). A notable exception is
* cairo_pattern_add_color_stop_rgb() and
* cairo_pattern_add_color_stop_rgba() which must only be called with
* gradient patterns (either LINEAR or RADIAL). Otherwise the pattern
* will be shutdown and put into an error state.
*/
typedef enum _cairo_pattern_type {
CAIRO_PATTERN_TYPE_SOLID,
CAIRO_PATTERN_TYPE_SURFACE,
CAIRO_PATTERN_TYPE_LINEAR,
CAIRO_PATTERN_TYPE_RADIAL
} cairo_pattern_type_t;
cairo_public cairo_pattern_type_t
cairo_pattern_get_type (cairo_pattern_t *pattern);
cairo_public void
cairo_pattern_add_color_stop_rgb (cairo_pattern_t *pattern,
double offset,

Просмотреть файл

@ -66,10 +66,6 @@
#include "cairo-debug.h"
#include <pixman.h>
#ifndef M_PI
#define M_PI 3.14159265358979323846
#endif
CAIRO_BEGIN_DECLS
#if __GNUC__ >= 3 && defined(__ELF__)
@ -187,6 +183,10 @@ cairo_private void _cairo_beos_unlock(void*);
#define TRUE 1
#endif
#ifndef M_PI
#define M_PI 3.14159265358979323846
#endif
#define ASSERT_NOT_REACHED \
do { \
static const int NOT_REACHED = 0; \
@ -259,6 +259,14 @@ typedef enum cairo_int_status {
CAIRO_INT_STATUS_CACHE_EMPTY
} cairo_int_status_t;
typedef enum cairo_internal_surface_type {
CAIRO_INTERNAL_SURFACE_TYPE_META = 0x1000,
CAIRO_INTERNAL_SURFACE_TYPE_PAGINATED,
CAIRO_INTERNAL_SURFACE_TYPE_TEST_META,
CAIRO_INTERNAL_SURFACE_TYPE_TEST_FALLBACK,
CAIRO_INTERNAL_SURFACE_TYPE_TEST_PAGINATED
} cairo_internal_surface_type_t;
typedef enum cairo_direction {
CAIRO_DIRECTION_FORWARD,
CAIRO_DIRECTION_REVERSE
@ -345,7 +353,7 @@ struct _cairo_array {
cairo_private void
_cairo_array_init (cairo_array_t *array, int element_size);
void
cairo_private void
_cairo_array_init_snapshot (cairo_array_t *array,
const cairo_array_t *other);
@ -366,7 +374,7 @@ _cairo_array_append_multiple (cairo_array_t *array,
const void *elements,
int num_elements);
cairo_status_t
cairo_private cairo_status_t
_cairo_array_allocate (cairo_array_t *array,
int num_elements,
void **elements);
@ -467,6 +475,7 @@ struct _cairo_scaled_font {
};
struct _cairo_font_face {
/* hash_entry must be first */
cairo_hash_entry_t hash_entry;
cairo_status_t status;
int ref_count;
@ -511,6 +520,8 @@ typedef enum _cairo_scaled_glyph_info {
} cairo_scaled_glyph_info_t;
struct _cairo_scaled_font_backend {
cairo_font_type_t type;
cairo_status_t
(*create_toy) (cairo_toy_font_face_t *toy_face,
const cairo_matrix_t *font_matrix,
@ -558,6 +569,8 @@ struct _cairo_scaled_font_backend {
};
struct _cairo_font_face_backend {
cairo_font_type_t type;
/* The destroy() function is allowed to resurrect the font face
* by re-referencing. This is needed for the FreeType backend.
*/
@ -602,6 +615,8 @@ typedef struct _cairo_stroke_style {
} cairo_stroke_style_t;
struct _cairo_surface_backend {
cairo_surface_type_t type;
cairo_surface_t *
(*create_similar) (void *surface,
cairo_content_t content,
@ -777,7 +792,7 @@ struct _cairo_surface_backend {
/* OK, I'm starting over somewhat by defining the 5 top-level
* drawing operators for the surface backend here with consistent
* naming and argument-order convensions. */
* naming and argument-order conventions. */
cairo_int_status_t
(*paint) (void *surface,
cairo_operator_t op,
@ -832,6 +847,11 @@ typedef struct _cairo_format_masks {
struct _cairo_surface {
const cairo_surface_backend_t *backend;
/* We allow surfaces to override the backend->type by shoving something
* else into surface->type. This is for "wrapper" surfaces that want to
* hide their internal type from the user-level API. */
cairo_surface_type_t type;
unsigned int ref_count;
cairo_status_t status;
cairo_bool_t finished;
@ -839,8 +859,6 @@ struct _cairo_surface {
double device_x_offset;
double device_y_offset;
double device_x_scale;
double device_y_scale;
cairo_clip_t *clip;
@ -912,13 +930,6 @@ typedef enum {
#define CAIRO_EXTEND_GRADIENT_DEFAULT CAIRO_EXTEND_PAD
#define CAIRO_FILTER_DEFAULT CAIRO_FILTER_BEST
typedef enum {
CAIRO_PATTERN_SOLID,
CAIRO_PATTERN_SURFACE,
CAIRO_PATTERN_LINEAR,
CAIRO_PATTERN_RADIAL
} cairo_pattern_type_t;
struct _cairo_pattern {
cairo_pattern_type_t type;
unsigned int ref_count;
@ -1043,6 +1054,8 @@ _cairo_restrict_value (double *value, double min, double max);
cairo_private cairo_fixed_t
_cairo_fixed_from_int (int i);
#define CAIRO_FIXED_ONE _cairo_fixed_from_int (1)
cairo_private cairo_fixed_t
_cairo_fixed_from_double (double d);
@ -1074,9 +1087,6 @@ _cairo_gstate_destroy (cairo_gstate_t *gstate);
cairo_private cairo_gstate_t *
_cairo_gstate_clone (cairo_gstate_t *gstate);
cairo_private void
_moz_cairo_gstate_set_target (cairo_gstate_t *gstate, cairo_surface_t *target);
cairo_private cairo_bool_t
_cairo_gstate_is_redirected (cairo_gstate_t *gstate);
@ -1092,6 +1102,9 @@ _cairo_gstate_get_parent_target (cairo_gstate_t *gstate);
cairo_private cairo_surface_t *
_cairo_gstate_get_original_target (cairo_gstate_t *gstate);
cairo_private void
_cairo_gstate_get_target_offsets_from_original (cairo_gstate_t *gstate, double *dx, double *dy);
cairo_private cairo_clip_t *
_cairo_gstate_get_clip (cairo_gstate_t *gstate);
@ -1238,15 +1251,6 @@ _cairo_gstate_clip (cairo_gstate_t *gstate, cairo_path_fixed_t *path);
cairo_private cairo_status_t
_cairo_gstate_reset_clip (cairo_gstate_t *gstate);
cairo_private cairo_bool_t
_cairo_gstate_has_clip (cairo_gstate_t *gstate);
cairo_private cairo_bool_t
_cairo_gstate_extract_clip_rectangles (cairo_gstate_t *gstate,
int max_rectangles,
cairo_clip_rect_t *rectangles_out,
int *num_rectangles_out);
cairo_private cairo_status_t
_cairo_gstate_show_surface (cairo_gstate_t *gstate,
cairo_surface_t *surface,
@ -1261,6 +1265,15 @@ _cairo_gstate_select_font_face (cairo_gstate_t *gstate,
cairo_font_slant_t slant,
cairo_font_weight_t weight);
cairo_private cairo_bool_t
_cairo_gstate_has_clip (cairo_gstate_t *gstate);
cairo_private cairo_bool_t
_cairo_gstate_extract_clip_rectangles (cairo_gstate_t *gstate,
int max_rectangles,
cairo_clip_rect_t *rectangles_out,
int *num_rectangles_out);
cairo_private cairo_status_t
_cairo_gstate_set_font_size (cairo_gstate_t *gstate,
double size);
@ -1410,13 +1423,13 @@ cairo_private cairo_status_t
_cairo_path_fixed_init_copy (cairo_path_fixed_t *path,
cairo_path_fixed_t *other);
cairo_path_fixed_t *
cairo_private cairo_path_fixed_t *
_cairo_path_fixed_create (void);
cairo_private void
_cairo_path_fixed_fini (cairo_path_fixed_t *path);
void
cairo_private void
_cairo_path_fixed_destroy (cairo_path_fixed_t *path);
cairo_private cairo_status_t
@ -1491,11 +1504,9 @@ _cairo_path_fixed_bounds (cairo_path_fixed_t *path,
double *x2, double *y2);
cairo_private void
_cairo_path_fixed_offset_and_scale (cairo_path_fixed_t *path,
cairo_fixed_t offx,
cairo_fixed_t offy,
cairo_fixed_t scalex,
cairo_fixed_t scaley);
_cairo_path_fixed_offset (cairo_path_fixed_t *path,
cairo_fixed_t offx,
cairo_fixed_t offy);
/* cairo_path_fill.c */
cairo_private cairo_status_t
@ -1589,7 +1600,7 @@ _cairo_scaled_glyph_set_path (cairo_scaled_glyph_t *scaled_glyph,
cairo_scaled_font_t *scaled_font,
cairo_path_fixed_t *path);
cairo_status_t
cairo_private cairo_status_t
_cairo_scaled_glyph_lookup (cairo_scaled_font_t *scaled_font,
unsigned long index,
cairo_scaled_glyph_info_t info,
@ -1838,6 +1849,9 @@ _cairo_surface_composite_shape_fixup_unbounded (cairo_surface_t *dst,
unsigned int width,
unsigned int height);
cairo_private cairo_bool_t
_cairo_surface_has_device_offset_or_scale (cairo_surface_t *surface);
/* cairo_image_surface.c */
#define CAIRO_FORMAT_VALID(format) ((format) >= CAIRO_FORMAT_ARGB32 && \
@ -1855,7 +1869,7 @@ _cairo_format_from_content (cairo_content_t content);
cairo_private cairo_content_t
_cairo_content_from_format (cairo_format_t format);
cairo_surface_t *
cairo_private cairo_surface_t *
_cairo_image_surface_create_for_pixman_image (pixman_image_t *pixman_image,
cairo_format_t format);
@ -2113,7 +2127,7 @@ _cairo_pattern_acquire_surfaces (cairo_pattern_t *src,
cairo_surface_attributes_t *src_attributes,
cairo_surface_attributes_t *mask_attributes);
cairo_status_t
cairo_private cairo_status_t
_cairo_pattern_get_extents (cairo_pattern_t *pattern,
cairo_rectangle_t *extents);
@ -2167,6 +2181,16 @@ _cairo_output_stream_write_hex_string (cairo_output_stream_t *stream,
const char *data,
size_t length);
cairo_private void
_cairo_output_stream_write_base85_string (cairo_output_stream_t *stream,
const char *data,
size_t length);
cairo_private void *
_cairo_compress_lzw (void *data,
unsigned long data_size,
unsigned long *compressed_size);
cairo_private cairo_status_t
_cairo_output_stream_vprintf (cairo_output_stream_t *stream,
const char *fmt, va_list ap);
@ -2191,7 +2215,6 @@ cairo_private int
_cairo_dtostr (char *buffer, size_t size, double d);
/* Avoid unnecessary PLT entries. */
slim_hidden_proto(cairo_get_current_point)
slim_hidden_proto(cairo_fill_preserve)
slim_hidden_proto(cairo_clip_preserve)
@ -2217,7 +2240,6 @@ slim_hidden_proto(cairo_push_group)
slim_hidden_proto(cairo_push_group_with_content)
slim_hidden_proto(cairo_pop_group)
slim_hidden_proto(cairo_pop_group_to_source)
slim_hidden_proto(moz_cairo_set_target)
CAIRO_END_DECLS

Просмотреть файл

@ -175,6 +175,7 @@ _test_fallback_surface_get_extents (void *abstract_surface,
}
const cairo_surface_backend_t test_fallback_surface_backend = {
CAIRO_INTERNAL_SURFACE_TYPE_TEST_FALLBACK,
_test_fallback_surface_create_similar,
_test_fallback_surface_finish,
_test_fallback_surface_acquire_source_image,

Просмотреть файл

@ -296,6 +296,7 @@ _test_meta_surface_snapshot (void *abstract_other)
}
const cairo_surface_backend_t test_meta_surface_backend = {
CAIRO_INTERNAL_SURFACE_TYPE_TEST_META,
NULL, /* create_similar */
_test_meta_surface_finish,
_test_meta_surface_acquire_source_image,

Просмотреть файл

@ -44,7 +44,6 @@
#define M_PI 3.14159265358979323846
#endif
/* #define PIXMAN_CONVOLUTION */
/* #define PIXMAN_INDEXED_FORMATS */

Просмотреть файл

@ -1,6 +1,4 @@
/*
* $Id: fbedge.c,v 1.10 2006/03/17 07:44:26 vladimir%pobox.com Exp $
*
* Copyright © 2004 Keith Packard
*
* Permission to use, copy, modify, distribute, and sell this software and its

Просмотреть файл

@ -1,6 +1,4 @@
/*
* $Id: fbedgeimp.h,v 1.10 2006/03/17 07:44:26 vladimir%pobox.com Exp $
*
* Copyright © 2004 Keith Packard
*
* Permission to use, copy, modify, distribute, and sell this software and its

Просмотреть файл

@ -1,6 +1,4 @@
/*
* $Id: fbpict.c,v 1.7 2006/03/17 07:44:26 vladimir%pobox.com Exp $
*
* Copyright © 2000 SuSE, Inc.
*
* Permission to use, copy, modify, distribute, and sell this software and its
@ -1151,7 +1149,7 @@ fbCompositeTrans_0888xnx0888(pixman_operator_t op,
setupPackedReader(ws,wt,isrc,wsrc,workingSource);
/* get to word aligned */
switch(!(long)dst&3)
switch(~(long)dst&3)
{
case 1:
readPackedSource(rs);
@ -1227,7 +1225,7 @@ fbCompositeTrans_0888xnx0888(pixman_operator_t op,
srcLine += srcStride;
w = width*3;
/* get to word aligned */
switch(!(long)src&3)
switch(~(long)src&3)
{
case 1:
rd=alphamaskCombine24(*src++, *dst)>>8;

Просмотреть файл

@ -1,6 +1,4 @@
/*
* $Id: fbpict.h,v 1.7 2006/03/17 07:44:26 vladimir%pobox.com Exp $
*
* Copyright © 2000 Keith Packard
* 2005 Lars Knoll & Zack Rusin, Trolltech
*

Просмотреть файл

@ -1,5 +1,5 @@
/*
* $Id: fbtrap.c,v 1.10 2006/03/17 07:44:26 vladimir%pobox.com Exp $
* $Id: fbtrap.c,v 1.11 2006/03/17 22:24:10 vladimir%pobox.com Exp $
*
* Copyright © 2004 Keith Packard
*

Просмотреть файл

@ -1,6 +1,4 @@
/*
* $Id: icpixels.c,v 1.10 2006/03/17 07:44:26 vladimir%pobox.com Exp $
*
* Copyright © 1998 Keith Packard
*
* Permission to use, copy, modify, distribute, and sell this software and its

Просмотреть файл

@ -1,6 +1,4 @@
/*
* $Id: ictrap.c,v 1.10 2006/03/17 07:44:26 vladimir%pobox.com Exp $
*
* Copyright © 2002 Keith Packard
*
* Permission to use, copy, modify, distribute, and sell this software and its

Просмотреть файл

@ -47,6 +47,8 @@
#define pixman_image_set_filter _cairo_pixman_image_set_filter
#define pixman_image_set_repeat _cairo_pixman_image_set_repeat
#define pixman_image_set_transform _cairo_pixman_image_set_transform
#define pixman_image_create_linear_gradient _cairo_pixman_image_create_linear_gradient
#define pixman_image_create_radial_gradient _cairo_pixman_image_create_radial_gradient
#define miIsSolidAlpha _cairo_pixman_is_solid_alpha
#define pixman_pixel_to_color _cairo_pixman_pixel_to_color
#define pixman_region_append _cairo_pixman_region_append

Просмотреть файл

@ -54,8 +54,6 @@ ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
SOFTWARE.
******************************************************************/
/* $Id: pixman.h,v 1.13 2006/03/17 07:44:26 vladimir%pobox.com Exp $ */
/* libic.h */
/*

Просмотреть файл

@ -44,8 +44,6 @@ ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
SOFTWARE.
******************************************************************/
/* $Id: pixregionint.h,v 1.10 2006/03/17 07:44:26 vladimir%pobox.com Exp $ */
#ifndef _PIXREGIONINT_H_
#define _PIXREGIONINT_H_

Просмотреть файл

@ -1,6 +1,4 @@
/*
* $Id: renderedge.c,v 1.10 2006/03/17 07:44:26 vladimir%pobox.com Exp $
*
* Copyright © 2004 Keith Packard
*
* Permission to use, copy, modify, distribute, and sell this software and its

Просмотреть файл

@ -1,6 +1,4 @@
/*
* $Id: renderedge.h,v 1.10 2006/03/17 07:44:26 vladimir%pobox.com Exp $
*
* Copyright © 2004 Keith Packard
*
* Permission to use, copy, modify, distribute, and sell this software and its

Просмотреть файл

@ -402,19 +402,19 @@ nsThebesFontMetrics::DrawString(const PRUnichar* aString, PRUint32 aLength,
// back.
nsresult
nsThebesFontMetrics::GetBoundingMetrics(const char *aString, PRUint32 aLength,
nsBoundingMetrics &aBoundingMetrics)
nsBoundingMetrics &aBoundingMetrics)
{
return NS_OK;
return NS_ERROR_NOT_IMPLEMENTED;
}
// aCachedOffset will be updated with a new offset.
nsresult
nsThebesFontMetrics::GetBoundingMetrics(const PRUnichar *aString,
PRUint32 aLength,
nsBoundingMetrics &aBoundingMetrics,
PRInt32 *aFontID)
PRUint32 aLength,
nsBoundingMetrics &aBoundingMetrics,
PRInt32 *aFontID)
{
return NS_OK;
return NS_ERROR_NOT_IMPLEMENTED;
}
#endif /* MOZ_MATHML */

Просмотреть файл

@ -51,7 +51,6 @@
#include "gfxFont.h"
class gfxRegion;
class gfxFilter;
class gfxTextRun;
/**
@ -81,9 +80,13 @@ public:
gfxASurface *CurrentSurface();
/**
* Return the current transparency group target, if any
* Return the current transparency group target, if any, along
* with its device offsets from the top.
*/
already_AddRefed<gfxASurface> CurrentGroupSurface();
already_AddRefed<gfxASurface> CurrentGroupSurface(gfxFloat *dx, gfxFloat *dy);
already_AddRefed<gfxASurface> CurrentGroupSurface() {
return CurrentGroupSurface(NULL, NULL);
}
/**
* Return the raw cairo_t object.

Просмотреть файл

@ -41,15 +41,20 @@
#include <stdlib.h>
#include <stdint.h>
/*#include <stdio.h>
#define CAIRO_XLIB_DRAWING_NOTE(m) fprintf(stderr, m) */
#if 0
#include <stdio.h>
#define CAIRO_XLIB_DRAWING_NOTE(m) fprintf(stderr, m)
#else
#define CAIRO_XLIB_DRAWING_NOTE(m) do {} while (0)
#endif
static cairo_surface_t *_get_current_target (cairo_t *cr)
static cairo_surface_t *_get_current_target (cairo_t *cr, double *dx, double *dy)
{
cairo_surface_t *target = cairo_get_group_target (cr);
cairo_surface_t *target = cairo_get_group_target (cr, dx, dy);
if (target == NULL) {
target = cairo_get_target (cr);
*dx = 0.0;
*dy = 0.0;
}
return target;
}
@ -116,7 +121,6 @@ _intersect_interval (double a_begin, double a_end, double b_begin, double b_end,
#define MAX_STATIC_CLIP_RECTANGLES 50
static cairo_bool_t
_get_rectangular_clip (cairo_t *cr,
double device_offset_x, double device_offset_y,
int bounds_x, int bounds_y,
int bounds_width, int bounds_height,
cairo_bool_t *need_clip,
@ -136,17 +140,14 @@ _get_rectangular_clip (cairo_t *cr,
*need_clip = False;
return True;
}
if (!cairo_extract_clip_rectangles (cr, MAX_STATIC_CLIP_RECTANGLES, clips, &count))
return False;
for (i = 0; i < count; ++i) {
double intersect_x, intersect_y, intersect_x_most, intersect_y_most;
/* get the clip rect into surface coordinates */
clips[i].x += device_offset_x;
clips[i].y += device_offset_y;
/* the clip is always in surface backend coordinates (i.e. native backend coords) */
if (b_x >= clips[i].x && b_x_most <= clips[i].x + clips[i].width &&
b_y >= clips[i].y && b_y_most <= clips[i].y + clips[i].height) {
/* the bounds are entirely inside the clip region so we don't need to clip. */
@ -191,8 +192,8 @@ _draw_with_xlib_direct (cairo_t *cr,
int bounds_width, int bounds_height,
cairo_xlib_drawing_support_t capabilities)
{
cairo_surface_t *target = _get_current_target (cr);
Drawable d = cairo_xlib_surface_get_drawable (target);
cairo_surface_t *target;
Drawable d;
cairo_matrix_t matrix;
short offset_x, offset_y;
cairo_bool_t needs_clip;
@ -203,8 +204,10 @@ _draw_with_xlib_direct (cairo_t *cr,
Display *dpy;
Visual *visual;
target = _get_current_target (cr, &device_offset_x, &device_offset_y);
d = cairo_xlib_surface_get_drawable (target);
cairo_get_matrix (cr, &matrix);
cairo_surface_get_device_offset (target, &device_offset_x, &device_offset_y);
/* Check that the matrix is a pure translation */
/* XXX test some approximation to == 1.0 here? */
@ -214,8 +217,8 @@ _draw_with_xlib_direct (cairo_t *cr,
}
/* Check that the matrix translation offsets (adjusted for
device offset) are integers */
if (!_convert_coord_to_short (matrix.x0 + device_offset_x, &offset_x) ||
!_convert_coord_to_short (matrix.y0 + device_offset_y, &offset_y)) {
if (!_convert_coord_to_short (matrix.x0 - device_offset_x, &offset_x) ||
!_convert_coord_to_short (matrix.y0 - device_offset_y, &offset_y)) {
CAIRO_XLIB_DRAWING_NOTE("TAKING SLOW PATH: non-integer offset\n");
return False;
}
@ -229,7 +232,7 @@ _draw_with_xlib_direct (cairo_t *cr,
}
/* Check that the clip is rectangular and aligned on unit boundaries */
if (!_get_rectangular_clip (cr, device_offset_x, device_offset_y,
if (!_get_rectangular_clip (cr,
offset_x, offset_y, bounds_width, bounds_height,
&needs_clip,
rectangles, max_rectangles, &rect_count)) {
@ -565,7 +568,7 @@ cairo_draw_with_xlib (cairo_t *cr,
used for 'cr', which is ideal if it's going to be cached and reused.
We do not return an image if the result has uniform color and alpha. */
if (result && (!result->uniform_alpha || !result->uniform_color)) {
cairo_surface_t *target = _get_current_target (cr);
cairo_surface_t *target = _get_current_target (cr, NULL, NULL);
cairo_surface_t *similar_surface =
cairo_surface_create_similar (target, CAIRO_CONTENT_COLOR_ALPHA,
width, height);

Просмотреть файл

@ -73,11 +73,14 @@ gfxASurface *gfxContext::CurrentSurface()
return mSurface;
}
already_AddRefed<gfxASurface> gfxContext::CurrentGroupSurface()
already_AddRefed<gfxASurface> gfxContext::CurrentGroupSurface(gfxFloat *dx, gfxFloat *dy)
{
cairo_surface_t *s = cairo_get_group_target(mCairo);
if (!s)
cairo_surface_t *s = cairo_get_group_target(mCairo, dx, dy);
if (!s) {
*dx = 0.0;
*dy = 0.0;
return NULL;
}
gfxASurface *wrapper = new gfxUnknownSurface(s);
NS_ADDREF(wrapper);

Просмотреть файл

@ -62,8 +62,8 @@ gfxWindowsSurface::gfxWindowsSurface(HDC dc, unsigned long width, unsigned long
// with CreateCompatibleDC, but from stuff that I've read
// that's only useful for terminal services clients.
Init(cairo_win32_surface_create_dib((cairo_format_t)imageFormat,
width, height));
Init(cairo_win32_surface_create_with_dib((cairo_format_t)imageFormat,
width, height));
mDC = cairo_win32_surface_get_dc(CairoSurface());
}

Просмотреть файл

@ -83,6 +83,10 @@ ifdef SUNCTL
REQUIRES += ctl
endif
ifdef MOZ_ENABLE_CAIRO_GFX
REQUIRES += thebes cairo
endif
EXPORTS = \
nsFrameList.h \
nsHTMLParts.h \

Просмотреть файл

@ -1102,19 +1102,20 @@ nsObjectFrame::PaintPlugin(nsIRenderingContext& aRenderingContext,
SaveDC(hdc);
nsRefPtr<gfxContext> ctx = (gfxContext*)aRenderingContext.GetNativeGraphicData(nsIRenderingContext::NATIVE_THEBES_CONTEXT);
nsRefPtr<gfxASurface> surf = ctx->CurrentGroupSurface();
if (!surf)
gfxFloat xoff, yoff;
nsRefPtr<gfxASurface> surf = ctx->CurrentGroupSurface(&xoff, &yoff);
if (!surf) {
surf = ctx->CurrentSurface();
xoff = yoff = 0.0;
}
/* Need to force the clip to be set */
ctx->UpdateSurfaceClip();
/* Set the device offsets as appropriate */
gfxFloat xoff, yoff;
POINT origViewportOrigin;
surf->GetDeviceOffset(&xoff, &yoff);
GetViewportOrgEx(hdc, &origViewportOrigin);
SetViewportOrgEx(hdc, origViewportOrigin.x + (int) xoff, origViewportOrigin.y + (int) yoff, NULL);
SetViewportOrgEx(hdc, origViewportOrigin.x - (int) xoff, origViewportOrigin.y - (int) yoff, NULL);
#endif
if (NS_REINTERPRET_CAST(PRUint32, window->window) != (PRUint32)(HDC)hdc) {

Просмотреть файл

@ -761,9 +761,12 @@ nsNativeThemeWin::DrawWidgetBackground(nsIRenderingContext* aContext,
nsRefPtr<gfxContext> ctx = (gfxContext*)aContext->GetNativeGraphicData(nsIRenderingContext::NATIVE_THEBES_CONTEXT);
nsRefPtr<gfxASurface> surf = ctx->CurrentGroupSurface();
if (!surf)
gfxFloat xoff, yoff;
nsRefPtr<gfxASurface> surf = ctx->CurrentGroupSurface(&xoff, &yoff);
if (!surf) {
surf = ctx->CurrentSurface();
xoff = yoff = 0.0;
}
HDC hdc = cairo_win32_surface_get_dc (surf->CairoSurface());
SaveDC(hdc);
@ -775,11 +778,9 @@ nsNativeThemeWin::DrawWidgetBackground(nsIRenderingContext* aContext,
//ctx->CurrentSurface()->Flush();
/* Set the device offsets as appropriate */
gfxFloat xoff, yoff;
POINT origViewportOrigin;
surf->GetDeviceOffset(&xoff, &yoff);
GetViewportOrgEx(hdc, &origViewportOrigin);
SetViewportOrgEx(hdc, origViewportOrigin.x + (int) xoff, origViewportOrigin.y + (int) yoff, NULL);
SetViewportOrgEx(hdc, origViewportOrigin.x - (int) xoff, origViewportOrigin.y - (int) yoff, NULL);
/* Covert the current transform to a world transform */
gfxMatrix m = ctx->CurrentMatrix();
@ -1811,9 +1812,12 @@ nsresult nsNativeThemeWin::ClassicDrawWidgetBackground(nsIRenderingContext* aCon
nsRefPtr<gfxContext> ctx = (gfxContext*)aContext->GetNativeGraphicData(nsIRenderingContext::NATIVE_THEBES_CONTEXT);
nsRefPtr<gfxASurface> surf = ctx->CurrentGroupSurface();
if (!surf)
gfxFloat xoff, yoff;
nsRefPtr<gfxASurface> surf = ctx->CurrentGroupSurface(&xoff, &yoff);
if (!surf) {
surf = ctx->CurrentSurface();
xoff = yoff = 0.0;
}
HDC hdc = cairo_win32_surface_get_dc (surf->CairoSurface());
SaveDC(hdc);
@ -1823,11 +1827,9 @@ nsresult nsNativeThemeWin::ClassicDrawWidgetBackground(nsIRenderingContext* aCon
ctx->UpdateSurfaceClip();
/* Set the device offsets as appropriate */
gfxFloat xoff, yoff;
POINT origViewportOrigin;
surf->GetDeviceOffset(&xoff, &yoff);
GetViewportOrgEx(hdc, &origViewportOrigin);
SetViewportOrgEx(hdc, origViewportOrigin.x + (int) xoff, origViewportOrigin.y + (int) yoff, NULL);
SetViewportOrgEx(hdc, origViewportOrigin.x - (int) xoff, origViewportOrigin.y - (int) yoff, NULL);
/* Covert the current transform to a world transform */
gfxMatrix m = ctx->CurrentMatrix();