backout [mq]: cairo-rollback.patch

git-svn-id: svn://10.0.0.236/trunk@249704 18797224-902f-48f8-a5cc-f745e15eee43
This commit is contained in:
vladimir%pobox.com 2008-04-06 23:34:12 +00:00
parent a469b83e7f
commit b6e1ca553a
69 changed files with 6949 additions and 8357 deletions

1475
mozilla/configure vendored

File diff suppressed because it is too large Load Diff

View File

@ -7181,7 +7181,7 @@ if test "$MOZ_TREE_CAIRO"; then
if test "$MOZ_WIDGET_TOOLKIT" = "mac" -o "$MOZ_WIDGET_TOOLKIT" = "cocoa"; then
QUARTZ_SURFACE_FEATURE="#define CAIRO_HAS_QUARTZ_SURFACE 1"
QUARTZ_IMAGE_SURFACE_FEATURE="#define CAIRO_HAS_QUARTZ_IMAGE_SURFACE 1"
QUARTZ_FONT_FEATURE="#define CAIRO_HAS_QUARTZ_FONT 1"
ATSUI_FONT_FEATURE="#define CAIRO_HAS_ATSUI_FONT 1"
fi
if test "$MOZ_WIDGET_TOOLKIT" = "windows"; then
WIN32_SURFACE_FEATURE="#define CAIRO_HAS_WIN32_SURFACE 1"
@ -7231,7 +7231,7 @@ if test "$MOZ_TREE_CAIRO"; then
AC_SUBST(DIRECTFB_SURFACE_FEATURE)
AC_SUBST(FT_FONT_FEATURE)
AC_SUBST(WIN32_FONT_FEATURE)
AC_SUBST(QUARTZ_FONT_FEATURE)
AC_SUBST(ATSUI_FONT_FEATURE)
AC_SUBST(PNG_FUNCTIONS_FEATURE)
if test "$_WIN32_MSVC"; then

View File

@ -7,8 +7,8 @@ http://www.cairographics.org/.
VERSIONS:
cairo (1.6.x - 1.5.18-3-g3d22902)
pixman (0.10.x - pixman-0.10.0-8-g0b207ae)
cairo (1.5.x - 1.5.12-56-ga33351f)
pixman (0.9.x - pixman-0.9.6-43-gddfb69a)
glitz 0.5.2 (cvs - 2006-01-10)
***** NOTE FOR VISUAL C++ 6.0 *****

View File

@ -164,8 +164,8 @@ EXPORTS += $(PDF_EXPORTS)
endif
ifneq (,$(filter mac cocoa,$(MOZ_WIDGET_TOOLKIT)))
CSRCS += cairo-quartz-surface.c cairo-quartz-image-surface.c cairo-quartz-font.c
EXPORTS += cairo-quartz.h cairo-quartz-image.h
CSRCS += cairo-quartz-surface.c cairo-quartz-image-surface.c cairo-atsui-font.c
EXPORTS += cairo-quartz.h cairo-atsui.h cairo-quartz-image.h
endif
ifeq ($(MOZ_WIDGET_TOOLKIT),beos)
@ -186,7 +186,6 @@ endif
ifdef MOZ_X11
CSRCS += cairo-xlib-surface.c \
cairo-xlib-screen.c \
cairo-xlib-visual.c \
cairo-xlib-display.c
EXPORTS += cairo-xlib.h cairo-xlib-xrender.h
endif

View File

@ -125,20 +125,8 @@ _cairo_analysis_surface_add_operation (cairo_analysis_surface_t *surface,
cairo_int_status_t status;
cairo_box_t bbox;
if (rect->width == 0 || rect->height == 0) {
/* Even though the operation is not visible we must be careful
* to not allow unsupported operations to be replayed to the
* backend during CAIRO_PAGINATED_MODE_RENDER */
if (backend_status == CAIRO_STATUS_SUCCESS ||
backend_status == CAIRO_INT_STATUS_FLATTEN_TRANSPARENCY)
{
return CAIRO_STATUS_SUCCESS;
}
else
{
return CAIRO_INT_STATUS_IMAGE_FALLBACK;
}
}
if (rect->width == 0 || rect->height == 0)
return CAIRO_STATUS_SUCCESS;
if (surface->has_ctm) {
double x1, y1, x2, y2;
@ -155,21 +143,8 @@ _cairo_analysis_surface_add_operation (cairo_analysis_surface_t *surface,
x2 = ceil (x2) - rect->x;
y2 = ceil (y2) - rect->y;
if (x2 <= 0 || y2 <= 0) {
/* Even though the operation is not visible we must be
* careful to not allow unsupported operations to be
* replayed to the backend during
* CAIRO_PAGINATED_MODE_RENDER */
if (backend_status == CAIRO_STATUS_SUCCESS ||
backend_status == CAIRO_INT_STATUS_FLATTEN_TRANSPARENCY)
{
return CAIRO_STATUS_SUCCESS;
}
else
{
return CAIRO_INT_STATUS_IMAGE_FALLBACK;
}
}
if (x2 <= 0 || y2 <= 0)
return CAIRO_STATUS_SUCCESS;
rect->width = x2;
rect->height = y2;
@ -459,23 +434,17 @@ _cairo_analysis_surface_stroke (void *abstract_surface,
ctm, ctm_inverse,
tolerance,
&traps);
if (status) {
if (status || traps.num_traps == 0) {
_cairo_traps_fini (&traps);
return status;
}
if (traps.num_traps == 0) {
extents.x = 0;
extents.y = 0;
extents.width = 0;
extents.height = 0;
} else {
_cairo_traps_extents (&traps, &box);
extents.x = _cairo_fixed_integer_floor (box.p1.x);
extents.y = _cairo_fixed_integer_floor (box.p1.y);
extents.width = _cairo_fixed_integer_ceil (box.p2.x) - extents.x;
extents.height = _cairo_fixed_integer_ceil (box.p2.y) - extents.y;
}
_cairo_traps_extents (&traps, &box);
extents.x = _cairo_fixed_integer_floor (box.p1.x);
extents.y = _cairo_fixed_integer_floor (box.p1.y);
extents.width = _cairo_fixed_integer_ceil (box.p2.x) - extents.x;
extents.height = _cairo_fixed_integer_ceil (box.p2.y) - extents.y;
_cairo_traps_fini (&traps);
}
@ -537,23 +506,17 @@ _cairo_analysis_surface_fill (void *abstract_surface,
fill_rule,
tolerance,
&traps);
if (status) {
if (status || traps.num_traps == 0) {
_cairo_traps_fini (&traps);
return status;
}
if (traps.num_traps == 0) {
extents.x = 0;
extents.y = 0;
extents.width = 0;
extents.height = 0;
} else {
_cairo_traps_extents (&traps, &box);
extents.x = _cairo_fixed_integer_floor (box.p1.x);
extents.y = _cairo_fixed_integer_floor (box.p1.y);
extents.width = _cairo_fixed_integer_ceil (box.p2.x) - extents.x;
extents.height = _cairo_fixed_integer_ceil (box.p2.y) - extents.y;
}
_cairo_traps_extents (&traps, &box);
extents.x = _cairo_fixed_integer_floor (box.p1.x);
extents.y = _cairo_fixed_integer_floor (box.p1.y);
extents.width = _cairo_fixed_integer_ceil (box.p2.x) - extents.x;
extents.height = _cairo_fixed_integer_ceil (box.p2.y) - extents.y;
_cairo_traps_fini (&traps);
}

View File

@ -110,19 +110,15 @@ _cairo_array_fini (cairo_array_t *array)
* is always increased by doubling as many times as necessary.
**/
cairo_status_t
_cairo_array_grow_by (cairo_array_t *array, unsigned int additional)
_cairo_array_grow_by (cairo_array_t *array, int additional)
{
char *new_elements;
unsigned int old_size = array->size;
unsigned int required_size = array->num_elements + additional;
unsigned int new_size;
int old_size = array->size;
int required_size = array->num_elements + additional;
int new_size;
assert (! array->is_snapshot);
/* check for integer overflow */
if (required_size > INT_MAX || required_size < array->num_elements)
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
if (required_size <= old_size)
return CAIRO_STATUS_SUCCESS;

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,58 @@
/* cairo - a vector graphics library with display and print output
*
* Copyright © 2004 Calum Robinson
*
* 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.
*
* The Initial Developer of the Original Code is Calum Robinson
*
* Contributor(s):
* Calum Robinson <calumr@mac.com>
*/
#ifndef CAIRO_ATSUI_H
#define CAIRO_ATSUI_H
#include <cairo.h>
#if CAIRO_HAS_ATSUI_FONT
/* ATSUI platform-specific font interface */
#include <Carbon/Carbon.h>
CAIRO_BEGIN_DECLS
cairo_public cairo_font_face_t *
cairo_atsui_font_face_create_for_atsu_font_id (ATSUFontID font_id);
CAIRO_END_DECLS
#else /* CAIRO_HAS_ATSUI_FONT */
# error Cairo was not compiled with support for the atsui font backend
#endif /* CAIRO_HAS_ATSUI_FONT */
#endif /* CAIRO_ATSUI_H */

View File

@ -34,11 +34,6 @@
* Eugeniy Meshcheryakov <eugen@debian.org>
*/
/*
* Useful links:
* http://www.adobe.com/devnet/font/pdfs/5176.CFF.pdf
*/
#define _BSD_SOURCE /* for snprintf(), strdup() */
#include "cairoint.h"
#include "cairo-scaled-font-subsets-private.h"

View File

@ -50,8 +50,6 @@
*/
#define CAIRO_FORMAT_RGB16_565 4
#define CAIRO_FONT_TYPE_ATSUI CAIRO_FONT_TYPE_QUARTZ
#ifndef _CAIROINT_H_
/* Obsolete functions. These definitions exist to coerce the compiler
@ -106,7 +104,6 @@
#define cairo_ps_surface_set_dpi cairo_ps_surface_set_dpi_REPLACED_BY_cairo_surface_set_fallback_resolution
#define cairo_pdf_surface_set_dpi cairo_pdf_surface_set_dpi_REPLACED_BY_cairo_surface_set_fallback_resolution
#define cairo_svg_surface_set_dpi cairo_svg_surface_set_dpi_REPLACED_BY_cairo_surface_set_fallback_resolution
#define cairo_atsui_font_face_create_for_atsu_font_id cairo_atsui_font_face_create_for_atsu_font_id_REPLACED_BY_cairo_quartz_font_face_create_for_atsu_font_id
#define cairo_current_path cairo_current_path_DEPRECATED_BY_cairo_copy_path
#define cairo_current_path_flat cairo_current_path_flat_DEPRECATED_BY_cairo_copy_path_flat

View File

@ -53,9 +53,9 @@
#define CAIRO_VERSION_MAJOR 1
#define CAIRO_VERSION_MINOR 5
#define CAIRO_VERSION_MICRO 16
#define CAIRO_VERSION_MICRO 12
#define CAIRO_VERSION_STRING "1.5.16"
#define CAIRO_VERSION_STRING "1.5.12"
@PS_SURFACE_FEATURE@
@ -87,7 +87,7 @@
@WIN32_FONT_FEATURE@
@QUARTZ_FONT_FEATURE@
@ATSUI_FONT_FEATURE@
@PNG_FUNCTIONS_FEATURE@

View File

@ -433,7 +433,6 @@ _cairo_toy_font_face_create (const char *family,
return &font_face->base;
UNWIND_FONT_FACE_INIT:
_cairo_toy_font_face_fini (font_face);
UNWIND_FONT_FACE_MALLOC:
free (font_face);
UNWIND_HASH_TABLE_LOCK:

View File

@ -817,7 +817,7 @@ _cairo_glitz_pattern_acquire_surface (cairo_pattern_t *pattern,
(((int) (gradient->stops[i].color.green_short >> 8)) << 8) |
(((int) (gradient->stops[i].color.blue_short >> 8)));
params[n_base_params + 3 * i + 0] = _cairo_fixed_16_16_from_double (gradient->stops[i].offset);
params[n_base_params + 3 * i + 0] = gradient->stops[i].x;
params[n_base_params + 3 * i + 1] = i << 16;
params[n_base_params + 3 * i + 2] = 0;
}

View File

@ -255,7 +255,7 @@ _cairo_gstate_clone (cairo_gstate_t *other, cairo_gstate_t **out)
cairo_status_t
_cairo_gstate_save (cairo_gstate_t **gstate)
{
cairo_gstate_t *top = NULL;
cairo_gstate_t *top;
cairo_status_t status;
status = _cairo_gstate_clone (*gstate, &top);
@ -290,6 +290,27 @@ _cairo_gstate_restore (cairo_gstate_t **gstate)
return CAIRO_STATUS_SUCCESS;
}
static cairo_status_t
_cairo_gstate_recursive_apply_clip_path (cairo_gstate_t *gstate,
cairo_clip_path_t *cpath)
{
cairo_status_t status;
if (cpath == NULL)
return CAIRO_STATUS_SUCCESS;
status = _cairo_gstate_recursive_apply_clip_path (gstate, cpath->prev);
if (status)
return status;
return _cairo_clip_clip (&gstate->clip,
&cpath->path,
cpath->fill_rule,
cpath->tolerance,
cpath->antialias,
gstate->target);
}
/**
* _cairo_gstate_redirect_target:
* @gstate: a #cairo_gstate_t

View File

@ -192,7 +192,7 @@ cairo_status_t
_cairo_hull_compute (cairo_pen_vertex_t *vertices, int *num_vertices)
{
cairo_status_t status;
cairo_hull_t *hull = NULL;
cairo_hull_t *hull;
int num_hull = *num_vertices;
status = _cairo_hull_create (vertices, num_hull, &hull);

View File

@ -59,7 +59,6 @@ _cairo_format_from_pixman_format (pixman_format_code_t pixman_format)
case PIXMAN_a4: case PIXMAN_r1g2b1: case PIXMAN_b1g2r1:
case PIXMAN_a1r1g1b1: case PIXMAN_a1b1g1r1: case PIXMAN_c4:
case PIXMAN_g4: case PIXMAN_g1:
case PIXMAN_yuy2: case PIXMAN_yv12:
default:
return CAIRO_FORMAT_INVALID;
}
@ -101,8 +100,6 @@ _cairo_content_from_pixman_format (pixman_format_code_t pixman_format)
case PIXMAN_c4:
case PIXMAN_g4:
case PIXMAN_g1:
case PIXMAN_yuy2:
case PIXMAN_yv12:
return CAIRO_CONTENT_COLOR;
case PIXMAN_a8:
case PIXMAN_a1:
@ -144,104 +141,143 @@ _cairo_image_surface_create_for_pixman_image (pixman_image_t *pixman_image,
return &surface->base;
}
cairo_int_status_t
_pixman_format_from_masks (cairo_format_masks_t *masks,
pixman_format_code_t *format_ret)
/* XXX: This function should really live inside pixman. */
pixman_format_code_t
_pixman_format_from_masks (cairo_format_masks_t *masks)
{
pixman_format_code_t format;
int format_type;
int a, r, g, b;
cairo_format_masks_t format_masks;
a = _cairo_popcount (masks->alpha_mask);
r = _cairo_popcount (masks->red_mask);
g = _cairo_popcount (masks->green_mask);
b = _cairo_popcount (masks->blue_mask);
if (masks->red_mask) {
if (masks->red_mask > masks->blue_mask)
format_type = PIXMAN_TYPE_ARGB;
else
format_type = PIXMAN_TYPE_ABGR;
} else if (masks->alpha_mask) {
format_type = PIXMAN_TYPE_A;
} else {
return CAIRO_INT_STATUS_UNSUPPORTED;
switch (masks->bpp) {
case 32:
if (masks->alpha_mask == 0xff000000 &&
masks->red_mask == 0x00ff0000 &&
masks->green_mask == 0x0000ff00 &&
masks->blue_mask == 0x000000ff)
{
return PIXMAN_a8r8g8b8;
}
if (masks->alpha_mask == 0x00000000 &&
masks->red_mask == 0x00ff0000 &&
masks->green_mask == 0x0000ff00 &&
masks->blue_mask == 0x000000ff)
{
return PIXMAN_x8r8g8b8;
}
if (masks->alpha_mask == 0xff000000 &&
masks->red_mask == 0x000000ff &&
masks->green_mask == 0x0000ff00 &&
masks->blue_mask == 0x00ff0000)
{
return PIXMAN_a8b8g8r8;
}
if (masks->alpha_mask == 0x00000000 &&
masks->red_mask == 0x000000ff &&
masks->green_mask == 0x0000ff00 &&
masks->blue_mask == 0x00ff0000)
{
return PIXMAN_x8b8g8r8;
}
break;
case 16:
if (masks->alpha_mask == 0x0000 &&
masks->red_mask == 0xf800 &&
masks->green_mask == 0x07e0 &&
masks->blue_mask == 0x001f)
{
return PIXMAN_r5g6b5;
}
if (masks->alpha_mask == 0x0000 &&
masks->red_mask == 0x7c00 &&
masks->green_mask == 0x03e0 &&
masks->blue_mask == 0x001f)
{
return PIXMAN_x1r5g5b5;
}
break;
case 8:
if (masks->alpha_mask == 0xff)
{
return PIXMAN_a8;
}
break;
case 1:
if (masks->alpha_mask == 0x1)
{
return PIXMAN_a1;
}
break;
}
format = PIXMAN_FORMAT (masks->bpp, format_type, a, r, g, b);
fprintf (stderr,
"Error: Cairo " PACKAGE_VERSION " does not yet support the requested image format:\n"
"\tDepth: %d\n"
"\tAlpha mask: 0x%08lx\n"
"\tRed mask: 0x%08lx\n"
"\tGreen mask: 0x%08lx\n"
"\tBlue mask: 0x%08lx\n"
"Please file an enhancement request (quoting the above) at:\n"
PACKAGE_BUGREPORT "\n",
masks->bpp, masks->alpha_mask,
masks->red_mask, masks->green_mask, masks->blue_mask);
if (! pixman_format_supported_destination (format))
return CAIRO_INT_STATUS_UNSUPPORTED;
/* Sanity check that we got out of PIXMAN_FORMAT exactly what we
* expected. This avoid any problems from something bizarre like
* alpha in the least-significant bits, or insane channel order,
* or whatever. */
_pixman_format_to_masks (format, &format_masks);
if (masks->bpp != format_masks.bpp ||
masks->red_mask != format_masks.red_mask ||
masks->green_mask != format_masks.green_mask ||
masks->blue_mask != format_masks.blue_mask)
{
return CAIRO_INT_STATUS_UNSUPPORTED;
}
*format_ret = format;
return CAIRO_STATUS_SUCCESS;
ASSERT_NOT_REACHED;
return 0;
}
/* A mask consisting of N bits set to 1. */
#define MASK(N) ((1 << (N))-1)
/* XXX: This function should really live inside pixman. */
void
_pixman_format_to_masks (pixman_format_code_t format,
cairo_format_masks_t *masks)
_pixman_format_to_masks (pixman_format_code_t pixman_format,
uint32_t *bpp,
uint32_t *red,
uint32_t *green,
uint32_t *blue)
{
int a, r, g, b;
*red = 0x0;
*green = 0x0;
*blue = 0x0;
masks->bpp = PIXMAN_FORMAT_BPP (format);
/* Number of bits in each channel */
a = PIXMAN_FORMAT_A (format);
r = PIXMAN_FORMAT_R (format);
g = PIXMAN_FORMAT_G (format);
b = PIXMAN_FORMAT_B (format);
switch (PIXMAN_FORMAT_TYPE (format)) {
case PIXMAN_TYPE_ARGB:
masks->alpha_mask = MASK (a) << (r + g + b);
masks->red_mask = MASK (r) << (g + b);
masks->green_mask = MASK (g) << (b);
masks->blue_mask = MASK (b);
return;
case PIXMAN_TYPE_ABGR:
masks->alpha_mask = MASK (a) << (b + g + r);
masks->blue_mask = MASK (b) << (g +r);
masks->green_mask = MASK (g) << (r);
masks->red_mask = MASK (r);
return;
case PIXMAN_TYPE_A:
masks->alpha_mask = MASK (a);
masks->red_mask = 0;
masks->green_mask = 0;
masks->blue_mask = 0;
return;
case PIXMAN_TYPE_OTHER:
case PIXMAN_TYPE_COLOR:
case PIXMAN_TYPE_GRAY:
case PIXMAN_TYPE_YUY2:
case PIXMAN_TYPE_YV12:
switch (pixman_format)
{
case PIXMAN_a8r8g8b8:
case PIXMAN_x8r8g8b8:
default:
masks->alpha_mask = 0;
masks->red_mask = 0;
masks->green_mask = 0;
masks->blue_mask = 0;
return;
*bpp = 32;
*red = 0x00ff0000;
*green = 0x0000ff00;
*blue = 0x000000ff;
break;
case PIXMAN_a8b8g8r8:
case PIXMAN_x8b8g8r8:
*bpp = 32;
*red = 0x000000ff;
*green = 0x0000ff00;
*blue = 0x00ff0000;
break;
case PIXMAN_r5g6b5:
*bpp = 16;
*red = 0xf800;
*green = 0x07e0;
*blue = 0x001f;
break;
case PIXMAN_x1r5g5b5:
*bpp = 16;
*red = 0x7c00;
*green = 0x03e0;
*blue = 0x001f;
break;
case PIXMAN_a8:
*bpp = 8;
break;
case PIXMAN_a1:
*bpp = 1;
break;
}
}
/* XXX: This function really should be eliminated. We don't really
* want to advertise a cairo image surface that supports any possible
* format. A minimal step would be to replace this function with one
@ -253,25 +289,9 @@ _cairo_image_surface_create_with_masks (unsigned char *data,
int height,
int stride)
{
cairo_int_status_t status;
pixman_format_code_t pixman_format;
status = _pixman_format_from_masks (masks, &pixman_format);
if (status == CAIRO_INT_STATUS_UNSUPPORTED) {
fprintf (stderr,
"Error: Cairo " PACKAGE_VERSION " does not yet support the requested image format:\n"
"\tDepth: %d\n"
"\tAlpha mask: 0x%08lx\n"
"\tRed mask: 0x%08lx\n"
"\tGreen mask: 0x%08lx\n"
"\tBlue mask: 0x%08lx\n"
"Please file an enhancement request (quoting the above) at:\n"
PACKAGE_BUGREPORT "\n",
masks->bpp, masks->alpha_mask,
masks->red_mask, masks->green_mask, masks->blue_mask);
ASSERT_NOT_REACHED;
}
pixman_format = _pixman_format_from_masks (masks);
return _cairo_image_surface_create_with_pixman_format (data,
pixman_format,
@ -375,6 +395,9 @@ _cairo_image_surface_create_with_content (cairo_content_t content,
width, height);
}
/* pixman required stride alignment in bytes. should be power of two. */
#define STRIDE_ALIGNMENT (sizeof (uint32_t))
/**
* cairo_format_stride_for_width:
* @format: A #cairo_format_t value
@ -416,7 +439,7 @@ cairo_format_stride_for_width (cairo_format_t format,
if ((unsigned) (width) >= (INT32_MAX - 7) / (unsigned) (bpp))
return -1;
return CAIRO_STRIDE_FOR_WIDTH_BPP (width, bpp);
return ((bpp*width+7)/8 + STRIDE_ALIGNMENT-1) & ~(STRIDE_ALIGNMENT-1);
}
slim_hidden_def (cairo_format_stride_for_width);
@ -475,7 +498,7 @@ cairo_image_surface_create_for_data (unsigned char *data,
if (! CAIRO_FORMAT_VALID (format))
return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_INVALID_FORMAT));
if ((stride & (CAIRO_STRIDE_ALIGNMENT-1)) != 0)
if ((stride & (STRIDE_ALIGNMENT-1)) != 0)
return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_INVALID_STRIDE));
pixman_format = _cairo_format_to_pixman_format_code (format);
@ -524,7 +547,6 @@ cairo_image_surface_get_data (cairo_surface_t *surface)
return image_surface->data;
}
slim_hidden_def (cairo_image_surface_get_data);
/**
* cairo_image_surface_get_format:
@ -621,7 +643,6 @@ cairo_image_surface_get_stride (cairo_surface_t *surface)
return image_surface->stride;
}
slim_hidden_def (cairo_image_surface_get_stride);
cairo_format_t
_cairo_format_from_content (cairo_content_t content)

View File

@ -743,11 +743,7 @@ _cairo_meta_surface_replay_internal (cairo_surface_t *surface,
{
cairo_command_t *stroke_command;
if (type != CAIRO_META_CREATE_REGIONS)
stroke_command = (i < num_elements - 1) ? elements[i + 1] : NULL;
else
stroke_command = NULL;
stroke_command = (i < num_elements - 1) ? elements[i + 1] : NULL;
if (stroke_command != NULL &&
type == CAIRO_META_REPLAY && region != CAIRO_META_REGION_ALL)
{
@ -787,6 +783,14 @@ _cairo_meta_surface_replay_internal (cairo_surface_t *surface,
stroke_command->stroke.tolerance,
stroke_command->stroke.antialias);
i++;
if (type == CAIRO_META_CREATE_REGIONS) {
if (status == CAIRO_STATUS_SUCCESS) {
stroke_command->header.region = CAIRO_META_REGION_NATIVE;
} else if (status == CAIRO_INT_STATUS_IMAGE_FALLBACK) {
stroke_command->header.region = CAIRO_META_REGION_IMAGE_FALLBACK;
status = CAIRO_STATUS_SUCCESS;
}
}
} else
status = _cairo_surface_fill (target,
command->fill.op,

View File

@ -110,6 +110,9 @@ _cairo_output_stream_write_hex_string (cairo_output_stream_t *stream,
const char *data,
size_t length);
cairo_private void
_cairo_dtostr (char *buffer, size_t size, double d);
cairo_private void
_cairo_output_stream_vprintf (cairo_output_stream_t *stream,
const char *fmt,

View File

@ -44,26 +44,6 @@
#include <ctype.h>
#include <errno.h>
/* Numbers printed with %f are printed with this number of significant
* digits after the decimal.
*/
#define SIGNIFICANT_DIGITS_AFTER_DECIMAL 6
/* Numbers printed with %g are assumed to only have CAIRO_FIXED_FRAC_BITS
* bits of precision available after the decimal point.
*
* FIXED_POINT_DECIMAL_DIGITS specifies the minimum number of decimal
* digits after the decimal point required to preserve the available
* precision.
*
* The conversion is:
*
* FIXED_POINT_DECIMAL_DIGITS = ceil( CAIRO_FIXED_FRAC_BITS * ln(2)/ln(10) )
*
* We can replace ceil(x) with (int)(x+1) since x will never be an
* integer for any likely value of CAIRO_FIXED_FRAC_BITS.
*/
#define FIXED_POINT_DECIMAL_DIGITS ((int)(CAIRO_FIXED_FRAC_BITS*0.301029996 + 1))
void
_cairo_output_stream_init (cairo_output_stream_t *stream,
@ -256,6 +236,8 @@ _cairo_output_stream_write_hex_string (cairo_output_stream_t *stream,
}
}
#define SIGNIFICANT_DIGITS_AFTER_DECIMAL 6
/* 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
@ -264,8 +246,8 @@ _cairo_output_stream_write_hex_string (cairo_output_stream_t *stream,
* has been relicensed under the LGPL/MPL dual license for inclusion
* into cairo (see COPYING). -- Kristian Høgsberg <krh@redhat.com>
*/
static void
_cairo_dtostr (char *buffer, size_t size, double d, cairo_bool_t limited_precision)
void
_cairo_dtostr (char *buffer, size_t size, double d)
{
struct lconv *locale_data;
const char *decimal_point;
@ -284,44 +266,40 @@ _cairo_dtostr (char *buffer, size_t size, double d, cairo_bool_t limited_precisi
assert (decimal_point_len != 0);
if (limited_precision) {
snprintf (buffer, size, "%.*f", FIXED_POINT_DECIMAL_DIGITS, d);
/* Using "%f" to print numbers less than 0.1 will result in
* reduced precision due to the default 6 digits after the
* decimal point.
*
* For numbers is < 0.1, we print with maximum precision and count
* the number of zeros between the decimal point and the first
* significant digit. We then print the number again with the
* number of decimal places that gives us the required number of
* significant digits. This ensures the number is correctly
* rounded.
*/
if (fabs (d) >= 0.1) {
snprintf (buffer, size, "%f", d);
} else {
/* Using "%f" to print numbers less than 0.1 will result in
* reduced precision due to the default 6 digits after the
* decimal point.
*
* For numbers is < 0.1, we print with maximum precision and count
* the number of zeros between the decimal point and the first
* significant digit. We then print the number again with the
* number of decimal places that gives us the required number of
* significant digits. This ensures the number is correctly
* rounded.
*/
if (fabs (d) >= 0.1) {
snprintf (buffer, size, "%f", d);
} else {
snprintf (buffer, size, "%.18f", d);
p = buffer;
snprintf (buffer, size, "%.18f", d);
p = buffer;
if (*p == '+' || *p == '-')
p++;
if (*p == '+' || *p == '-')
p++;
while (isdigit (*p))
p++;
while (isdigit (*p))
p++;
if (strncmp (p, decimal_point, decimal_point_len) == 0)
p += decimal_point_len;
if (strncmp (p, decimal_point, decimal_point_len) == 0)
p += decimal_point_len;
num_zeros = 0;
while (*p++ == '0')
num_zeros++;
num_zeros = 0;
while (*p++ == '0')
num_zeros++;
decimal_digits = num_zeros + SIGNIFICANT_DIGITS_AFTER_DECIMAL;
decimal_digits = num_zeros + SIGNIFICANT_DIGITS_AFTER_DECIMAL;
if (decimal_digits < 18)
snprintf (buffer, size, "%.*f", decimal_digits, d);
}
if (decimal_digits < 18)
snprintf (buffer, size, "%.*f", decimal_digits, d);
}
p = buffer;
@ -463,10 +441,7 @@ _cairo_output_stream_vprintf (cairo_output_stream_t *stream,
single_fmt, va_arg (ap, const char *));
break;
case 'f':
_cairo_dtostr (buffer, sizeof buffer, va_arg (ap, double), FALSE);
break;
case 'g':
_cairo_dtostr (buffer, sizeof buffer, va_arg (ap, double), TRUE);
_cairo_dtostr (buffer, sizeof buffer, va_arg (ap, double));
break;
case 'c':
buffer[0] = va_arg (ap, int);

View File

@ -613,10 +613,8 @@ _cairo_path_fixed_is_equal (cairo_path_fixed_t *path,
if (other_buf == NULL ||
path_buf->num_ops != other_buf->num_ops ||
path_buf->num_points != other_buf->num_points ||
memcmp (path_buf->op, other_buf->op,
sizeof (cairo_path_op_t) * path_buf->num_ops) != 0 ||
memcmp (path_buf->points, other_buf->points,
sizeof (cairo_point_t) * path_buf->num_points) != 0)
memcmp (path_buf->op, other_buf->op, path_buf->num_ops) != 0 ||
memcmp (path_buf->points, other_buf->points, path_buf->num_points != 0))
{
return FALSE;
}

View File

@ -821,6 +821,7 @@ _cairo_pattern_add_color_stop (cairo_gradient_pattern_t *pattern,
double alpha)
{
cairo_gradient_stop_t *stops;
cairo_fixed_t x;
unsigned int i;
if (pattern->n_stops >= pattern->stops_size) {
@ -833,9 +834,10 @@ _cairo_pattern_add_color_stop (cairo_gradient_pattern_t *pattern,
stops = pattern->stops;
x = _cairo_fixed_from_double (offset);
for (i = 0; i < pattern->n_stops; i++)
{
if (offset < stops[i].offset)
if (x < stops[i].x)
{
memmove (&stops[i + 1], &stops[i],
sizeof (cairo_gradient_stop_t) * (pattern->n_stops - i));
@ -844,7 +846,7 @@ _cairo_pattern_add_color_stop (cairo_gradient_pattern_t *pattern,
}
}
stops[i].offset = offset;
stops[i].x = x;
stops[i].color.red = red;
stops[i].color.green = green;
@ -1084,9 +1086,6 @@ cairo_pattern_get_filter (cairo_pattern_t *pattern)
* Sets the mode to be used for drawing outside the area of a pattern.
* See #cairo_extend_t for details on the semantics of each extend
* strategy.
*
* The default extend mode is %CAIRO_EXTEND_NONE for surface patterns
* and %CAIRO_EXTEND_PAD for gradient patterns.
**/
void
cairo_pattern_set_extend (cairo_pattern_t *pattern, cairo_extend_t extend)
@ -1209,7 +1208,7 @@ _cairo_pattern_acquire_surface_for_gradient (cairo_gradient_pattern_t *pattern,
}
for (i = 0; i < pattern->n_stops; i++) {
pixman_stops[i].x = _cairo_fixed_16_16_from_double (pattern->stops[i].offset);
pixman_stops[i].x = _cairo_fixed_to_16_16 (pattern->stops[i].x);
pixman_stops[i].color.red = pattern->stops[i].color.red_short;
pixman_stops[i].color.green = pattern->stops[i].color.green_short;
pixman_stops[i].color.blue = pattern->stops[i].color.blue_short;
@ -1983,65 +1982,50 @@ _cairo_pattern_get_extents (cairo_pattern_t *pattern,
(cairo_surface_pattern_t *) pattern;
cairo_surface_t *surface = surface_pattern->surface;
cairo_matrix_t imatrix;
double x1, y1, x2, y2;
double x, y;
/* Initialize to keep the compiler quiet. */
int left=0, right=0, top=0, bottom=0;
int lx, rx, ty, by;
int sx, sy;
cairo_bool_t set = FALSE;
status = _cairo_surface_get_extents (surface, &surface_extents);
if (status)
return status;
x1 = surface_extents.x;
y1 = surface_extents.y;
x2 = x1 + surface_extents.width;
y2 = y1 + surface_extents.height;
/* The filter can effectively enlarge the extents of the
* pattern, so extend as necessary. Note: We aren't doing any
* backend-specific querying of filter box sizes at this time,
* (since currently no specific backends that could do custom
* filters are calling _cairo_pattern_get_extents). */
switch (pattern->filter) {
case CAIRO_FILTER_GOOD:
case CAIRO_FILTER_BEST:
case CAIRO_FILTER_BILINEAR:
x1 -= 0.5;
y1 -= 0.5;
x2 += 0.5;
y2 += 0.5;
break;
case CAIRO_FILTER_FAST:
case CAIRO_FILTER_NEAREST:
case CAIRO_FILTER_GAUSSIAN:
default:
/* Nothing to do */
break;
}
imatrix = pattern->matrix;
status = cairo_matrix_invert (&imatrix);
/* cairo_pattern_set_matrix ensures the matrix is invertible */
assert (status == CAIRO_STATUS_SUCCESS);
_cairo_matrix_transform_bounding_box (&imatrix,
&x1, &y1, &x2, &y2,
NULL);
x1 = floor (x1);
if (x1 < 0)
x1 = 0;
y1 = floor (y1);
if (y1 < 0)
y1 = 0;
x2 = ceil (x2);
if (x2 > CAIRO_RECT_INT_MAX)
x2 = CAIRO_RECT_INT_MAX;
y2 = ceil (y2);
if (y2 > CAIRO_RECT_INT_MAX)
y2 = CAIRO_RECT_INT_MAX;
extents->x = x1; extents->width = x2 - x1;
extents->y = y1; extents->height = y2 - y1;
/* XXX Use _cairo_matrix_transform_bounding_box here */
for (sy = 0; sy <= 1; sy++) {
for (sx = 0; sx <= 1; sx++) {
x = surface_extents.x + sx * surface_extents.width;
y = surface_extents.y + sy * surface_extents.height;
cairo_matrix_transform_point (&imatrix, &x, &y);
if (x < 0) x = 0;
if (x > CAIRO_RECT_INT_MAX) x = CAIRO_RECT_INT_MAX;
if (y < 0) y = 0;
if (y > CAIRO_RECT_INT_MAX) y = CAIRO_RECT_INT_MAX;
lx = floor (x); rx = ceil (x);
ty = floor (y); by = ceil (y);
if (!set) {
left = lx;
right = rx;
top = ty;
bottom = by;
set = TRUE;
} else {
if (lx < left) left = lx;
if (rx > right) right = rx;
if (ty < top) top = ty;
if (by > bottom) bottom = by;
}
}
}
extents->x = left; extents->width = right - left;
extents->y = top; extents->height = bottom - top;
return CAIRO_STATUS_SUCCESS;
}
@ -2171,7 +2155,7 @@ cairo_pattern_get_color_stop_rgba (cairo_pattern_t *pattern,
return _cairo_error (CAIRO_STATUS_INVALID_INDEX);
if (offset)
*offset = gradient->stops[index].offset;
*offset = _cairo_fixed_to_double(gradient->stops[index].x);
if (red)
*red = gradient->stops[index].color.red;
if (green)

View File

@ -108,7 +108,6 @@ typedef struct _word_wrap_stream {
int column;
cairo_bool_t last_write_was_space;
cairo_bool_t in_hexstring;
cairo_bool_t empty_hexstring;
} word_wrap_stream_t;
static int
@ -137,15 +136,11 @@ _count_hexstring_up_to (const unsigned char *s, int length, int columns)
{
int word = 0;
while (length--) {
while (length-- && columns--) {
if (*s++ != '>')
word++;
else
return word;
columns--;
if (columns < 0 && word > 1)
return word;
}
return word;
@ -163,19 +158,14 @@ _word_wrap_stream_write (cairo_output_stream_t *base,
while (length) {
if (*data == '<') {
stream->in_hexstring = TRUE;
stream->empty_hexstring = TRUE;
stream->last_write_was_space = FALSE;
data++;
length--;
_cairo_output_stream_printf (stream->output, "<");
stream->column++;
} else if (*data == '>') {
stream->in_hexstring = FALSE;
stream->last_write_was_space = FALSE;
data++;
length--;
_cairo_output_stream_printf (stream->output, ">");
stream->column++;
} else if (isspace (*data)) {
newline = (*data == '\n' || *data == '\r');
if (! newline && stream->column >= stream->max_column) {
@ -185,9 +175,8 @@ _word_wrap_stream_write (cairo_output_stream_t *base,
_cairo_output_stream_write (stream->output, data, 1);
data++;
length--;
if (newline) {
if (newline)
stream->column = 0;
}
else
stream->column++;
stream->last_write_was_space = TRUE;
@ -200,21 +189,17 @@ _word_wrap_stream_write (cairo_output_stream_t *base,
}
/* Don't wrap if this word is a continuation of a non hex
* string word from a previous call to write. */
if (stream->column + word >= stream->max_column) {
if (stream->last_write_was_space ||
(stream->in_hexstring && !stream->empty_hexstring))
{
_cairo_output_stream_printf (stream->output, "\n");
stream->column = 0;
}
if (stream->column + word >= stream->max_column &&
(stream->last_write_was_space || stream->in_hexstring))
{
_cairo_output_stream_printf (stream->output, "\n");
stream->column = 0;
}
_cairo_output_stream_write (stream->output, data, word);
data += word;
length -= word;
stream->column += word;
stream->last_write_was_space = FALSE;
if (stream->in_hexstring)
stream->empty_hexstring = FALSE;
}
}
@ -251,7 +236,6 @@ _word_wrap_stream_create (cairo_output_stream_t *output, int max_column)
stream->column = 0;
stream->last_write_was_space = FALSE;
stream->in_hexstring = FALSE;
stream->empty_hexstring = TRUE;
return &stream->base;
}
@ -275,7 +259,7 @@ _cairo_pdf_path_move_to (void *closure, cairo_point_t *point)
info->has_sub_path = FALSE;
cairo_matrix_transform_point (info->path_transform, &x, &y);
_cairo_output_stream_printf (info->output,
"%g %g m ", x, y);
"%f %f m ", x, y);
return _cairo_output_stream_get_status (info->output);
}
@ -298,7 +282,7 @@ _cairo_pdf_path_line_to (void *closure, cairo_point_t *point)
info->has_sub_path = TRUE;
cairo_matrix_transform_point (info->path_transform, &x, &y);
_cairo_output_stream_printf (info->output,
"%g %g l ", x, y);
"%f %f l ", x, y);
return _cairo_output_stream_get_status (info->output);
}
@ -322,7 +306,7 @@ _cairo_pdf_path_curve_to (void *closure,
cairo_matrix_transform_point (info->path_transform, &cx, &cy);
cairo_matrix_transform_point (info->path_transform, &dx, &dy);
_cairo_output_stream_printf (info->output,
"%g %g %g %g %g %g c ",
"%f %f %f %f %f %f c ",
bx, by, cx, cy, dx, dy);
return _cairo_output_stream_get_status (info->output);
}
@ -355,7 +339,7 @@ _cairo_pdf_path_rectangle (pdf_path_info_t *info, cairo_box_t *box)
cairo_matrix_transform_point (info->path_transform, &x1, &y1);
cairo_matrix_transform_point (info->path_transform, &x2, &y2);
_cairo_output_stream_printf (info->output,
"%g %g %g %g re ",
"%f %f %f %f re ",
x1, y1, x2 - x1, y2 - y1);
return _cairo_output_stream_get_status (info->output);
@ -371,7 +355,7 @@ _cairo_pdf_path_rectangle (pdf_path_info_t *info, cairo_box_t *box)
* the stroke workaround will not modify the path being emitted.
*/
static cairo_status_t
_cairo_pdf_operators_emit_path (cairo_pdf_operators_t *pdf_operators,
_cairo_pdf_operators_emit_path (cairo_pdf_operators_t *pdf_operators,
cairo_path_fixed_t *path,
cairo_matrix_t *path_transform,
cairo_line_cap_t line_cap)
@ -381,10 +365,10 @@ _cairo_pdf_operators_emit_path (cairo_pdf_operators_t *pdf_operators,
pdf_path_info_t info;
cairo_box_t box;
word_wrap = _word_wrap_stream_create (pdf_operators->stream, 72);
word_wrap = _word_wrap_stream_create (pdf_operators->stream, 79);
status = _cairo_output_stream_get_status (word_wrap);
if (status)
return _cairo_output_stream_destroy (word_wrap);
return status;
info.output = word_wrap;
info.path_transform = path_transform;
@ -480,8 +464,7 @@ _cairo_pdf_line_join (cairo_line_join_t join)
static cairo_int_status_t
_cairo_pdf_operators_emit_stroke_style (cairo_pdf_operators_t *pdf_operators,
cairo_stroke_style_t *style,
double scale)
cairo_stroke_style_t *style)
{
double *dash = style->dash;
int num_dashes = style->num_dashes;
@ -552,7 +535,7 @@ _cairo_pdf_operators_emit_stroke_style (cairo_pdf_operators_t *pdf_operators,
_cairo_output_stream_printf (pdf_operators->stream,
"%f w\n",
style->line_width * scale);
style->line_width);
_cairo_output_stream_printf (pdf_operators->stream,
"%d J\n",
@ -567,9 +550,9 @@ _cairo_pdf_operators_emit_stroke_style (cairo_pdf_operators_t *pdf_operators,
_cairo_output_stream_printf (pdf_operators->stream, "[");
for (d = 0; d < num_dashes; d++)
_cairo_output_stream_printf (pdf_operators->stream, " %f", dash[d] * scale);
_cairo_output_stream_printf (pdf_operators->stream, " %f", dash[d]);
_cairo_output_stream_printf (pdf_operators->stream, "] %f d\n",
dash_offset * scale);
dash_offset);
} else {
_cairo_output_stream_printf (pdf_operators->stream, "[] 0.0 d\n");
}
@ -583,116 +566,6 @@ _cairo_pdf_operators_emit_stroke_style (cairo_pdf_operators_t *pdf_operators,
return _cairo_output_stream_get_status (pdf_operators->stream);
}
/* Scale the matrix so the largest absolute value of the non
* translation components is 1.0. Return the scale required to restore
* the matrix to the original values.
*
* eg the matrix [ 100 0 0 50 20 10 ]
*
* is rescaled to [ 1 0 0 0.5 0.2 0.1 ]
* and the scale returned is 100
*/
static void
_cairo_matrix_factor_out_scale (cairo_matrix_t *m, double *scale)
{
double s;
s = fabs (m->xx);
if (fabs (m->xy) > s)
s = fabs (m->xy);
if (fabs (m->yx) > s)
s = fabs (m->yx);
if (fabs (m->yy) > s)
s = fabs (m->yy);
*scale = s;
s = 1.0/s;
cairo_matrix_scale (m, s, s);
}
static cairo_int_status_t
_cairo_pdf_operators_emit_stroke (cairo_pdf_operators_t *pdf_operators,
cairo_path_fixed_t *path,
cairo_stroke_style_t *style,
cairo_matrix_t *ctm,
cairo_matrix_t *ctm_inverse,
const char *pdf_operator)
{
cairo_status_t status;
cairo_matrix_t m, path_transform;
cairo_bool_t has_ctm = TRUE;
double scale = 1.0;
/* Optimize away the stroke ctm when it does not affect the
* stroke. There are other ctm cases that could be optimized
* however this is the most common.
*/
if (fabs(ctm->xx) == 1.0 && fabs(ctm->yy) == 1.0 &&
fabs(ctm->xy) == 0.0 && fabs(ctm->yx) == 0.0)
{
has_ctm = FALSE;
}
/* The PDF CTM is transformed to the user space CTM when stroking
* so the corect pen shape will be used. This also requires that
* the path be transformed to user space when emitted. The
* conversion of path coordinates to user space may cause rounding
* errors. For example the device space point (1.234, 3.142) when
* transformed to a user space CTM of [100 0 0 100 0 0] will be
* emitted as (0.012, 0.031).
*
* To avoid the rounding problem we scale the user space CTM
* matrix so that all the non translation components of the matrix
* are <= 1. The line width and and dashes are scaled by the
* inverse of the scale applied to the CTM. This maintains the
* shape of the stroke pen while keeping the user space CTM within
* the range that maximizes the precision of the emitted path.
*/
if (has_ctm) {
m = *ctm;
/* Zero out the translation since it does not affect the pen
* shape however it may cause unnecessary digits to be emitted.
*/
m.x0 = 0.0;
m.y0 = 0.0;
_cairo_matrix_factor_out_scale (&m, &scale);
path_transform = m;
status = cairo_matrix_invert (&path_transform);
if (status)
return status;
cairo_matrix_multiply (&m, &m, &pdf_operators->cairo_to_pdf);
}
status = _cairo_pdf_operators_emit_stroke_style (pdf_operators, style, scale);
if (status == CAIRO_INT_STATUS_NOTHING_TO_DO)
return CAIRO_STATUS_SUCCESS;
if (status)
return status;
if (has_ctm) {
_cairo_output_stream_printf (pdf_operators->stream,
"q %f %f %f %f %f %f cm\n",
m.xx, m.yx, m.xy, m.yy,
m.x0, m.y0);
} else {
path_transform = pdf_operators->cairo_to_pdf;
}
status = _cairo_pdf_operators_emit_path (pdf_operators,
path,
&path_transform,
style->line_cap);
if (status)
return status;
_cairo_output_stream_printf (pdf_operators->stream, "%s", pdf_operator);
if (has_ctm)
_cairo_output_stream_printf (pdf_operators->stream, " Q");
_cairo_output_stream_printf (pdf_operators->stream, "\n");
return _cairo_output_stream_get_status (pdf_operators->stream);
}
cairo_int_status_t
_cairo_pdf_operators_stroke (cairo_pdf_operators_t *pdf_operators,
@ -701,12 +574,31 @@ _cairo_pdf_operators_stroke (cairo_pdf_operators_t *pdf_operators,
cairo_matrix_t *ctm,
cairo_matrix_t *ctm_inverse)
{
return _cairo_pdf_operators_emit_stroke (pdf_operators,
cairo_status_t status;
cairo_matrix_t m;
status = _cairo_pdf_operators_emit_stroke_style (pdf_operators, style);
if (status == CAIRO_INT_STATUS_NOTHING_TO_DO)
return CAIRO_STATUS_SUCCESS;
if (status)
return status;
cairo_matrix_multiply (&m, ctm, &pdf_operators->cairo_to_pdf);
_cairo_output_stream_printf (pdf_operators->stream,
"q %f %f %f %f %f %f cm\n",
m.xx, m.yx, m.xy, m.yy,
m.x0, m.y0);
status = _cairo_pdf_operators_emit_path (pdf_operators,
path,
style,
ctm,
ctm_inverse,
"S");
style->line_cap);
if (status)
return status;
_cairo_output_stream_printf (pdf_operators->stream, "S Q\n");
return _cairo_output_stream_get_status (pdf_operators->stream);
}
cairo_int_status_t
@ -750,25 +642,45 @@ _cairo_pdf_operators_fill_stroke (cairo_pdf_operators_t *pdf_operators,
cairo_matrix_t *ctm,
cairo_matrix_t *ctm_inverse)
{
const char *operator;
const char *pdf_operator;
cairo_status_t status;
cairo_matrix_t m;
status = _cairo_pdf_operators_emit_stroke_style (pdf_operators, style);
if (status == CAIRO_INT_STATUS_NOTHING_TO_DO)
return CAIRO_STATUS_SUCCESS;
if (status)
return status;
cairo_matrix_multiply (&m, ctm, &pdf_operators->cairo_to_pdf);
_cairo_output_stream_printf (pdf_operators->stream,
"q %f %f %f %f %f %f cm\n",
m.xx, m.yx, m.xy, m.yy,
m.x0, m.y0);
status = _cairo_pdf_operators_emit_path (pdf_operators,
path,
ctm_inverse,
style->line_cap);
if (status)
return status;
switch (fill_rule) {
case CAIRO_FILL_RULE_WINDING:
operator = "B";
pdf_operator = "B";
break;
case CAIRO_FILL_RULE_EVEN_ODD:
operator = "B*";
pdf_operator = "B*";
break;
default:
ASSERT_NOT_REACHED;
}
return _cairo_pdf_operators_emit_stroke (pdf_operators,
path,
style,
ctm,
ctm_inverse,
operator);
_cairo_output_stream_printf (pdf_operators->stream,
"%s Q\n",
pdf_operator);
return _cairo_output_stream_get_status (pdf_operators->stream);
}
#define GLYPH_POSITION_TOLERANCE 0.001
@ -791,10 +703,10 @@ _cairo_pdf_operators_show_glyphs (cairo_pdf_operators_t *pdf_operators,
for (i = 0; i < num_glyphs; i++)
cairo_matrix_transform_point (&pdf_operators->cairo_to_pdf, &glyphs[i].x, &glyphs[i].y);
word_wrap_stream = _word_wrap_stream_create (pdf_operators->stream, 72);
word_wrap_stream = _word_wrap_stream_create (pdf_operators->stream, 79);
status = _cairo_output_stream_get_status (word_wrap_stream);
if (status)
return _cairo_output_stream_destroy (word_wrap_stream);
return status;
_cairo_output_stream_printf (word_wrap_stream,
"BT\n");
@ -887,28 +799,10 @@ _cairo_pdf_operators_show_glyphs (cairo_pdf_operators_t *pdf_operators,
} else {
if (fabs((glyphs[i].x - Tm_x)/scaled_font->scale.xx) > GLYPH_POSITION_TOLERANCE) {
double delta = glyphs[i].x - Tm_x;
int rounded_delta;
delta = -1000.0*delta/scaled_font->scale.xx;
/* As the delta is in 1/1000 of a unit of text
* space, rounding to an integer should still
* provide sufficient precision. We round the
* delta before adding to Tm_x so that we keep
* track of the accumulated rounding error in
* the PDF interpreter and compensate for it
* when calculating subsequent deltas.
*/
rounded_delta = _cairo_lround (delta);
if (rounded_delta != 0) {
_cairo_output_stream_printf (word_wrap_stream,
"> %d <",
rounded_delta);
}
/* Convert the rounded delta back to cairo
* space before adding to the current text
* position. */
delta = rounded_delta*scaled_font->scale.xx/-1000.0;
_cairo_output_stream_printf (word_wrap_stream,
"> %f <",
-1000.0*delta/scaled_font->scale.xx);
Tm_x += delta;
}
_cairo_output_stream_printf (word_wrap_stream,
@ -923,16 +817,10 @@ _cairo_pdf_operators_show_glyphs (cairo_pdf_operators_t *pdf_operators,
if (in_TJ) {
if (fabs((glyphs[i].x - Tm_x)/scaled_font->scale.xx) > GLYPH_POSITION_TOLERANCE) {
double delta = glyphs[i].x - Tm_x;
int rounded_delta;
delta = -1000.0*delta/scaled_font->scale.xx;
rounded_delta = _cairo_lround (delta);
if (rounded_delta != 0) {
_cairo_output_stream_printf (word_wrap_stream,
"> %d <",
rounded_delta);
}
delta = rounded_delta*scaled_font->scale.xx/-1000.0;
_cairo_output_stream_printf (word_wrap_stream,
"> %f <",
-1000.0*delta/scaled_font->scale.xx);
Tm_x += delta;
}
_cairo_output_stream_printf (word_wrap_stream,
@ -946,7 +834,7 @@ _cairo_pdf_operators_show_glyphs (cairo_pdf_operators_t *pdf_operators,
_cairo_output_stream_printf (word_wrap_stream,
"%f %f Td ",
(glyphs[i].x - Tlm_x)/scaled_font->scale.xx,
(glyphs[i].y - Tlm_y)/scaled_font->scale.yy);
(glyphs[i].y - Tlm_y)/-scaled_font->scale.yy);
Tlm_x = glyphs[i].x;
Tlm_y = glyphs[i].y;
Tm_x = Tlm_x;

View File

@ -211,18 +211,6 @@ _cairo_pdf_surface_update_object (cairo_pdf_surface_t *surface,
object->offset = _cairo_output_stream_get_position (surface->output);
}
static void
cairo_pdf_surface_set_size_internal (cairo_pdf_surface_t *surface,
double width,
double height)
{
surface->width = width;
surface->height = height;
cairo_matrix_init (&surface->cairo_to_pdf, 1, 0, 0, -1, 0, height);
_cairo_pdf_operators_set_cairo_to_pdf_matrix (&surface->pdf_operators,
&surface->cairo_to_pdf);
}
static cairo_surface_t *
_cairo_pdf_surface_create_for_stream_internal (cairo_output_stream_t *output,
double width,
@ -405,15 +393,10 @@ _extract_pdf_surface (cairo_surface_t *surface,
{
cairo_surface_t *target;
if (surface->status)
return surface->status;
if (! _cairo_surface_is_paginated (surface))
return _cairo_error (CAIRO_STATUS_SURFACE_TYPE_MISMATCH);
target = _cairo_paginated_surface_get_target (surface);
if (target->status)
return target->status;
if (! _cairo_surface_is_pdf (target))
return _cairo_error (CAIRO_STATUS_SURFACE_TYPE_MISMATCH);
@ -454,9 +437,11 @@ cairo_pdf_surface_set_size (cairo_surface_t *surface,
return;
}
cairo_pdf_surface_set_size_internal (pdf_surface,
width_in_points,
height_in_points);
pdf_surface->width = width_in_points;
pdf_surface->height = height_in_points;
cairo_matrix_init (&pdf_surface->cairo_to_pdf, 1, 0, 0, -1, 0, height_in_points);
_cairo_pdf_operators_set_cairo_to_pdf_matrix (&pdf_surface->pdf_operators,
&pdf_surface->cairo_to_pdf);
status = _cairo_paginated_surface_set_size (pdf_surface->paginated_surface,
width_in_points,
height_in_points);
@ -741,8 +726,6 @@ _cairo_pdf_smask_group_destroy (cairo_pdf_smask_group_t *group)
cairo_pattern_destroy (group->source);
if (group->mask)
cairo_pattern_destroy (group->mask);
if (group->glyphs)
free (group->glyphs);
if (group->scaled_font)
cairo_scaled_font_destroy (group->scaled_font);
free (group);
@ -1262,6 +1245,7 @@ _cairo_pdf_surface_emit_smask (cairo_pdf_surface_t *surface,
int i, x, y;
cairo_bool_t opaque;
uint8_t a;
int src_bit, dst_bit;
/* This is the only image format we support, which simplifies things. */
assert (image->format == CAIRO_FORMAT_ARGB32 ||
@ -1271,7 +1255,11 @@ _cairo_pdf_surface_emit_smask (cairo_pdf_surface_t *surface,
stream_ret->id = 0;
if (image->format == CAIRO_FORMAT_A1) {
alpha_size = (image->width + 7) / 8 * image->height;
/* We allocate using slightly different math so that we can get
* the overflow checking from _cairo_malloc_ab, but alpha_size
* needs to be the correct size for emitting the data in the PDF.
*/
alpha_size = (image->width*image->height + 7) / 8;
alpha = _cairo_malloc_ab ((image->width+7) / 8, image->height);
} else {
alpha_size = image->height * image->width;
@ -1285,6 +1273,8 @@ _cairo_pdf_surface_emit_smask (cairo_pdf_surface_t *surface,
opaque = TRUE;
i = 0;
src_bit = 0;
dst_bit = 7;
for (y = 0; y < image->height; y++) {
if (image->format == CAIRO_FORMAT_ARGB32) {
pixel32 = (uint32_t *) (image->data + y * image->stride);
@ -1307,12 +1297,21 @@ _cairo_pdf_surface_emit_smask (cairo_pdf_surface_t *surface,
} else { /* image->format == CAIRO_FORMAT_A1 */
pixel8 = (uint8_t *) (image->data + y * image->stride);
for (x = 0; x < (image->width + 7) / 8; x++, pixel8++) {
a = *pixel8;
a = CAIRO_BITSWAP8_IF_LITTLE_ENDIAN (a);
alpha[i++] = a;
if (a != 0xff)
opaque = FALSE;
for (x = 0; x < image->width; x++, pixel8++) {
if (dst_bit == 7)
alpha[i] = 0;
if ((*pixel8 >> src_bit) & 1) {
opaque = FALSE;
alpha[i] |= (1 << dst_bit);
}
if (++src_bit > 7) {
src_bit = 0;
pixel8++;
}
if (--dst_bit < 0) {
dst_bit = 7;
i++;
}
}
}
}
@ -1493,10 +1492,10 @@ _cairo_pdf_surface_emit_meta_surface (cairo_pdf_surface_t *surface,
cairo_pdf_resource_t *resource)
{
double old_width, old_height;
cairo_matrix_t old_cairo_to_pdf;
cairo_paginated_mode_t old_paginated_mode;
cairo_clip_t *old_clip;
cairo_rectangle_int_t meta_extents;
cairo_status_t status, status2;
cairo_status_t status;
int alpha = 0;
status = _cairo_surface_get_extents (meta_surface, &meta_extents);
@ -1505,16 +1504,19 @@ _cairo_pdf_surface_emit_meta_surface (cairo_pdf_surface_t *surface,
old_width = surface->width;
old_height = surface->height;
old_cairo_to_pdf = surface->cairo_to_pdf;
old_paginated_mode = surface->paginated_mode;
old_clip = _cairo_surface_get_clip (&surface->base);
cairo_pdf_surface_set_size_internal (surface,
meta_extents.width,
meta_extents.height);
surface->width = meta_extents.width;
surface->height = meta_extents.height;
/* Patterns are emitted after fallback images. The paginated mode
* needs to be set to _RENDER while the meta surface is replayed
* back to this surface.
*/
surface->paginated_mode = CAIRO_PAGINATED_MODE_RENDER;
cairo_matrix_init (&surface->cairo_to_pdf, 1, 0, 0, -1, 0, surface->height);
_cairo_pdf_operators_set_cairo_to_pdf_matrix (&surface->pdf_operators,
&surface->cairo_to_pdf);
_cairo_pdf_group_resources_clear (&surface->resources);
status = _cairo_pdf_surface_open_content_stream (surface, TRUE);
if (status)
@ -1542,13 +1544,12 @@ _cairo_pdf_surface_emit_meta_surface (cairo_pdf_surface_t *surface,
status = _cairo_pdf_surface_close_content_stream (surface);
CLEANUP_GROUP:
cairo_pdf_surface_set_size_internal (surface,
old_width,
old_height);
surface->width = old_width;
surface->height = old_height;
surface->paginated_mode = old_paginated_mode;
status2 = _cairo_surface_set_clip (&surface->base, old_clip);
if (status == CAIRO_STATUS_SUCCESS)
status = status2;
surface->cairo_to_pdf = old_cairo_to_pdf;
_cairo_pdf_operators_set_cairo_to_pdf_matrix (&surface->pdf_operators,
&surface->cairo_to_pdf);
return status;
}
@ -1980,7 +1981,7 @@ _cairo_pdf_surface_emit_pattern_stops (cairo_pdf_surface_t *surface,
stops[i].color[3] = pattern->stops[i].color.alpha;
if (!CAIRO_ALPHA_IS_OPAQUE (stops[i].color[3]))
emit_alpha = TRUE;
stops[i].offset = pattern->stops[i].offset;
stops[i].offset = _cairo_fixed_to_double (pattern->stops[i].x);
}
if (pattern->base.extend == CAIRO_EXTEND_REPEAT ||
@ -2219,8 +2220,8 @@ _cairo_pdf_surface_emit_linear_pattern (cairo_pdf_surface_t *surface,
assert (status == CAIRO_STATUS_SUCCESS);
cairo_matrix_multiply (&pat_to_pdf, &pat_to_pdf, &surface->cairo_to_pdf);
first_stop = gradient->stops[0].offset;
last_stop = gradient->stops[gradient->n_stops - 1].offset;
first_stop = _cairo_fixed_to_double (gradient->stops[0].x);
last_stop = _cairo_fixed_to_double (gradient->stops[gradient->n_stops - 1].x);
if (pattern->base.base.extend == CAIRO_EXTEND_REPEAT ||
pattern->base.base.extend == CAIRO_EXTEND_REFLECT) {
@ -2519,9 +2520,8 @@ _cairo_pdf_surface_emit_pattern (cairo_pdf_surface_t *surface, cairo_pdf_pattern
old_width = surface->width;
old_height = surface->height;
cairo_pdf_surface_set_size_internal (surface,
pdf_pattern->width,
pdf_pattern->height);
surface->width = pdf_pattern->width;
surface->height = pdf_pattern->height;
switch (pdf_pattern->pattern->type) {
case CAIRO_PATTERN_TYPE_SOLID:
@ -2547,9 +2547,8 @@ _cairo_pdf_surface_emit_pattern (cairo_pdf_surface_t *surface, cairo_pdf_pattern
break;
}
cairo_pdf_surface_set_size_internal (surface,
old_width,
old_height);
surface->width = old_width;
surface->height = old_height;
return status;
}
@ -3827,13 +3826,18 @@ _cairo_pdf_surface_write_smask_group (cairo_pdf_surface_t *surface,
cairo_pdf_smask_group_t *group)
{
double old_width, old_height;
cairo_matrix_t old_cairo_to_pdf;
cairo_status_t status;
old_width = surface->width;
old_height = surface->height;
cairo_pdf_surface_set_size_internal (surface,
group->width,
group->height);
old_cairo_to_pdf = surface->cairo_to_pdf;
surface->width = group->width;
surface->height = group->height;
cairo_matrix_init (&surface->cairo_to_pdf, 1, 0, 0, -1, 0, surface->height);
_cairo_pdf_operators_set_cairo_to_pdf_matrix (&surface->pdf_operators,
&surface->cairo_to_pdf);
/* _mask is a special case that requires two groups - source
* and mask as well as a smask and gstate dictionary */
if (group->operation == PDF_MASK)
@ -3884,9 +3888,11 @@ _cairo_pdf_surface_write_smask_group (cairo_pdf_surface_t *surface,
_cairo_pdf_surface_unselect_pattern (surface);
status = _cairo_pdf_surface_close_group (surface, NULL);
cairo_pdf_surface_set_size_internal (surface,
old_width,
old_height);
surface->width = old_width;
surface->height = old_height;
surface->cairo_to_pdf = old_cairo_to_pdf;
_cairo_pdf_operators_set_cairo_to_pdf_matrix (&surface->pdf_operators,
&surface->cairo_to_pdf);
return status;
}
@ -4142,10 +4148,9 @@ _cairo_pdf_surface_analyze_operation (cairo_pdf_surface_t *surface,
if (! _pattern_supported (pattern))
return CAIRO_INT_STATUS_UNSUPPORTED;
if (op == CAIRO_OPERATOR_OVER) {
if (op == CAIRO_OPERATOR_OVER || op == CAIRO_OPERATOR_SOURCE) {
if (pattern->type == CAIRO_PATTERN_TYPE_SURFACE) {
cairo_surface_pattern_t *surface_pattern = (cairo_surface_pattern_t *) pattern;
if ( _cairo_surface_is_meta (surface_pattern->surface))
return CAIRO_INT_STATUS_ANALYZE_META_SURFACE_PATTERN;
}
@ -4160,13 +4165,8 @@ _cairo_pdf_surface_analyze_operation (cairo_pdf_surface_t *surface,
if (pattern->type == CAIRO_PATTERN_TYPE_SURFACE) {
cairo_surface_pattern_t *surface_pattern = (cairo_surface_pattern_t *) pattern;
if (_cairo_surface_is_meta (surface_pattern->surface)) {
if (_cairo_pattern_is_opaque (pattern))
return CAIRO_INT_STATUS_ANALYZE_META_SURFACE_PATTERN;
} else {
return _cairo_pdf_surface_analyze_surface_pattern_transparency (surface,
surface_pattern);
}
return _cairo_pdf_surface_analyze_surface_pattern_transparency (surface,
surface_pattern);
}
if (_cairo_pattern_is_opaque (pattern))
@ -4536,14 +4536,19 @@ _cairo_pdf_surface_fill_stroke (void *abstract_surface,
if (surface->paginated_mode == CAIRO_PAGINATED_MODE_ANALYZE)
return CAIRO_INT_STATUS_UNSUPPORTED;
/* PDF rendering of fill-stroke is not the same as cairo when
* either the fill or stroke is not opaque.
/* Fill-stroke with patterns requiring an SMask are not currently
* implemented. Non opaque stroke patterns are not supported
* because the PDF fill-stroke operator does not blend a
* transparent stroke with the fill.
*/
if ( !_cairo_pattern_is_opaque (fill_source) ||
!_cairo_pattern_is_opaque (stroke_source))
if (fill_source->type == CAIRO_PATTERN_TYPE_LINEAR ||
fill_source->type == CAIRO_PATTERN_TYPE_RADIAL)
{
return CAIRO_INT_STATUS_UNSUPPORTED;
if (!_cairo_pattern_is_opaque (fill_source))
return CAIRO_INT_STATUS_UNSUPPORTED;
}
if (!_cairo_pattern_is_opaque (stroke_source))
return CAIRO_INT_STATUS_UNSUPPORTED;
fill_pattern_res.id = 0;
gstate_res.id = 0;
@ -4626,12 +4631,7 @@ _cairo_pdf_surface_show_glyphs (void *abstract_surface,
group->operation = PDF_SHOW_GLYPHS;
group->source = cairo_pattern_reference (source);
group->source_res = pattern_res;
group->glyphs = _cairo_malloc_ab (num_glyphs, sizeof (cairo_glyph_t));
if (group->glyphs == NULL) {
_cairo_pdf_smask_group_destroy (group);
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
}
memcpy (group->glyphs, glyphs, sizeof (cairo_glyph_t) * num_glyphs);
group->glyphs = glyphs;
group->num_glyphs = num_glyphs;
group->scaled_font = cairo_scaled_font_reference (scaled_font);
status = _cairo_pdf_surface_add_smask_group (surface, group);

View File

@ -211,8 +211,9 @@ write_png (cairo_surface_t *surface,
PNG_COMPRESSION_TYPE_DEFAULT,
PNG_FILTER_TYPE_DEFAULT);
white.gray = (1 << depth) - 1;
white.red = white.blue = white.green = white.gray;
white.red = 0xff;
white.blue = 0xff;
white.green = 0xff;
png_set_bKGD (png, info, &white);
png_convert_from_time_t (&pt, time (NULL));

View File

@ -180,13 +180,11 @@ _cairo_ps_surface_emit_header (cairo_ps_surface_t *surface)
" {\n"
" dup\n"
" type /stringtype eq\n"
" { show } { -0.001 mul 0 cairo_font_matrix dtransform rmoveto } ifelse\n"
" { show } { -0.0001 mul 0 rmoveto } ifelse\n"
" } forall\n"
"} bind def\n"
"/Td { matrix translate cairo_font_matrix matrix concatmatrix dup\n"
" /cairo_font_matrix exch def cairo_font exch selectfont 0 0 moveto } bind def\n"
"/Tm { 6 array astore dup /cairo_font_matrix exch def\n"
" cairo_font exch selectfont 0 0 moveto } bind def\n"
"/Td { moveto } bind def\n"
"/Tm { 6 array astore cairo_font exch selectfont 0 0 moveto } bind def\n"
"/g { setgray } bind def\n"
"/rg { setrgbcolor } bind def\n");
@ -860,15 +858,10 @@ _extract_ps_surface (cairo_surface_t *surface,
{
cairo_surface_t *target;
if (surface->status)
return surface->status;
if (! _cairo_surface_is_paginated (surface))
return _cairo_error (CAIRO_STATUS_SURFACE_TYPE_MISMATCH);
target = _cairo_paginated_surface_get_target (surface);
if (target->status)
return target->status;
if (! _cairo_surface_is_ps (target))
return _cairo_error (CAIRO_STATUS_SURFACE_TYPE_MISMATCH);
@ -2036,7 +2029,6 @@ _cairo_ps_surface_emit_meta_surface (cairo_ps_surface_t *surface,
double old_width, old_height;
cairo_matrix_t old_cairo_to_ps;
cairo_content_t old_content;
cairo_clip_t *old_clip;
cairo_rectangle_int_t meta_extents;
cairo_status_t status;
@ -2048,7 +2040,6 @@ _cairo_ps_surface_emit_meta_surface (cairo_ps_surface_t *surface,
old_width = surface->width;
old_height = surface->height;
old_cairo_to_ps = surface->cairo_to_ps;
old_clip = _cairo_surface_get_clip (&surface->base);
surface->width = meta_extents.width;
surface->height = meta_extents.height;
cairo_matrix_init (&surface->cairo_to_ps, 1, 0, 0, -1, 0, surface->height);
@ -2080,10 +2071,6 @@ _cairo_ps_surface_emit_meta_surface (cairo_ps_surface_t *surface,
surface->width = old_width;
surface->height = old_height;
surface->cairo_to_ps = old_cairo_to_ps;
status = _cairo_surface_set_clip (&surface->base, old_clip);
if (status)
return status;
_cairo_pdf_operators_set_cairo_to_pdf_matrix (&surface->pdf_operators,
&surface->cairo_to_ps);
@ -2148,23 +2135,17 @@ _cairo_ps_surface_acquire_surface (cairo_ps_surface_t *surface,
cairo_rectangle_int_t pattern_extents;
status = _cairo_surface_get_extents (meta_surface, &pattern_extents);
if (status)
return status;
*width = pattern_extents.width;
*height = pattern_extents.height;
} else {
status = _cairo_surface_acquire_source_image (pattern->surface,
&surface->image,
&surface->image_extra);
if (status)
return status;
*width = surface->image->width;
*height = surface->image->height;
}
return CAIRO_STATUS_SUCCESS;
return status;
}
static cairo_status_t
@ -2225,14 +2206,6 @@ _cairo_ps_surface_paint_surface (cairo_ps_surface_t *surface,
(int)(height/scale),
scale*72,
(long)width*height*3);
} else {
if (op == CAIRO_OPERATOR_SOURCE) {
_cairo_output_stream_printf (surface->stream,
"%d g 0 0 %f %f rectfill\n",
surface->content == CAIRO_CONTENT_COLOR ? 0 : 1,
surface->width,
surface->height);
}
}
status = cairo_matrix_invert (&cairo_p2d);
@ -2339,12 +2312,6 @@ _cairo_ps_surface_emit_surface_pattern (cairo_ps_surface_t *surface,
old_use_string_datasource = surface->use_string_datasource;
surface->use_string_datasource = TRUE;
if (op == CAIRO_OPERATOR_SOURCE) {
_cairo_output_stream_printf (surface->stream,
"%d g 0 0 %f %f rectfill\n",
surface->content == CAIRO_CONTENT_COLOR ? 0 : 1,
xstep, ystep);
}
status = _cairo_ps_surface_emit_surface (surface, pattern, op);
if (status)
return status;
@ -2376,17 +2343,10 @@ _cairo_ps_surface_emit_surface_pattern (cairo_ps_surface_t *surface,
pattern_height*2,
pattern_width*2);
} else {
if (op == CAIRO_OPERATOR_SOURCE) {
_cairo_output_stream_printf (surface->stream,
" /BBox [0 0 %f %f]\n",
xstep, ystep);
} else {
_cairo_output_stream_printf (surface->stream,
" /BBox [0 0 %d %d]\n",
pattern_width, pattern_height);
}
_cairo_output_stream_printf (surface->stream,
" /PaintProc { CairoPattern }\n");
" /BBox [0 0 %d %d]\n"
" /PaintProc { CairoPattern }\n",
pattern_width, pattern_height);
}
_cairo_output_stream_printf (surface->stream,
@ -2506,7 +2466,7 @@ _cairo_ps_surface_emit_pattern_stops (cairo_ps_surface_t *surface,
stops[i].color[1] = stop->color.green;
stops[i].color[2] = stop->color.blue;
stops[i].color[3] = stop->color.alpha;
stops[i].offset = pattern->stops[i].offset;
stops[i].offset = _cairo_fixed_to_double (pattern->stops[i].x);
}
if (pattern->base.extend == CAIRO_EXTEND_REPEAT ||
@ -2625,8 +2585,8 @@ _cairo_ps_surface_emit_linear_pattern (cairo_ps_surface_t *surface,
assert (status == CAIRO_STATUS_SUCCESS);
cairo_matrix_multiply (&pat_to_ps, &pat_to_ps, &surface->cairo_to_ps);
first_stop = gradient->stops[0].offset;
last_stop = gradient->stops[gradient->n_stops - 1].offset;
first_stop = _cairo_fixed_to_double (gradient->stops[0].x);
last_stop = _cairo_fixed_to_double (gradient->stops[gradient->n_stops - 1].x);
if (pattern->base.base.extend == CAIRO_EXTEND_REPEAT ||
pattern->base.base.extend == CAIRO_EXTEND_REFLECT) {
@ -2901,7 +2861,7 @@ _cairo_ps_surface_paint (void *abstract_surface,
{
cairo_ps_surface_t *surface = abstract_surface;
cairo_output_stream_t *stream = surface->stream;
cairo_rectangle_int_t extents;
cairo_rectangle_int_t extents, surface_extents;
cairo_status_t status;
if (surface->paginated_mode == CAIRO_PAGINATED_MODE_ANALYZE)
@ -2914,15 +2874,22 @@ _cairo_ps_surface_paint (void *abstract_surface,
"%% _cairo_ps_surface_paint\n");
#endif
status = _cairo_surface_get_extents (&surface->base, &extents);
status = _cairo_surface_get_extents (&surface->base, &surface_extents);
if (status)
return status;
status = _cairo_pattern_get_extents (source, &extents);
if (status)
return status;
_cairo_rectangle_intersect (&extents, &surface_extents);
if (source->type == CAIRO_PATTERN_TYPE_SURFACE &&
(source->extend == CAIRO_EXTEND_NONE ||
source->extend == CAIRO_EXTEND_PAD))
source->extend == CAIRO_EXTEND_NONE)
{
_cairo_output_stream_printf (stream, "q 0 0 %d %d rectclip\n",
_cairo_output_stream_printf (stream, "q %d %d %d %d rectclip\n",
extents.x,
surface_extents.height - extents.y - extents.height,
extents.width,
extents.height);
@ -2941,7 +2908,9 @@ _cairo_ps_surface_paint (void *abstract_surface,
if (status)
return status;
_cairo_output_stream_printf (stream, "0 0 %d %d rectfill\n",
_cairo_output_stream_printf (stream, "%d %d %d %d rectfill\n",
extents.x,
surface_extents.height - extents.y - extents.height,
extents.width,
extents.height);
}
@ -3007,8 +2976,7 @@ _cairo_ps_surface_fill (void *abstract_surface,
#endif
if (source->type == CAIRO_PATTERN_TYPE_SURFACE &&
(source->extend == CAIRO_EXTEND_NONE ||
source->extend == CAIRO_EXTEND_PAD))
source->extend == CAIRO_EXTEND_NONE)
{
_cairo_output_stream_printf (surface->stream, "q\n");

View File

@ -1,794 +0,0 @@
/* -*- Mode: c; c-basic-offset: 4; indent-tabs-mode: t; tab-width: 8; -*- */
/* cairo - a vector graphics library with display and print output
*
* Copyright <EFBFBD> 2008 Mozilla Corporation
*
* 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.
*
* The Initial Developer of the Original Code is Mozilla Corporation.
*
* Contributor(s):
* Vladimir Vukicevic <vladimir@mozilla.com>
*/
#include "cairoint.h"
#include <dlfcn.h>
#include "cairo-quartz.h"
#include "cairo-quartz-private.h"
/* CreateWithFontName exists in 10.5, but not in 10.4; CreateWithName isn't public in 10.4 */
static CGFontRef (*CGFontCreateWithFontNamePtr) (CFStringRef) = NULL;
static CGFontRef (*CGFontCreateWithNamePtr) (const char *) = NULL;
/* These aren't public before 10.5, and some have different names in 10.4 */
static int (*CGFontGetUnitsPerEmPtr) (CGFontRef) = NULL;
static bool (*CGFontGetGlyphAdvancesPtr) (CGFontRef, const CGGlyph[], size_t, int[]) = NULL;
static bool (*CGFontGetGlyphBBoxesPtr) (CGFontRef, const CGGlyph[], size_t, CGRect[]) = NULL;
static CGRect (*CGFontGetFontBBoxPtr) (CGFontRef) = NULL;
/* Not public, but present */
static void (*CGFontGetGlyphsForUnicharsPtr) (CGFontRef, const UniChar[], const CGGlyph[], size_t) = NULL;
/* Not public in the least bit */
static CGPathRef (*CGFontGetGlyphPathPtr) (CGFontRef fontRef, CGAffineTransform *textTransform, int unknown, CGGlyph glyph) = NULL;
/* CGFontGetHMetrics isn't public, but the other functions are public/present in 10.5 */
typedef struct {
int ascent;
int descent;
int leading;
} quartz_CGFontMetrics;
static quartz_CGFontMetrics* (*CGFontGetHMetricsPtr) (CGFontRef fontRef) = NULL;
static int (*CGFontGetAscentPtr) (CGFontRef fontRef) = NULL;
static int (*CGFontGetDescentPtr) (CGFontRef fontRef) = NULL;
static int (*CGFontGetLeadingPtr) (CGFontRef fontRef) = NULL;
static cairo_bool_t _cairo_quartz_font_symbol_lookup_done = FALSE;
static cairo_bool_t _cairo_quartz_font_symbols_present = FALSE;
static void
quartz_font_ensure_symbols(void)
{
if (_cairo_quartz_font_symbol_lookup_done)
return;
/* Look for the 10.5 versions first */
CGFontGetGlyphBBoxesPtr = dlsym(RTLD_DEFAULT, "CGFontGetGlyphBBoxes");
if (!CGFontGetGlyphBBoxesPtr)
CGFontGetGlyphBBoxesPtr = dlsym(RTLD_DEFAULT, "CGFontGetGlyphBoundingBoxes");
CGFontGetGlyphsForUnicharsPtr = dlsym(RTLD_DEFAULT, "CGFontGetGlyphsForUnichars");
if (!CGFontGetGlyphsForUnicharsPtr)
CGFontGetGlyphsForUnicharsPtr = dlsym(RTLD_DEFAULT, "CGFontGetGlyphsForUnicodes");
CGFontGetFontBBoxPtr = dlsym(RTLD_DEFAULT, "CGFontGetFontBBox");
/* We just need one of these two */
CGFontCreateWithFontNamePtr = dlsym(RTLD_DEFAULT, "CGFontCreateWithFontName");
CGFontCreateWithNamePtr = dlsym(RTLD_DEFAULT, "CGFontCreateWithName");
/* These have the same name in 10.4 and 10.5 */
CGFontGetUnitsPerEmPtr = dlsym(RTLD_DEFAULT, "CGFontGetUnitsPerEm");
CGFontGetGlyphAdvancesPtr = dlsym(RTLD_DEFAULT, "CGFontGetGlyphAdvances");
CGFontGetGlyphPathPtr = dlsym(RTLD_DEFAULT, "CGFontGetGlyphPath");
CGFontGetHMetricsPtr = dlsym(RTLD_DEFAULT, "CGFontGetHMetrics");
CGFontGetAscentPtr = dlsym(RTLD_DEFAULT, "CGFontGetAscent");
CGFontGetDescentPtr = dlsym(RTLD_DEFAULT, "CGFontGetDescent");
CGFontGetLeadingPtr = dlsym(RTLD_DEFAULT, "CGFontGetLeading");
if ((CGFontCreateWithFontNamePtr || CGFontCreateWithNamePtr) &&
CGFontGetGlyphBBoxesPtr &&
CGFontGetGlyphsForUnicharsPtr &&
CGFontGetUnitsPerEmPtr &&
CGFontGetGlyphAdvancesPtr &&
CGFontGetGlyphPathPtr &&
(CGFontGetHMetricsPtr || (CGFontGetAscentPtr && CGFontGetDescentPtr && CGFontGetLeadingPtr)))
_cairo_quartz_font_symbols_present = TRUE;
_cairo_quartz_font_symbol_lookup_done = TRUE;
}
typedef struct _cairo_quartz_font_face cairo_quartz_font_face_t;
typedef struct _cairo_quartz_scaled_font cairo_quartz_scaled_font_t;
struct _cairo_quartz_scaled_font {
cairo_scaled_font_t base;
};
struct _cairo_quartz_font_face {
cairo_font_face_t base;
CGFontRef cgFont;
};
/**
** font face backend
**/
static void
_cairo_quartz_font_face_destroy (void *abstract_face)
{
cairo_quartz_font_face_t *font_face = (cairo_quartz_font_face_t*) abstract_face;
CGFontRelease (font_face->cgFont);
}
static cairo_status_t
_cairo_quartz_font_face_scaled_font_create (void *abstract_face,
const cairo_matrix_t *font_matrix,
const cairo_matrix_t *ctm,
const cairo_font_options_t *options,
cairo_scaled_font_t **font_out)
{
cairo_quartz_font_face_t *font_face = abstract_face;
cairo_quartz_scaled_font_t *font = NULL;
cairo_status_t status;
cairo_font_extents_t fs_metrics;
double ems;
CGRect bbox;
quartz_font_ensure_symbols();
if (!_cairo_quartz_font_symbols_present)
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
font = malloc(sizeof(cairo_quartz_scaled_font_t));
if (font == NULL)
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
memset (font, 0, sizeof(cairo_quartz_scaled_font_t));
status = _cairo_scaled_font_init (&font->base,
&font_face->base, font_matrix, ctm, options,
&cairo_quartz_scaled_font_backend);
if (status)
goto FINISH;
ems = CGFontGetUnitsPerEmPtr (font_face->cgFont);
/* initialize metrics */
if (CGFontGetFontBBoxPtr && CGFontGetAscentPtr) {
fs_metrics.ascent = (CGFontGetAscentPtr (font_face->cgFont) / ems);
fs_metrics.descent = - (CGFontGetDescentPtr (font_face->cgFont) / ems);
fs_metrics.height = fs_metrics.ascent + fs_metrics.descent +
(CGFontGetLeadingPtr (font_face->cgFont) / ems);
bbox = CGFontGetFontBBoxPtr (font_face->cgFont);
fs_metrics.max_x_advance = CGRectGetMaxX(bbox) / ems;
fs_metrics.max_y_advance = 0.0;
} else {
CGGlyph wGlyph;
UniChar u;
quartz_CGFontMetrics *m;
m = CGFontGetHMetricsPtr (font_face->cgFont);
fs_metrics.ascent = (m->ascent / ems);
fs_metrics.descent = - (m->descent / ems);
fs_metrics.height = fs_metrics.ascent + fs_metrics.descent + (m->leading / ems);
/* We kind of have to guess here; W's big, right? */
u = (UniChar) 'W';
CGFontGetGlyphsForUnicharsPtr (font_face->cgFont, &u, &wGlyph, 1);
if (wGlyph && CGFontGetGlyphBBoxesPtr (font_face->cgFont, &wGlyph, 1, &bbox)) {
fs_metrics.max_x_advance = CGRectGetMaxX(bbox) / ems;
fs_metrics.max_y_advance = 0.0;
} else {
fs_metrics.max_x_advance = 0.0;
fs_metrics.max_y_advance = 0.0;
}
}
status = _cairo_scaled_font_set_metrics (&font->base, &fs_metrics);
FINISH:
if (status != CAIRO_STATUS_SUCCESS) {
free (font);
} else {
*font_out = (cairo_scaled_font_t*) font;
}
return status;
}
static const cairo_font_face_backend_t _cairo_quartz_font_face_backend = {
CAIRO_FONT_TYPE_QUARTZ,
_cairo_quartz_font_face_destroy,
_cairo_quartz_font_face_scaled_font_create
};
/**
* cairo_quartz_font_face_create_for_cgfont
* @font: a #CGFontRef obtained through a method external to cairo.
*
* Creates a new font for the Quartz font backend based on a
* #CGFontRef. This font can then be used with
* cairo_set_font_face() or cairo_scaled_font_create().
*
* Return value: a newly created #cairo_font_face_t. Free with
* cairo_font_face_destroy() when you are done using it.
*
* Since: 1.6
*/
cairo_font_face_t *
cairo_quartz_font_face_create_for_cgfont (CGFontRef font)
{
cairo_quartz_font_face_t *font_face;
quartz_font_ensure_symbols();
font_face = malloc (sizeof (cairo_quartz_font_face_t));
if (!font_face) {
_cairo_error (CAIRO_STATUS_NO_MEMORY);
return (cairo_font_face_t *)&_cairo_font_face_nil;
}
font_face->cgFont = CGFontRetain (font);
_cairo_font_face_init (&font_face->base, &_cairo_quartz_font_face_backend);
return &font_face->base;
}
/**
** scaled font backend
**/
static cairo_quartz_font_face_t *
_cairo_quartz_scaled_to_face (void *abstract_font)
{
cairo_quartz_scaled_font_t *sfont = (cairo_quartz_scaled_font_t*) abstract_font;
cairo_font_face_t *font_face = cairo_scaled_font_get_font_face (&sfont->base);
if (!font_face || font_face->backend->type != CAIRO_FONT_TYPE_QUARTZ)
return NULL;
return (cairo_quartz_font_face_t*) font_face;
}
static cairo_status_t
_cairo_quartz_font_create_toy(cairo_toy_font_face_t *toy_face,
const cairo_matrix_t *font_matrix,
const cairo_matrix_t *ctm,
const cairo_font_options_t *options,
cairo_scaled_font_t **font_out)
{
const char *family = toy_face->family;
char *full_name = malloc(strlen(family) + 64); // give us a bit of room to tack on Bold, Oblique, etc.
CFStringRef cgFontName = NULL;
CGFontRef cgFont = NULL;
int loop;
cairo_status_t status;
cairo_font_face_t *face;
cairo_scaled_font_t *scaled_font;
quartz_font_ensure_symbols();
if (!_cairo_quartz_font_symbols_present)
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
/* handle CSS-ish faces */
if (!strcmp(family, "serif") || !strcmp(family, "Times Roman"))
family = "Times";
else if (!strcmp(family, "sans-serif") || !strcmp(family, "sans"))
family = "Helvetica";
else if (!strcmp(family, "cursive"))
family = "Apple Chancery";
else if (!strcmp(family, "fantasy"))
family = "Papyrus";
else if (!strcmp(family, "monospace") || !strcmp(family, "mono"))
family = "Courier";
/* Try to build up the full name, e.g. "Helvetica Bold Oblique" first,
* then drop the bold, then drop the slant, then drop both.. finally
* just use "Helvetica". And if Helvetica doesn't exist, give up.
*/
for (loop = 0; loop < 5; loop++) {
if (loop == 4)
family = "Helvetica";
strcpy (full_name, family);
if (loop < 3 && (loop & 1) == 0) {
if (toy_face->weight == CAIRO_FONT_WEIGHT_BOLD)
strcat (full_name, " Bold");
}
if (loop < 3 && (loop & 2) == 0) {
if (toy_face->slant == CAIRO_FONT_SLANT_ITALIC)
strcat (full_name, " Italic");
else if (toy_face->slant == CAIRO_FONT_SLANT_OBLIQUE)
strcat (full_name, " Oblique");
}
if (CGFontCreateWithFontNamePtr) {
cgFontName = CFStringCreateWithCString (NULL, full_name, kCFStringEncodingASCII);
cgFont = CGFontCreateWithFontNamePtr (cgFontName);
CFRelease (cgFontName);
} else {
cgFont = CGFontCreateWithNamePtr (full_name);
}
if (cgFont)
break;
}
if (!cgFont) {
/* Give up */
return CAIRO_STATUS_NO_MEMORY;
}
face = cairo_quartz_font_face_create_for_cgfont (cgFont);
if (face->status)
return face->status;
status = _cairo_quartz_font_face_scaled_font_create (face,
font_matrix, ctm,
options,
&scaled_font);
cairo_font_face_destroy (face);
if (status)
return status;
*font_out = scaled_font;
return CAIRO_STATUS_SUCCESS;
}
static void
_cairo_quartz_font_fini(void *abstract_font)
{
}
#define INVALID_GLYPH 0x00
static inline CGGlyph
_cairo_quartz_scaled_glyph_index (cairo_scaled_glyph_t *scaled_glyph) {
unsigned long index = _cairo_scaled_glyph_index (scaled_glyph);
if (index > 0xffff)
return INVALID_GLYPH;
return (CGGlyph) index;
}
static inline cairo_status_t
_cairo_matrix_to_unit_quartz_matrix (const cairo_matrix_t *m, CGAffineTransform *txout,
double *xout, double *yout)
{
CGAffineTransform transform;
double xscale, yscale;
cairo_status_t status;
status = _cairo_matrix_compute_scale_factors (m, &xscale, &yscale, 1);
if (status)
return status;
transform = CGAffineTransformMake (m->xx, - m->yx,
- m->xy, m->yy,
0.0f, 0.0f);
if (xout)
*xout = xscale;
if (yout)
*yout = yscale;
if (xscale)
xscale = 1.0 / xscale;
if (yscale)
yscale = 1.0 / yscale;
*txout = CGAffineTransformScale (transform, xscale, yscale);
return CAIRO_STATUS_SUCCESS;
}
static cairo_int_status_t
_cairo_quartz_init_glyph_metrics (cairo_quartz_scaled_font_t *font,
cairo_scaled_glyph_t *scaled_glyph)
{
cairo_int_status_t status = CAIRO_STATUS_SUCCESS;
cairo_quartz_font_face_t *font_face = _cairo_quartz_scaled_to_face(font);
cairo_text_extents_t extents = {0, 0, 0, 0, 0, 0};
CGAffineTransform textMatrix;
CGGlyph glyph = _cairo_quartz_scaled_glyph_index (scaled_glyph);
int advance;
CGRect bbox;
double emscale = CGFontGetUnitsPerEmPtr (font_face->cgFont);
double xscale, yscale;
double xmin, ymin, xmax, ymax;
if (glyph == INVALID_GLYPH)
goto FAIL;
if (!CGFontGetGlyphAdvancesPtr (font_face->cgFont, &glyph, 1, &advance) ||
!CGFontGetGlyphBBoxesPtr (font_face->cgFont, &glyph, 1, &bbox))
goto FAIL;
status = _cairo_matrix_compute_scale_factors (&font->base.scale,
&xscale, &yscale, 1);
if (status)
goto FAIL;
bbox = CGRectMake (bbox.origin.x / emscale,
bbox.origin.y / emscale,
bbox.size.width / emscale,
bbox.size.height / emscale);
/* Should we want to always integer-align glyph extents, we can do so in this way */
#if 0
{
CGAffineTransform textMatrix;
textMatrix = CGAffineTransformMake (font->base.scale.xx,
-font->base.scale.yx,
-font->base.scale.xy,
font->base.scale.yy,
0.0f, 0.0f);
bbox = CGRectApplyAffineTransform (bbox, textMatrix);
bbox = CGRectIntegral (bbox);
bbox = CGRectApplyAffineTransform (bbox, CGAffineTransformInvert (textMatrix));
}
#endif
#if 0
fprintf (stderr, "[0x%04x] bbox: %f %f %f %f\n", glyph,
bbox.origin.x / emscale, bbox.origin.y / emscale,
bbox.size.width / emscale, bbox.size.height / emscale);
#endif
xmin = CGRectGetMinX(bbox);
ymin = CGRectGetMinY(bbox);
xmax = CGRectGetMaxX(bbox);
ymax = CGRectGetMaxY(bbox);
extents.x_bearing = xmin;
extents.y_bearing = - ymax;
extents.width = xmax - xmin;
extents.height = ymax - ymin;
extents.x_advance = (double) advance / emscale;
extents.y_advance = 0.0;
#if 0
fprintf (stderr, "[0x%04x] extents: bearings: %f %f dim: %f %f adv: %f\n\n", glyph,
extents.x_bearing, extents.y_bearing, extents.width, extents.height, extents.x_advance);
#endif
FAIL:
_cairo_scaled_glyph_set_metrics (scaled_glyph,
&font->base,
&extents);
return status;
}
static void
_cairo_quartz_path_apply_func (void *info, const CGPathElement *el)
{
cairo_path_fixed_t *path = (cairo_path_fixed_t *) info;
switch (el->type) {
case kCGPathElementMoveToPoint:
_cairo_path_fixed_move_to (path,
_cairo_fixed_from_double(el->points[0].x),
_cairo_fixed_from_double(el->points[0].y));
break;
case kCGPathElementAddLineToPoint:
_cairo_path_fixed_line_to (path,
_cairo_fixed_from_double(el->points[0].x),
_cairo_fixed_from_double(el->points[0].y));
break;
case kCGPathElementAddQuadCurveToPoint: {
cairo_fixed_t fx, fy;
double x, y;
if (!_cairo_path_fixed_get_current_point (path, &fx, &fy))
fx = fy = 0;
x = _cairo_fixed_to_double (fx);
y = _cairo_fixed_to_double (fy);
_cairo_path_fixed_curve_to (path,
_cairo_fixed_from_double((x + el->points[0].x * 2.0) / 3.0),
_cairo_fixed_from_double((y + el->points[0].y * 2.0) / 3.0),
_cairo_fixed_from_double((el->points[0].x * 2.0 + el->points[1].x) / 3.0),
_cairo_fixed_from_double((el->points[0].y * 2.0 + el->points[1].y) / 3.0),
_cairo_fixed_from_double(el->points[1].x),
_cairo_fixed_from_double(el->points[1].y));
}
break;
case kCGPathElementAddCurveToPoint:
_cairo_path_fixed_curve_to (path,
_cairo_fixed_from_double(el->points[0].x),
_cairo_fixed_from_double(el->points[0].y),
_cairo_fixed_from_double(el->points[1].x),
_cairo_fixed_from_double(el->points[1].y),
_cairo_fixed_from_double(el->points[2].x),
_cairo_fixed_from_double(el->points[2].y));
break;
case kCGPathElementCloseSubpath:
_cairo_path_fixed_close_path (path);
break;
}
}
static cairo_int_status_t
_cairo_quartz_init_glyph_path (cairo_quartz_scaled_font_t *font,
cairo_scaled_glyph_t *scaled_glyph)
{
cairo_quartz_font_face_t *font_face = _cairo_quartz_scaled_to_face(font);
CGGlyph glyph = _cairo_quartz_scaled_glyph_index (scaled_glyph);
CGAffineTransform textMatrix;
CGPathRef glyphPath;
cairo_path_fixed_t *path;
if (glyph == INVALID_GLYPH) {
_cairo_scaled_glyph_set_path (scaled_glyph, &font->base, _cairo_path_fixed_create());
return CAIRO_STATUS_SUCCESS;
}
textMatrix = CGAffineTransformMake (font->base.scale.xx,
-font->base.scale.yx,
-font->base.scale.xy,
font->base.scale.yy,
font->base.scale.x0,
font->base.scale.y0);
textMatrix = CGAffineTransformConcat (textMatrix, CGAffineTransformMake (1.0, 0.0, 0.0, -1.0, 0.0, 0.0));
glyphPath = CGFontGetGlyphPathPtr (font_face->cgFont, &textMatrix, 0, glyph);
if (!glyphPath)
return CAIRO_INT_STATUS_UNSUPPORTED;
path = _cairo_path_fixed_create ();
if (!path) {
CGPathRelease (glyphPath);
return _cairo_error(CAIRO_STATUS_NO_MEMORY);
}
CGPathApply (glyphPath, path, _cairo_quartz_path_apply_func);
CGPathRelease (glyphPath);
_cairo_scaled_glyph_set_path (scaled_glyph, &font->base, path);
return CAIRO_STATUS_SUCCESS;
}
static cairo_int_status_t
_cairo_quartz_init_glyph_surface (cairo_quartz_scaled_font_t *font,
cairo_scaled_glyph_t *scaled_glyph)
{
cairo_int_status_t status = CAIRO_STATUS_SUCCESS;
cairo_quartz_font_face_t *font_face = _cairo_quartz_scaled_to_face(font);
cairo_image_surface_t *surface = NULL;
CGGlyph glyph = _cairo_quartz_scaled_glyph_index (scaled_glyph);
int advance;
CGRect bbox;
double width, height;
double xscale, yscale;
double emscale = CGFontGetUnitsPerEmPtr (font_face->cgFont);
CGColorSpaceRef gray;
CGContextRef cgContext = NULL;
CGAffineTransform textMatrix;
CGRect glyphRect, glyphRectInt;
CGPoint glyphOrigin;
//fprintf (stderr, "scaled_glyph: %p surface: %p\n", scaled_glyph, scaled_glyph->surface);
/* Create blank 2x2 image if we don't have this character.
* Maybe we should draw a better missing-glyph slug or something,
* but this is ok for now.
*/
if (glyph == INVALID_GLYPH) {
surface = (cairo_image_surface_t*) cairo_image_surface_create (CAIRO_FORMAT_A8, 2, 2);
status = cairo_surface_status ((cairo_surface_t *) surface);
if (status)
return status;
_cairo_scaled_glyph_set_surface (scaled_glyph,
&font->base,
surface);
return CAIRO_STATUS_SUCCESS;
}
if (!CGFontGetGlyphAdvancesPtr (font_face->cgFont, &glyph, 1, &advance) ||
!CGFontGetGlyphBBoxesPtr (font_face->cgFont, &glyph, 1, &bbox))
{
return CAIRO_INT_STATUS_UNSUPPORTED;
}
status = _cairo_matrix_compute_scale_factors (&font->base.scale,
&xscale, &yscale, 1);
if (status)
return status;
textMatrix = CGAffineTransformMake (font->base.scale.xx,
-font->base.scale.yx,
-font->base.scale.xy,
font->base.scale.yy,
0.0f, 0.0f);
glyphRect = CGRectMake (bbox.origin.x / emscale,
bbox.origin.y / emscale,
bbox.size.width / emscale,
bbox.size.height / emscale);
glyphRect = CGRectApplyAffineTransform (glyphRect, textMatrix);
/* Round the rectangle outwards, so that we don't have to deal
* with non-integer-pixel origins or dimensions.
*/
glyphRectInt = CGRectIntegral (glyphRect);
#if 0
fprintf (stderr, "glyphRect[o]: %f %f %f %f\n",
glyphRect.origin.x, glyphRect.origin.y, glyphRect.size.width, glyphRect.size.height);
fprintf (stderr, "glyphRectInt: %f %f %f %f\n",
glyphRectInt.origin.x, glyphRectInt.origin.y, glyphRectInt.size.width, glyphRectInt.size.height);
#endif
glyphOrigin = glyphRectInt.origin;
//textMatrix = CGAffineTransformConcat (textMatrix, CGAffineTransformInvert (ctm));
width = glyphRectInt.size.width;
height = glyphRectInt.size.height;
//fprintf (stderr, "glyphRect[n]: %f %f %f %f\n", glyphRect.origin.x, glyphRect.origin.y, glyphRect.size.width, glyphRect.size.height);
surface = (cairo_image_surface_t*) cairo_image_surface_create (CAIRO_FORMAT_A8, width, height);
if (surface->base.status)
return surface->base.status;
gray = CGColorSpaceCreateDeviceGray ();
cgContext = CGBitmapContextCreate (surface->data,
surface->width,
surface->height,
8,
surface->stride,
gray,
kCGImageAlphaNone);
CGColorSpaceRelease (gray);
CGContextSetFont (cgContext, font_face->cgFont);
CGContextSetFontSize (cgContext, 1.0);
CGContextSetTextMatrix (cgContext, textMatrix);
CGContextClearRect (cgContext, CGRectMake (0.0f, 0.0f, width, height));
if (font->base.options.antialias == CAIRO_ANTIALIAS_NONE)
CGContextSetShouldAntialias (cgContext, false);
CGContextSetRGBFillColor (cgContext, 1.0, 1.0, 1.0, 1.0);
CGContextShowGlyphsAtPoint (cgContext, - glyphOrigin.x, - glyphOrigin.y, &glyph, 1);
CGContextRelease (cgContext);
cairo_surface_set_device_offset (&surface->base,
- glyphOrigin.x,
height + glyphOrigin.y);
_cairo_scaled_glyph_set_surface (scaled_glyph, &font->base, surface);
return status;
}
static cairo_int_status_t
_cairo_quartz_font_scaled_glyph_init (void *abstract_font,
cairo_scaled_glyph_t *scaled_glyph,
cairo_scaled_glyph_info_t info)
{
cairo_quartz_scaled_font_t *font = (cairo_quartz_scaled_font_t *) abstract_font;
cairo_int_status_t status = CAIRO_STATUS_SUCCESS;
if (!status && (info & CAIRO_SCALED_GLYPH_INFO_METRICS))
status = _cairo_quartz_init_glyph_metrics (font, scaled_glyph);
if (!status && (info & CAIRO_SCALED_GLYPH_INFO_PATH))
status = _cairo_quartz_init_glyph_path (font, scaled_glyph);
if (!status && (info & CAIRO_SCALED_GLYPH_INFO_SURFACE))
status = _cairo_quartz_init_glyph_surface (font, scaled_glyph);
return status;
}
static unsigned long
_cairo_quartz_ucs4_to_index (void *abstract_font,
uint32_t ucs4)
{
cairo_quartz_scaled_font_t *font = (cairo_quartz_scaled_font_t*) abstract_font;
cairo_quartz_font_face_t *ffont = _cairo_quartz_scaled_to_face(font);
UniChar u = (UniChar) ucs4;
CGGlyph glyph;
CGFontGetGlyphsForUnicharsPtr (ffont->cgFont, &u, &glyph, 1);
return glyph;
}
const cairo_scaled_font_backend_t cairo_quartz_scaled_font_backend = {
CAIRO_FONT_TYPE_QUARTZ,
_cairo_quartz_font_create_toy,
_cairo_quartz_font_fini,
_cairo_quartz_font_scaled_glyph_init,
NULL, /* text_to_glyphs */
_cairo_quartz_ucs4_to_index,
NULL, /* show_glyphs */
NULL, /* load_truetype_table */
NULL, /* map_glyphs_to_unicode */
};
/*
* private methods that the quartz surface uses
*/
CGFontRef
_cairo_quartz_scaled_font_get_cg_font_ref (cairo_scaled_font_t *abstract_font)
{
cairo_quartz_font_face_t *ffont = _cairo_quartz_scaled_to_face(abstract_font);
return ffont->cgFont;
}
/*
* compat with old ATSUI backend
*/
/**
* cairo_quartz_font_face_create_for_atsu_font_id
* @font_id: an ATSUFontID for the font.
*
* Creates a new font for the Quartz font backend based on an
* #ATSUFontID. This font can then be used with
* cairo_set_font_face() or cairo_scaled_font_create().
*
* Return value: a newly created #cairo_font_face_t. Free with
* cairo_font_face_destroy() when you are done using it.
*
* Since: 1.6
**/
cairo_font_face_t *
cairo_quartz_font_face_create_for_atsu_font_id (ATSUFontID font_id)
{
ATSFontRef atsFont = FMGetATSFontRefFromFont (font_id);
CGFontRef cgFont = CGFontCreateWithPlatformFont (&atsFont);
return cairo_quartz_font_face_create_for_cgfont (cgFont);
}
/* This is the old name for the above function, exported for compat purposes */
cairo_font_face_t *cairo_atsui_font_face_create_for_atsu_font_id (ATSUFontID font_id);
cairo_font_face_t *
cairo_atsui_font_face_create_for_atsu_font_id (ATSUFontID font_id)
{
return cairo_quartz_font_face_create_for_atsu_font_id (font_id);
}

View File

@ -92,14 +92,17 @@ _cairo_quartz_create_cgimage (cairo_format_t format,
CGDataProviderReleaseDataCallback releaseCallback,
void *releaseInfo);
CGFontRef
_cairo_quartz_scaled_font_get_cg_font_ref (cairo_scaled_font_t *sfont);
#endif /* CAIRO_HAS_QUARTZ_SURFACE */
#if CAIRO_HAS_CGFONT_FONT
#if CAIRO_HAS_ATSUI_FONT
ATSUStyle
_cairo_atsui_scaled_font_get_atsu_style (cairo_scaled_font_t *sfont);
ATSUFontID
_cairo_atsui_scaled_font_get_atsu_font_id (cairo_scaled_font_t *sfont);
CGFontRef
_cairo_cgfont_scaled_font_get_cg_font_ref (cairo_scaled_font_t *sfont);
#endif /* CAIRO_HAS_CGFONT_FONT */
_cairo_atsui_scaled_font_get_cg_font_ref (cairo_scaled_font_t *sfont);
#endif /* CAIRO_HAS_ATSUI_FONT */
#endif /* CAIRO_QUARTZ_PRIVATE_H */

View File

@ -48,6 +48,7 @@
#define FloatToFixed(a) ((Fixed)((float)(a) * fixed1))
#endif
#include <Carbon/Carbon.h>
#include <limits.h>
#undef QUARTZ_DEBUG
@ -101,14 +102,13 @@ CG_EXTERN void CGContextReplacePathWithStrokedPath (CGContextRef);
CG_EXTERN CGImageRef CGBitmapContextCreateImage (CGContextRef);
#endif
/* Some of these are present in earlier versions of the OS than where
* they are public; others are not public at all (CGContextCopyPath,
* CGContextReplacePathWithClipPath, many of the getters, etc.)
*/
/* Only present in 10.4+ */
static void (*CGContextClipToMaskPtr) (CGContextRef, CGRect, CGImageRef) = NULL;
/* Only present in 10.5+ */
static void (*CGContextDrawTiledImagePtr) (CGContextRef, CGRect, CGImageRef) = NULL;
static unsigned int (*CGContextGetTypePtr) (CGContextRef) = NULL;
static void (*CGContextSetShouldAntialiasFontsPtr) (CGContextRef, bool) = NULL;
static void (*CGContextSetShouldSmoothFontsPtr) (CGContextRef, bool) = NULL;
static bool (*CGContextGetShouldAntialiasFontsPtr) (CGContextRef) = NULL;
static bool (*CGContextGetShouldSmoothFontsPtr) (CGContextRef) = NULL;
static void (*CGContextSetAllowsFontSmoothingPtr) (CGContextRef, bool) = NULL;
@ -116,8 +116,6 @@ static bool (*CGContextGetAllowsFontSmoothingPtr) (CGContextRef) = NULL;
static CGPathRef (*CGContextCopyPathPtr) (CGContextRef) = NULL;
static void (*CGContextReplacePathWithClipPathPtr) (CGContextRef) = NULL;
static SInt32 _cairo_quartz_osx_version = 0x0;
static cairo_bool_t _cairo_quartz_symbol_lookup_done = FALSE;
/*
@ -145,6 +143,7 @@ static void quartz_ensure_symbols(void)
CGContextDrawTiledImagePtr = dlsym(RTLD_DEFAULT, "CGContextDrawTiledImage");
CGContextGetTypePtr = dlsym(RTLD_DEFAULT, "CGContextGetType");
CGContextSetShouldAntialiasFontsPtr = dlsym(RTLD_DEFAULT, "CGContextSetShouldAntialiasFonts");
CGContextSetShouldSmoothFontsPtr = dlsym(RTLD_DEFAULT, "CGContextSetShouldSmoothFonts");
CGContextGetShouldAntialiasFontsPtr = dlsym(RTLD_DEFAULT, "CGContextGetShouldAntialiasFonts");
CGContextGetShouldSmoothFontsPtr = dlsym(RTLD_DEFAULT, "CGContextGetShouldSmoothFonts");
CGContextCopyPathPtr = dlsym(RTLD_DEFAULT, "CGContextCopyPath");
@ -152,11 +151,6 @@ static void quartz_ensure_symbols(void)
CGContextGetAllowsFontSmoothingPtr = dlsym(RTLD_DEFAULT, "CGContextGetAllowsFontSmoothing");
CGContextSetAllowsFontSmoothingPtr = dlsym(RTLD_DEFAULT, "CGContextSetAllowsFontSmoothing");
if (Gestalt(gestaltSystemVersion, &_cairo_quartz_osx_version) != noErr) {
// assume 10.4
_cairo_quartz_osx_version = 0x1040;
}
_cairo_quartz_symbol_lookup_done = TRUE;
}
@ -485,10 +479,6 @@ _cairo_quartz_fixup_unbounded_operation (cairo_quartz_surface_t *surface,
CGContextTranslateCTM (cgc, op->u.show_glyphs.origin.x, op->u.show_glyphs.origin.y);
if (op->u.show_glyphs.isClipping) {
/* Note that the comment in show_glyphs about kCGTextClip
* and the text transform still applies here; however, the
* cg_advances we have were already transformed, so we
* don't have to do anything. */
CGContextSetTextDrawingMode (cgc, kCGTextClip);
CGContextSaveGState (cgc);
}
@ -550,6 +540,7 @@ static void
ComputeGradientValue (void *info, const float *in, float *out)
{
double fdist = *in;
cairo_fixed_t fdist_fix;
cairo_gradient_pattern_t *grad = (cairo_gradient_pattern_t*) info;
unsigned int i;
@ -565,8 +556,10 @@ ComputeGradientValue (void *info, const float *in, float *out)
}
}
fdist_fix = _cairo_fixed_from_double(fdist);
for (i = 0; i < grad->n_stops; i++) {
if (grad->stops[i].offset > fdist)
if (grad->stops[i].x > fdist_fix)
break;
}
@ -578,8 +571,8 @@ ComputeGradientValue (void *info, const float *in, float *out)
out[2] = grad->stops[i].color.blue;
out[3] = grad->stops[i].color.alpha;
} else {
float ax = grad->stops[i-1].offset;
float bx = grad->stops[i].offset - ax;
float ax = _cairo_fixed_to_double(grad->stops[i-1].x);
float bx = _cairo_fixed_to_double(grad->stops[i].x) - ax;
float bp = (fdist - ax)/bx;
float ap = 1.0 - bp;
@ -1738,7 +1731,7 @@ _cairo_quartz_surface_stroke (void *abstract_surface,
cairo_int_status_t rv = CAIRO_STATUS_SUCCESS;
cairo_quartz_action_t action;
quartz_stroke_t stroke;
CGAffineTransform origCTM, strokeTransform;
CGAffineTransform strokeTransform;
CGPathRef path_for_unbounded = NULL;
ND((stderr, "%p _cairo_quartz_surface_stroke op %d source->type %d\n", surface, op, source->type));
@ -1759,9 +1752,6 @@ _cairo_quartz_surface_stroke (void *abstract_surface,
CGContextSetLineCap (surface->cgContext, _cairo_quartz_cairo_line_cap_to_quartz (style->line_cap));
CGContextSetLineJoin (surface->cgContext, _cairo_quartz_cairo_line_join_to_quartz (style->line_join));
CGContextSetMiterLimit (surface->cgContext, style->miter_limit);
origCTM = CGContextGetCTM (surface->cgContext);
_cairo_quartz_cairo_matrix_to_quartz (ctm, &strokeTransform);
CGContextConcatCTM (surface->cgContext, strokeTransform);
@ -1808,8 +1798,6 @@ _cairo_quartz_surface_stroke (void *abstract_surface,
CGContextReplacePathWithStrokedPath (surface->cgContext);
CGContextClip (surface->cgContext);
CGContextSetCTM (surface->cgContext, origCTM);
CGContextConcatCTM (surface->cgContext, surface->sourceTransform);
CGContextTranslateCTM (surface->cgContext, 0, surface->sourceImageRect.size.height);
CGContextScaleCTM (surface->cgContext, 1, -1);
@ -1822,8 +1810,6 @@ _cairo_quartz_surface_stroke (void *abstract_surface,
CGContextReplacePathWithStrokedPath (surface->cgContext);
CGContextClip (surface->cgContext);
CGContextSetCTM (surface->cgContext, origCTM);
CGContextConcatCTM (surface->cgContext, surface->sourceTransform);
CGContextDrawShading (surface->cgContext, surface->sourceShading);
} else if (action != DO_NOTHING) {
@ -1868,7 +1854,7 @@ _cairo_quartz_surface_stroke (void *abstract_surface,
return rv;
}
#if CAIRO_HAS_QUARTZ_FONT
#if CAIRO_HAS_ATSUI_FONT
static cairo_int_status_t
_cairo_quartz_surface_show_glyphs (void *abstract_surface,
cairo_operator_t op,
@ -1903,7 +1889,7 @@ _cairo_quartz_surface_show_glyphs (void *abstract_surface,
if (op == CAIRO_OPERATOR_DEST)
return CAIRO_STATUS_SUCCESS;
if (cairo_scaled_font_get_type (scaled_font) != CAIRO_FONT_TYPE_QUARTZ)
if (cairo_scaled_font_get_type (scaled_font) != CAIRO_FONT_TYPE_ATSUI)
return CAIRO_INT_STATUS_UNSUPPORTED;
CGContextSaveGState (surface->cgContext);
@ -1923,31 +1909,33 @@ _cairo_quartz_surface_show_glyphs (void *abstract_surface,
CGContextSetCompositeOperation (surface->cgContext, _cairo_quartz_cairo_operator_to_quartz (op));
/* this doesn't addref */
cgfref = _cairo_quartz_scaled_font_get_cg_font_ref (scaled_font);
cgfref = _cairo_atsui_scaled_font_get_cg_font_ref (scaled_font);
CGContextSetFont (surface->cgContext, cgfref);
CGContextSetFontSize (surface->cgContext, 1.0);
switch (scaled_font->options.antialias) {
case CAIRO_ANTIALIAS_SUBPIXEL:
CGContextSetShouldAntialias (surface->cgContext, TRUE);
CGContextSetShouldSmoothFonts (surface->cgContext, TRUE);
if (CGContextSetAllowsFontSmoothingPtr &&
!CGContextGetAllowsFontSmoothingPtr (surface->cgContext))
{
didForceFontSmoothing = TRUE;
CGContextSetAllowsFontSmoothingPtr (surface->cgContext, TRUE);
}
break;
case CAIRO_ANTIALIAS_NONE:
CGContextSetShouldAntialias (surface->cgContext, FALSE);
break;
case CAIRO_ANTIALIAS_GRAY:
CGContextSetShouldAntialias (surface->cgContext, TRUE);
CGContextSetShouldSmoothFonts (surface->cgContext, FALSE);
break;
case CAIRO_ANTIALIAS_DEFAULT:
/* Don't do anything */
break;
if (CGContextSetShouldAntialiasFontsPtr) {
switch (scaled_font->options.antialias) {
case CAIRO_ANTIALIAS_SUBPIXEL:
CGContextSetShouldAntialiasFontsPtr (surface->cgContext, TRUE);
CGContextSetShouldSmoothFontsPtr (surface->cgContext, TRUE);
if (CGContextSetAllowsFontSmoothingPtr &&
!CGContextGetAllowsFontSmoothingPtr (surface->cgContext))
{
didForceFontSmoothing = TRUE;
CGContextSetAllowsFontSmoothingPtr (surface->cgContext, TRUE);
}
break;
case CAIRO_ANTIALIAS_NONE:
CGContextSetShouldAntialiasFontsPtr (surface->cgContext, FALSE);
break;
case CAIRO_ANTIALIAS_GRAY:
CGContextSetShouldAntialiasFontsPtr (surface->cgContext, TRUE);
CGContextSetShouldSmoothFontsPtr (surface->cgContext, FALSE);
break;
case CAIRO_ANTIALIAS_DEFAULT:
/* Don't do anything */
break;
}
}
if (num_glyphs > STATIC_BUF_SIZE) {
@ -1996,13 +1984,10 @@ _cairo_quartz_surface_show_glyphs (void *abstract_surface,
yprev = yf;
}
if (_cairo_quartz_osx_version >= 0x1050 && isClipping) {
/* If we're clipping, OSX 10.5 (at least as of 10.5.2) has a
* bug (apple bug ID #5834794) where the glyph
* advances/positions are not transformed by the text matrix
* if kCGTextClip is being used. So, we pre-transform here.
* 10.4 does not have this problem (as of 10.4.11).
*/
if (isClipping) {
/* If we're clipping, we get multiplied by the inverse of our text matrix; no,
* I don't understand why this is any different. So pre-apply our textTransform.
* Note that the new CGContextShowGlyphsAtPositions has a similar problem. */
for (i = 0; i < num_glyphs - 1; i++)
cg_advances[i] = CGSizeApplyAffineTransform(cg_advances[i], textTransform);
}
@ -2075,7 +2060,7 @@ BAIL:
return rv;
}
#endif /* CAIRO_HAS_QUARTZ_FONT */
#endif /* CAIRO_HAS_ATSUI_FONT */
static cairo_int_status_t
_cairo_quartz_surface_mask_with_surface (cairo_quartz_surface_t *surface,
@ -2308,11 +2293,11 @@ static const struct _cairo_surface_backend cairo_quartz_surface_backend = {
_cairo_quartz_surface_mask,
_cairo_quartz_surface_stroke,
_cairo_quartz_surface_fill,
#if CAIRO_HAS_QUARTZ_FONT
#if CAIRO_HAS_ATSUI_FONT
_cairo_quartz_surface_show_glyphs,
#else
NULL, /* show_glyphs */
#endif
NULL, /* surface_show_glyphs */
#endif /* CAIRO_HAS_ATSUI_FONT */
NULL, /* snapshot */
NULL, /* is_similar */
@ -2373,20 +2358,22 @@ _cairo_quartz_surface_create_internal (CGContextRef cgContext,
* @height: height of the surface, in pixels
*
* Creates a Quartz surface that wraps the given CGContext. The
* CGContext is assumed to be in the standard Cairo coordinate space
* (that is, with the origin at the upper left and the Y axis
* increasing downward). If the CGContext is in the Quartz coordinate
* space (with the origin at the bottom left), then it should be
* flipped before this function is called. The flip can be accomplished
* using a translate and a scale; for example:
* CGContext is assumed to be in the QuickDraw coordinate space (that
* is, with the origin at the upper left and the Y axis increasing
* downward.) If the CGContext is in the Quartz coordinate space (with
* the origin at the bottom left), then it should be flipped before
* this function is called:
*
* <informalexample><programlisting>
* CGContextTranslateCTM (cgContext, 0.0, height);
* CGContextScaleCTM (cgContext, 1.0, -1.0);
* </programlisting></informalexample>
*
* All Cairo operations are implemented in terms of Quartz operations,
* as long as Quartz-compatible elements are used (such as Quartz fonts).
* A very small number of Cairo operations cannot be translated to
* Quartz operations; those operations will fail on this surface.
* If all Cairo operations are required to succeed, consider rendering
* to a surface created by cairo_quartz_surface_create() and then copying
* the result to the CGContext.
*
* Return value: the newly created Cairo surface.
*

View File

@ -40,7 +40,7 @@
#if CAIRO_HAS_QUARTZ_SURFACE
#include <ApplicationServices/ApplicationServices.h>
#include <Carbon/Carbon.h>
CAIRO_BEGIN_DECLS
@ -57,26 +57,10 @@ cairo_quartz_surface_create_for_cg_context (CGContextRef cgContext,
cairo_public CGContextRef
cairo_quartz_surface_get_cg_context (cairo_surface_t *surface);
/*
* Quartz font support
*/
#ifdef CAIRO_HAS_QUARTZ_FONT
cairo_public cairo_font_face_t *
cairo_quartz_font_face_create_for_cgfont (CGFontRef font);
cairo_public cairo_font_face_t *
cairo_quartz_font_face_create_for_atsu_font_id (ATSUFontID font_id);
#endif /* CAIRO_HAS_QUARTZ_FONT */
CAIRO_END_DECLS
#else
#else /* CAIRO_HAS_QUARTZ_SURFACE */
# error Cairo was not compiled with support for the quartz backend
#endif /* CAIRO_HAS_QUARTZ_SURFACE */
#endif /* CAIRO_QUARTZ_H */

View File

@ -108,7 +108,7 @@ _cairo_rectangle_intersect (cairo_rectangle_int_t *dest, cairo_rectangle_int_t *
cairo_bool_t
_cairo_box_intersects_line_segment (cairo_box_t *box, cairo_line_t *line)
{
cairo_fixed_t t1=0, t2=0, t3=0, t4=0;
cairo_fixed_t t1, t2, t3, t4;
cairo_int64_t t1y, t2y, t3x, t4x;
cairo_fixed_t xlen, ylen;

View File

@ -339,7 +339,6 @@ _cairo_sub_font_map_glyph (cairo_sub_font_t *sub_font,
scaled_font_glyph_index,
CAIRO_SCALED_GLYPH_INFO_METRICS,
&scaled_glyph);
assert (status != CAIRO_INT_STATUS_UNSUPPORTED);
if (status)
return status;
@ -545,21 +544,11 @@ _cairo_scaled_font_subsets_map_glyph (cairo_scaled_font_subsets_t *subsets,
}
/* Glyph not found. Determine whether the glyph is outline or
* bitmap and add to the appropriate subset.
*
* glyph_index 0 (the .notdef glyph) is a special case. Some fonts
* will return CAIRO_INT_STATUS_UNSUPPORTED when doing a
* _scaled_glyph_lookup(_GLYPH_INFO_PATH). Type1-fallback creates
* empty glyphs in this case so we can put the glyph in a unscaled
* subset. */
if (scaled_font_glyph_index == 0) {
status = CAIRO_STATUS_SUCCESS;
} else {
status = _cairo_scaled_glyph_lookup (scaled_font,
scaled_font_glyph_index,
CAIRO_SCALED_GLYPH_INFO_PATH,
&scaled_glyph);
}
* bitmap and add to the appropriate subset */
status = _cairo_scaled_glyph_lookup (scaled_font,
scaled_font_glyph_index,
CAIRO_SCALED_GLYPH_INFO_PATH,
&scaled_glyph);
if (status && status != CAIRO_INT_STATUS_UNSUPPORTED)
return status;

View File

@ -1151,9 +1151,9 @@ _cairo_surface_fallback_fill_rectangles (cairo_surface_t *surface,
if (rects[i].y < y1)
y1 = rects[i].y;
if ((int)(rects[i].x + rects[i].width) > x2)
if (rects[i].x + rects[i].width > x2)
x2 = rects[i].x + rects[i].width;
if ((int)(rects[i].y + rects[i].height) > y2)
if (rects[i].y + rects[i].height > y2)
y2 = rects[i].y + rects[i].height;
}

View File

@ -887,9 +887,6 @@ slim_hidden_def (cairo_surface_get_device_offset);
* there is currently no way to have more than one fallback resolution
* in effect on a single page.
*
* The default fallback resoultion is 300 pixels per inch in both
* dimensions.
*
* Since: 1.2
**/
void
@ -1988,12 +1985,6 @@ _cairo_surface_set_empty_clip_path (cairo_surface_t *surface,
return _cairo_surface_set_error (surface, status);
}
cairo_clip_t *
_cairo_surface_get_clip (cairo_surface_t *surface)
{
return surface->clip;
}
cairo_status_t
_cairo_surface_set_clip (cairo_surface_t *surface, cairo_clip_t *clip)
{
@ -2496,24 +2487,6 @@ _cairo_surface_create_in_error (cairo_status_t status)
return (cairo_surface_t *) &_cairo_surface_nil_temp_file_error;
case CAIRO_STATUS_INVALID_STRIDE:
return (cairo_surface_t *) &_cairo_surface_nil_invalid_stride;
case CAIRO_STATUS_SUCCESS:
ASSERT_NOT_REACHED;
/* fall-through */
case CAIRO_STATUS_INVALID_RESTORE:
case CAIRO_STATUS_INVALID_POP_GROUP:
case CAIRO_STATUS_NO_CURRENT_POINT:
case CAIRO_STATUS_INVALID_MATRIX:
case CAIRO_STATUS_INVALID_STATUS:
case CAIRO_STATUS_NULL_POINTER:
case CAIRO_STATUS_INVALID_STRING:
case CAIRO_STATUS_INVALID_PATH_DATA:
case CAIRO_STATUS_SURFACE_FINISHED:
case CAIRO_STATUS_SURFACE_TYPE_MISMATCH:
case CAIRO_STATUS_PATTERN_TYPE_MISMATCH:
case CAIRO_STATUS_INVALID_DASH:
case CAIRO_STATUS_INVALID_DSC_COMMENT:
case CAIRO_STATUS_INVALID_INDEX:
case CAIRO_STATUS_CLIP_NOT_REPRESENTABLE:
default:
_cairo_error_throw (CAIRO_STATUS_NO_MEMORY);
return (cairo_surface_t *) &_cairo_surface_nil;

View File

@ -233,15 +233,10 @@ _extract_svg_surface (cairo_surface_t *surface,
{
cairo_surface_t *target;
if (surface->status)
return surface->status;
if (! _cairo_surface_is_paginated (surface))
return _cairo_error (CAIRO_STATUS_SURFACE_TYPE_MISMATCH);
target = _cairo_paginated_surface_get_target (surface);
if (target->status)
return target->status;
if (! _cairo_surface_is_svg (target))
return _cairo_error (CAIRO_STATUS_SURFACE_TYPE_MISMATCH);
@ -491,21 +486,15 @@ _cairo_svg_surface_show_page (void *abstract_surface)
static void
_cairo_svg_surface_emit_transform (cairo_output_stream_t *output,
char const *attribute_str,
const cairo_matrix_t *object_matrix,
const cairo_matrix_t *parent_matrix)
cairo_matrix_t *matrix)
{
cairo_matrix_t matrix = *object_matrix;
if (parent_matrix != NULL)
cairo_matrix_multiply (&matrix, &matrix, parent_matrix);
if (!_cairo_matrix_is_identity (&matrix))
if (!_cairo_matrix_is_identity (matrix))
_cairo_output_stream_printf (output,
"%s=\"matrix(%f,%f,%f,%f,%f,%f)\"",
attribute_str,
matrix.xx, matrix.yx,
matrix.xy, matrix.yy,
matrix.x0, matrix.y0);
matrix->xx, matrix->yx,
matrix->xy, matrix->yy,
matrix->x0, matrix->y0);
}
typedef struct
@ -665,8 +654,7 @@ _cairo_svg_document_emit_bitmap_glyph_data (cairo_svg_document_t *document,
}
_cairo_output_stream_printf (document->xml_node_glyphs, "<g");
_cairo_svg_surface_emit_transform (document->xml_node_glyphs, " transform",
&image->base.device_transform_inverse, NULL);
_cairo_svg_surface_emit_transform (document->xml_node_glyphs, " transform", &image->base.device_transform_inverse);
_cairo_output_stream_printf (document->xml_node_glyphs, ">/n");
for (y = 0, row = image->data, rows = image->height; rows; row += image->stride, rows--, y++) {
@ -961,8 +949,7 @@ static cairo_status_t
_cairo_svg_surface_emit_composite_image_pattern (cairo_output_stream_t *output,
cairo_svg_surface_t *svg_surface,
cairo_surface_pattern_t *pattern,
int pattern_id,
const cairo_matrix_t *parent_matrix,
int pattern_id,
const char *extra_attributes)
{
cairo_surface_t *surface;
@ -980,7 +967,7 @@ _cairo_svg_surface_emit_composite_image_pattern (cairo_output_stream_t *output
status = _cairo_surface_get_extents (surface, &extents);
if (status)
goto FAIL;
return status;
p2u = pattern->base.matrix;
status = cairo_matrix_invert (&p2u);
@ -994,7 +981,7 @@ _cairo_svg_surface_emit_composite_image_pattern (cairo_output_stream_t *output
"width=\"%d\" height=\"%d\"",
pattern_id,
extents.width, extents.height);
_cairo_svg_surface_emit_transform (output, " patternTransform", &p2u, parent_matrix);
_cairo_svg_surface_emit_transform (output, " patternTransform", &p2u);
_cairo_output_stream_printf (output, ">\n");
}
@ -1003,7 +990,7 @@ _cairo_svg_surface_emit_composite_image_pattern (cairo_output_stream_t *output
extents.width, extents.height);
if (pattern_id == invalid_pattern_id)
_cairo_svg_surface_emit_transform (output, " transform", &p2u, parent_matrix);
_cairo_svg_surface_emit_transform (output, " transform", &p2u);
if (extra_attributes)
_cairo_output_stream_printf (output, " %s", extra_attributes);
@ -1017,7 +1004,6 @@ _cairo_svg_surface_emit_composite_image_pattern (cairo_output_stream_t *output
if (pattern_id != invalid_pattern_id)
_cairo_output_stream_printf (output, "</pattern>\n");
FAIL:
_cairo_pattern_release_surface ((cairo_pattern_t *)pattern,
surface, &surface_attr);
@ -1158,7 +1144,6 @@ _cairo_svg_surface_emit_composite_meta_pattern (cairo_output_stream_t *output,
cairo_svg_surface_t *surface,
cairo_surface_pattern_t *pattern,
int pattern_id,
const cairo_matrix_t *parent_matrix,
const char *extra_attributes)
{
cairo_svg_document_t *document = surface->document;
@ -1186,7 +1171,7 @@ _cairo_svg_surface_emit_composite_meta_pattern (cairo_output_stream_t *output,
pattern_id,
meta_surface->width_pixels,
meta_surface->height_pixels);
_cairo_svg_surface_emit_transform (output, " patternTransform", &p2u, parent_matrix);
_cairo_svg_surface_emit_transform (output, " patternTransform", &p2u);
_cairo_output_stream_printf (output, ">\n");
}
@ -1195,7 +1180,7 @@ _cairo_svg_surface_emit_composite_meta_pattern (cairo_output_stream_t *output,
id);
if (pattern_id == invalid_pattern_id)
_cairo_svg_surface_emit_transform (output, " transform", &p2u, parent_matrix);
_cairo_svg_surface_emit_transform (output, " transform", &p2u);
if (extra_attributes)
_cairo_output_stream_printf (output, " %s", extra_attributes);
@ -1213,17 +1198,16 @@ _cairo_svg_surface_emit_composite_pattern (cairo_output_stream_t *output,
cairo_svg_surface_t *surface,
cairo_surface_pattern_t *pattern,
int pattern_id,
const cairo_matrix_t *parent_matrix,
const char *extra_attributes)
{
if (_cairo_surface_is_meta (pattern->surface)) {
return _cairo_svg_surface_emit_composite_meta_pattern (output, surface, pattern,
pattern_id, parent_matrix, extra_attributes);
pattern_id, extra_attributes);
}
return _cairo_svg_surface_emit_composite_image_pattern (output, surface, pattern,
pattern_id, parent_matrix, extra_attributes);
pattern_id, extra_attributes);
}
static void
@ -1269,8 +1253,7 @@ static cairo_status_t
_cairo_svg_surface_emit_surface_pattern (cairo_svg_surface_t *surface,
cairo_surface_pattern_t *pattern,
cairo_output_stream_t *style,
cairo_bool_t is_stroke,
const cairo_matrix_t *parent_matrix)
cairo_bool_t is_stroke)
{
cairo_svg_document_t *document = surface->document;
cairo_status_t status;
@ -1279,13 +1262,13 @@ _cairo_svg_surface_emit_surface_pattern (cairo_svg_surface_t *surface,
pattern_id = document->pattern_id++;
status = _cairo_svg_surface_emit_composite_pattern (document->xml_node_defs,
surface, pattern,
pattern_id, parent_matrix, NULL);
pattern_id, NULL);
if (status)
return status;
_cairo_output_stream_printf (style,
"%s: url(#pattern%d);",
is_stroke ? "stroke" : "fill",
is_stroke ? "color" : "fill",
pattern_id);
return CAIRO_STATUS_SUCCESS;
@ -1311,7 +1294,7 @@ _cairo_svg_surface_emit_pattern_stops (cairo_output_stream_t *output,
"<stop offset=\"%f\" style=\""
"stop-color: rgb(%f%%,%f%%,%f%%); "
"stop-opacity: %f;\"/>\n",
pattern->stops[0].offset,
_cairo_fixed_to_double (pattern->stops[0].x),
pattern->stops[0].color.red * 100.0,
pattern->stops[0].color.green * 100.0,
pattern->stops[0].color.blue * 100.0,
@ -1328,20 +1311,22 @@ _cairo_svg_surface_emit_pattern_stops (cairo_output_stream_t *output,
for (i = 0; i < pattern->n_stops; i++) {
if (reverse_stops) {
stops[i] = pattern->stops[pattern->n_stops - i - 1];
stops[i].offset = 1.0 - stops[i].offset;
stops[i].x = _cairo_fixed_from_double (1.0 - _cairo_fixed_to_double (stops[i].x));
} else
stops[i] = pattern->stops[i];
if (emulate_reflect) {
stops[i].offset /= 2;
stops[i].x /= 2;
if (i > 0 && i < (pattern->n_stops - 1)) {
if (reverse_stops) {
stops[i + pattern->n_stops - 1] = pattern->stops[i];
stops[i + pattern->n_stops - 1].offset =
0.5 + 0.5 * stops[i + pattern->n_stops - 1].offset;
stops[i + pattern->n_stops - 1].x =
_cairo_fixed_from_double (0.5 + 0.5
* _cairo_fixed_to_double (stops[i + pattern->n_stops - 1].x));
} else {
stops[i + pattern->n_stops - 1] = pattern->stops[pattern->n_stops - i - 1];
stops[i + pattern->n_stops - 1].offset =
1 - 0.5 * stops[i + pattern->n_stops - 1].offset;
stops[i + pattern->n_stops - 1].x =
_cairo_fixed_from_double (1 - 0.5
* _cairo_fixed_to_double (stops [i + pattern->n_stops - 1].x));
}
}
}
@ -1353,7 +1338,8 @@ _cairo_svg_surface_emit_pattern_stops (cairo_output_stream_t *output,
if (start_offset >= 0.0)
for (i = 0; i < n_stops; i++) {
offset = start_offset + (1 - start_offset ) * stops[i].offset;
offset = start_offset + (1 - start_offset ) *
_cairo_fixed_to_double (stops[i].x);
_cairo_output_stream_printf (output,
"<stop offset=\"%f\" style=\""
"stop-color: rgb(%f%%,%f%%,%f%%); "
@ -1370,14 +1356,14 @@ _cairo_svg_surface_emit_pattern_stops (cairo_output_stream_t *output,
cairo_color_t offset_color_start, offset_color_stop;
for (i = 0; i < n_stops; i++) {
if (stops[i].offset >= -start_offset) {
if (_cairo_fixed_to_double (stops[i].x) >= -start_offset) {
if (i > 0) {
if (stops[i].offset != stops[i-1].offset) {
if (stops[i].x != stops[i-1].x) {
double x0, x1;
cairo_color_t *color0, *color1;
x0 = stops[i-1].offset;
x1 = stops[i].offset;
x0 = _cairo_fixed_to_double (stops[i-1].x);
x1 = _cairo_fixed_to_double (stops[i].x);
color0 = &stops[i-1].color;
color1 = &stops[i].color;
offset_color_start.red = color0->red + (color1->red - color0->red)
@ -1419,7 +1405,7 @@ _cairo_svg_surface_emit_pattern_stops (cairo_output_stream_t *output,
"<stop offset=\"%f\" style=\""
"stop-color: rgb(%f%%,%f%%,%f%%); "
"stop-opacity: %f;\"/>\n",
stops[i].offset + start_offset,
_cairo_fixed_to_double (stops[i].x) + start_offset,
stops[i].color.red * 100.0,
stops[i].color.green * 100.0,
stops[i].color.blue * 100.0,
@ -1430,7 +1416,7 @@ _cairo_svg_surface_emit_pattern_stops (cairo_output_stream_t *output,
"<stop offset=\"%f\" style=\""
"stop-color: rgb(%f%%,%f%%,%f%%); "
"stop-opacity: %f;\"/>\n",
1.0 + stops[i].offset + start_offset,
1.0 + _cairo_fixed_to_double (stops[i].x) + start_offset,
stops[i].color.red * 100.0,
stops[i].color.green * 100.0,
stops[i].color.blue * 100.0,
@ -1475,8 +1461,7 @@ static cairo_status_t
_cairo_svg_surface_emit_linear_pattern (cairo_svg_surface_t *surface,
cairo_linear_pattern_t *pattern,
cairo_output_stream_t *style,
cairo_bool_t is_stroke,
const cairo_matrix_t *parent_matrix)
cairo_bool_t is_stroke)
{
cairo_svg_document_t *document = surface->document;
double x0, y0, x1, y1;
@ -1501,7 +1486,7 @@ _cairo_svg_surface_emit_linear_pattern (cairo_svg_surface_t *surface,
x0, y0, x1, y1);
_cairo_svg_surface_emit_pattern_extend (document->xml_node_defs, &pattern->base.base),
_cairo_svg_surface_emit_transform (document->xml_node_defs, "gradientTransform", &p2u, parent_matrix);
_cairo_svg_surface_emit_transform (document->xml_node_defs, "gradientTransform", &p2u);
_cairo_output_stream_printf (document->xml_node_defs, ">\n");
status = _cairo_svg_surface_emit_pattern_stops (document->xml_node_defs,
@ -1515,7 +1500,7 @@ _cairo_svg_surface_emit_linear_pattern (cairo_svg_surface_t *surface,
_cairo_output_stream_printf (style,
"%s: url(#linear%d);",
is_stroke ? "stroke" : "fill",
is_stroke ? "color" : "fill",
document->linear_pattern_id);
document->linear_pattern_id++;
@ -1527,8 +1512,7 @@ static cairo_status_t
_cairo_svg_surface_emit_radial_pattern (cairo_svg_surface_t *surface,
cairo_radial_pattern_t *pattern,
cairo_output_stream_t *style,
cairo_bool_t is_stroke,
const cairo_matrix_t *parent_matrix)
cairo_bool_t is_stroke)
{
cairo_svg_document_t *document = surface->document;
cairo_matrix_t p2u;
@ -1579,7 +1563,7 @@ _cairo_svg_surface_emit_radial_pattern (cairo_svg_surface_t *surface,
document->radial_pattern_id,
x1, y1,
x1, y1, r1);
_cairo_svg_surface_emit_transform (document->xml_node_defs, "gradientTransform", &p2u, parent_matrix);
_cairo_svg_surface_emit_transform (document->xml_node_defs, "gradientTransform", &p2u);
_cairo_output_stream_printf (document->xml_node_defs, ">\n");
if (extend == CAIRO_EXTEND_NONE || n_stops < 1)
@ -1663,7 +1647,7 @@ _cairo_svg_surface_emit_radial_pattern (cairo_svg_surface_t *surface,
_cairo_output_stream_printf (document->xml_node_defs, "spreadMethod=\"repeat\" ");
else
_cairo_svg_surface_emit_pattern_extend (document->xml_node_defs, &pattern->base.base);
_cairo_svg_surface_emit_transform (document->xml_node_defs, "gradientTransform", &p2u, parent_matrix);
_cairo_svg_surface_emit_transform (document->xml_node_defs, "gradientTransform", &p2u);
_cairo_output_stream_printf (document->xml_node_defs, ">\n");
/* To support cairo's EXTEND_NONE, (for which SVG has no similar
@ -1700,7 +1684,7 @@ _cairo_svg_surface_emit_radial_pattern (cairo_svg_surface_t *surface,
_cairo_output_stream_printf (style,
"%s: url(#radial%d);",
is_stroke ? "stroke" : "fill",
is_stroke ? "color" : "fill",
document->radial_pattern_id);
document->radial_pattern_id++;
@ -1712,25 +1696,20 @@ static cairo_status_t
_cairo_svg_surface_emit_pattern (cairo_svg_surface_t *surface,
cairo_pattern_t *pattern,
cairo_output_stream_t *output,
cairo_bool_t is_stroke,
const cairo_matrix_t *parent_matrix)
cairo_bool_t is_stroke)
{
switch (pattern->type) {
case CAIRO_PATTERN_TYPE_SOLID:
return _cairo_svg_surface_emit_solid_pattern (surface, (cairo_solid_pattern_t *) pattern,
output, is_stroke);
return _cairo_svg_surface_emit_solid_pattern (surface, (cairo_solid_pattern_t *) pattern, output, is_stroke);
case CAIRO_PATTERN_TYPE_SURFACE:
return _cairo_svg_surface_emit_surface_pattern (surface, (cairo_surface_pattern_t *) pattern,
output, is_stroke, parent_matrix);
return _cairo_svg_surface_emit_surface_pattern (surface, (cairo_surface_pattern_t *) pattern, output, is_stroke);
case CAIRO_PATTERN_TYPE_LINEAR:
return _cairo_svg_surface_emit_linear_pattern (surface, (cairo_linear_pattern_t *) pattern,
output, is_stroke, parent_matrix);
return _cairo_svg_surface_emit_linear_pattern (surface, (cairo_linear_pattern_t *) pattern, output, is_stroke);
case CAIRO_PATTERN_TYPE_RADIAL:
return _cairo_svg_surface_emit_radial_pattern (surface, (cairo_radial_pattern_t *) pattern,
output, is_stroke, parent_matrix);
return _cairo_svg_surface_emit_radial_pattern (surface, (cairo_radial_pattern_t *) pattern, output, is_stroke);
}
return _cairo_error (CAIRO_STATUS_PATTERN_TYPE_MISMATCH);
}
@ -1740,15 +1719,14 @@ _cairo_svg_surface_emit_fill_style (cairo_output_stream_t *output,
cairo_svg_surface_t *surface,
cairo_operator_t op,
cairo_pattern_t *source,
cairo_fill_rule_t fill_rule,
cairo_matrix_t *parent_matrix)
cairo_fill_rule_t fill_rule)
{
_cairo_output_stream_printf (output,
"fill-rule: %s; ",
fill_rule == CAIRO_FILL_RULE_EVEN_ODD ?
"evenodd" : "nonzero");
_cairo_svg_surface_emit_operator (output, surface, op);
return _cairo_svg_surface_emit_pattern (surface, source, output, FALSE, parent_matrix);
return _cairo_svg_surface_emit_pattern (surface, source, output, FALSE);
}
static cairo_status_t
@ -1756,8 +1734,7 @@ _cairo_svg_surface_emit_stroke_style (cairo_output_stream_t *output,
cairo_svg_surface_t *surface,
cairo_operator_t op,
cairo_pattern_t *source,
cairo_stroke_style_t *stroke_style,
cairo_matrix_t *parent_matrix)
cairo_stroke_style_t *stroke_style)
{
cairo_status_t status;
const char *line_cap, *line_join;
@ -1799,7 +1776,7 @@ _cairo_svg_surface_emit_stroke_style (cairo_output_stream_t *output,
line_cap,
line_join);
status = _cairo_svg_surface_emit_pattern (surface, source, output, TRUE, parent_matrix);
status = _cairo_svg_surface_emit_pattern (surface, source, output, TRUE);
if (status)
return status;
@ -1849,13 +1826,11 @@ _cairo_svg_surface_fill_stroke (void *abstract_surface,
cairo_status_t status;
_cairo_output_stream_printf (surface->xml_node, "<path style=\"");
status = _cairo_svg_surface_emit_fill_style (surface->xml_node, surface, fill_op,
fill_source, fill_rule, stroke_ctm_inverse);
status = _cairo_svg_surface_emit_fill_style (surface->xml_node, surface, fill_op, fill_source, fill_rule);
if (status)
return status;
status = _cairo_svg_surface_emit_stroke_style (surface->xml_node, surface, stroke_op,
stroke_source, stroke_style, stroke_ctm_inverse);
status = _cairo_svg_surface_emit_stroke_style (surface->xml_node, surface, stroke_op, stroke_source, stroke_style);
if (status)
return status;
@ -1865,7 +1840,7 @@ _cairo_svg_surface_fill_stroke (void *abstract_surface,
if (status)
return status;
_cairo_svg_surface_emit_transform (surface->xml_node, " transform", stroke_ctm, NULL);
_cairo_svg_surface_emit_transform (surface->xml_node, " transform", stroke_ctm);
_cairo_output_stream_printf (surface->xml_node, "/>\n");
return CAIRO_STATUS_SUCCESS;
@ -1889,7 +1864,7 @@ _cairo_svg_surface_fill (void *abstract_surface,
assert (_cairo_svg_surface_operation_supported (surface, op, source));
_cairo_output_stream_printf (surface->xml_node, "<path style=\" stroke:none;");
status = _cairo_svg_surface_emit_fill_style (surface->xml_node, surface, op, source, fill_rule, NULL);
status = _cairo_svg_surface_emit_fill_style (surface->xml_node, surface, op, source, fill_rule);
if (status)
return status;
@ -1938,7 +1913,6 @@ _cairo_svg_surface_emit_paint (cairo_output_stream_t *output,
surface,
(cairo_surface_pattern_t *) source,
invalid_pattern_id,
NULL,
extra_attributes);
_cairo_output_stream_printf (output,
@ -1947,7 +1921,7 @@ _cairo_svg_surface_emit_paint (cairo_output_stream_t *output,
"style=\"",
surface->width, surface->height);
_cairo_svg_surface_emit_operator (output, surface, op);
status = _cairo_svg_surface_emit_pattern (surface, source, output, FALSE, NULL);
status = _cairo_svg_surface_emit_pattern (surface, source, output, FALSE);
if (status)
return status;
@ -2112,18 +2086,14 @@ _cairo_svg_surface_stroke (void *abstract_dst,
assert (_cairo_svg_surface_operation_supported (surface, op, source));
_cairo_output_stream_printf (surface->xml_node, "<path style=\"fill: none; ");
status = _cairo_svg_surface_emit_stroke_style (surface->xml_node, surface, op,
source, stroke_style, ctm_inverse);
if (status)
return status;
status = _cairo_svg_surface_emit_stroke_style (surface->xml_node, surface, op, source, stroke_style);
_cairo_output_stream_printf (surface->xml_node, "\" ");
status = _cairo_svg_surface_emit_path (surface->xml_node, path, ctm_inverse);
if (status)
return status;
_cairo_svg_surface_emit_transform (surface->xml_node, " transform", ctm, NULL);
_cairo_svg_surface_emit_transform (surface->xml_node, " transform", ctm);
_cairo_output_stream_printf (surface->xml_node, "/>\n");
return CAIRO_STATUS_SUCCESS;
@ -2160,7 +2130,7 @@ _cairo_svg_surface_show_glyphs (void *abstract_surface,
_cairo_output_stream_printf (surface->xml_node, "<g style=\"");
status = _cairo_svg_surface_emit_pattern (surface, pattern,
surface->xml_node, FALSE, NULL);
surface->xml_node, FALSE);
if (status)
return status;

View File

@ -34,12 +34,6 @@
* Adrian Johnson <ajohnson@redneon.com>
*/
/*
* Useful links:
* http://developer.apple.com/textfonts/TTRefMan/RM06/Chap6.html
* http://www.microsoft.com/typography/specs/default.htm
*/
#define _BSD_SOURCE /* for snprintf(), strdup() */
#include "cairoint.h"
@ -91,10 +85,8 @@ struct _cairo_truetype_font {
};
static cairo_status_t
cairo_truetype_font_use_glyph (cairo_truetype_font_t *font,
unsigned short glyph,
unsigned short *out);
static int
cairo_truetype_font_use_glyph (cairo_truetype_font_t *font, int glyph);
#define SFNT_VERSION 0x00010000
#define SFNT_STRING_MAX_LENGTH 65535
@ -499,10 +491,9 @@ cairo_truetype_font_write_generic_table (cairo_truetype_font_t *font,
return CAIRO_STATUS_SUCCESS;
}
static cairo_status_t
cairo_truetype_font_remap_composite_glyph (cairo_truetype_font_t *font,
unsigned char *buffer,
unsigned long size)
static void
cairo_truetype_font_remap_composite_glyph (cairo_truetype_font_t *font,
unsigned char *buffer)
{
tt_glyph_data_t *glyph_data;
tt_composite_glyph_t *composite_glyph;
@ -510,30 +501,19 @@ cairo_truetype_font_remap_composite_glyph (cairo_truetype_font_t *font,
int has_more_components;
unsigned short flags;
unsigned short index;
cairo_status_t status;
unsigned char *end = buffer + size;
if (font->status)
return font->status;
return;
glyph_data = (tt_glyph_data_t *) buffer;
if ((unsigned char *)(&glyph_data->data) >= end)
return CAIRO_INT_STATUS_UNSUPPORTED;
if ((int16_t)be16_to_cpu (glyph_data->num_contours) >= 0)
return CAIRO_STATUS_SUCCESS;
return;
composite_glyph = &glyph_data->glyph;
do {
if ((unsigned char *)(&composite_glyph->args[1]) >= end)
return CAIRO_INT_STATUS_UNSUPPORTED;
flags = be16_to_cpu (composite_glyph->flags);
flags = be16_to_cpu (composite_glyph->flags);
has_more_components = flags & TT_MORE_COMPONENTS;
status = cairo_truetype_font_use_glyph (font, be16_to_cpu (composite_glyph->index), &index);
if (status)
return status;
index = cairo_truetype_font_use_glyph (font, be16_to_cpu (composite_glyph->index));
composite_glyph->index = cpu_to_be16 (index);
num_args = 1;
if (flags & TT_ARG_1_AND_2_ARE_WORDS)
@ -546,8 +526,6 @@ cairo_truetype_font_remap_composite_glyph (cairo_truetype_font_t *font,
num_args += 3;
composite_glyph = (tt_composite_glyph_t *) &(composite_glyph->args[num_args]);
} while (has_more_components);
return CAIRO_STATUS_SUCCESS;
}
static cairo_status_t
@ -602,12 +580,6 @@ cairo_truetype_font_write_glyf_table (cairo_truetype_font_t *font,
end = be32_to_cpu (u.long_offsets[index + 1]);
}
/* quick sanity check... */
if (end < begin) {
status = CAIRO_INT_STATUS_UNSUPPORTED;
goto FAIL;
}
size = end - begin;
status = cairo_truetype_font_align_output (font, &next);
if (status)
@ -629,9 +601,7 @@ cairo_truetype_font_write_glyf_table (cairo_truetype_font_t *font,
if (status)
goto FAIL;
status = cairo_truetype_font_remap_composite_glyph (font, buffer, size);
if (status)
goto FAIL;
cairo_truetype_font_remap_composite_glyph (font, buffer);
}
}
@ -962,22 +932,16 @@ cairo_truetype_font_generate (cairo_truetype_font_t *font,
return _cairo_truetype_font_set_error (font, status);
}
static cairo_status_t
cairo_truetype_font_use_glyph (cairo_truetype_font_t *font,
unsigned short glyph,
unsigned short *out)
static int
cairo_truetype_font_use_glyph (cairo_truetype_font_t *font, int glyph)
{
if (glyph >= font->num_glyphs_in_face)
return CAIRO_INT_STATUS_UNSUPPORTED;
if (font->parent_to_subset[glyph] == 0) {
font->parent_to_subset[glyph] = font->base.num_glyphs;
font->glyphs[font->base.num_glyphs].parent_index = glyph;
font->base.num_glyphs++;
}
*out = font->parent_to_subset[glyph];
return CAIRO_STATUS_SUCCESS;
return font->parent_to_subset[glyph];
}
static void
@ -1073,7 +1037,7 @@ _cairo_truetype_subset_init (cairo_truetype_subset_t *truetype_subset,
cairo_status_t status;
const char *data = NULL; /* squelch bogus compiler warning */
unsigned long length = 0; /* squelch bogus compiler warning */
unsigned long offsets_length;
unsigned long parent_glyph, offsets_length;
unsigned int i;
const unsigned long *string_offsets = NULL;
unsigned long num_strings = 0;
@ -1083,10 +1047,8 @@ _cairo_truetype_subset_init (cairo_truetype_subset_t *truetype_subset,
return status;
for (i = 0; i < font->scaled_font_subset->num_glyphs; i++) {
unsigned short parent_glyph = font->scaled_font_subset->glyphs[i];
status = cairo_truetype_font_use_glyph (font, parent_glyph, &parent_glyph);
if (status)
goto fail1;
parent_glyph = font->scaled_font_subset->glyphs[i];
cairo_truetype_font_use_glyph (font, parent_glyph);
}
cairo_truetype_font_create_truetype_table_list (font);

View File

@ -331,6 +331,33 @@ charstring_encrypt (cairo_array_t *data)
}
}
static cairo_int_status_t
create_notdef_charstring (cairo_array_t *data, cairo_charstring_type_t type)
{
cairo_status_t status;
/* We're passing constants below, so we know the 0 values will
* only use 1 byte each, and the 500 values will use 2 bytes
* each. Then 2 more for each of the commands is 10 total. */
status = _cairo_array_grow_by (data, 10);
if (status)
return status;
if (type == CAIRO_CHARSTRING_TYPE1) {
charstring_encode_integer (data, 0, type);
charstring_encode_integer (data, 0, type);
/* The width is arbitrary. */
charstring_encode_integer (data, 500, type);
charstring_encode_integer (data, 0, type);
charstring_encode_command (data, CHARSTRING_sbw);
}
charstring_encode_command (data, CHARSTRING_endchar);
return CAIRO_STATUS_SUCCESS;
}
static cairo_int_status_t
cairo_type1_font_create_charstring (cairo_type1_font_t *font,
int subset_index,
@ -342,7 +369,6 @@ cairo_type1_font_create_charstring (cairo_type1_font_t *font,
cairo_scaled_glyph_t *scaled_glyph;
t1_path_info_t path_info;
cairo_text_extents_t *metrics;
cairo_bool_t emit_path = TRUE;
/* This call may return CAIRO_INT_STATUS_UNSUPPORTED for bitmap fonts. */
status = _cairo_scaled_glyph_lookup (font->type1_scaled_font,
@ -350,16 +376,6 @@ cairo_type1_font_create_charstring (cairo_type1_font_t *font,
CAIRO_SCALED_GLYPH_INFO_METRICS|
CAIRO_SCALED_GLYPH_INFO_PATH,
&scaled_glyph);
/* It is ok for the .notdef glyph to not have a path available. We
* just need the metrics to emit an empty glyph. */
if (glyph_index == 0 && status == CAIRO_INT_STATUS_UNSUPPORTED) {
emit_path = FALSE;
status = _cairo_scaled_glyph_lookup (font->type1_scaled_font,
glyph_index,
CAIRO_SCALED_GLYPH_INFO_METRICS,
&scaled_glyph);
}
if (status)
return status;
@ -395,24 +411,22 @@ cairo_type1_font_create_charstring (cairo_type1_font_t *font,
path_info.current_x = (int) scaled_glyph->metrics.x_bearing;
path_info.current_y = (int) scaled_glyph->metrics.y_bearing;
} else {
charstring_encode_integer (data, (int) scaled_glyph->metrics.x_advance, type);
charstring_encode_integer (data, (int) scaled_glyph->metrics.width, type);
path_info.current_x = 0;
path_info.current_y = 0;
}
path_info.data = data;
path_info.type = type;
if (emit_path) {
status = _cairo_path_fixed_interpret (scaled_glyph->path,
CAIRO_DIRECTION_FORWARD,
_charstring_move_to,
_charstring_line_to,
_charstring_curve_to,
_charstring_close_path,
&path_info);
if (status)
return status;
}
status = _cairo_path_fixed_interpret (scaled_glyph->path,
CAIRO_DIRECTION_FORWARD,
_charstring_move_to,
_charstring_line_to,
_charstring_curve_to,
_charstring_close_path,
&path_info);
if (status)
return status;
status = _cairo_array_grow_by (data, 1);
if (status)
@ -441,7 +455,7 @@ cairo_type1_font_write_charstrings (cairo_type1_font_t *font,
"2 index /CharStrings %d dict dup begin\n",
font->scaled_font_subset->num_glyphs + 1);
for (i = 0; i < font->scaled_font_subset->num_glyphs; i++) {
for (i = 1; i < font->scaled_font_subset->num_glyphs; i++) {
_cairo_array_truncate (&data, 0);
/* four "random" bytes required by encryption algorithm */
status = _cairo_array_append_multiple (&data, zeros, 4);
@ -459,8 +473,6 @@ cairo_type1_font_write_charstrings (cairo_type1_font_t *font,
_cairo_output_stream_printf (encrypted_output, "/%s %d RD ",
font->scaled_font_subset->glyph_names[i],
length);
} else if (i == 0) {
_cairo_output_stream_printf (encrypted_output, "/.notdef %d RD ", length);
} else {
_cairo_output_stream_printf (encrypted_output, "/g%d %d RD ", i, length);
}
@ -470,6 +482,24 @@ cairo_type1_font_write_charstrings (cairo_type1_font_t *font,
_cairo_output_stream_printf (encrypted_output, " ND\n");
}
/* All type 1 fonts must have a /.notdef charstring */
_cairo_array_truncate (&data, 0);
/* four "random" bytes required by encryption algorithm */
status = _cairo_array_append_multiple (&data, zeros, 4);
if (status)
goto fail;
status = create_notdef_charstring (&data, CAIRO_CHARSTRING_TYPE1);
if (status)
goto fail;
charstring_encrypt (&data);
length = _cairo_array_num_elements (&data);
_cairo_output_stream_printf (encrypted_output, "/.notdef %d RD ", length);
_cairo_output_stream_write (encrypted_output,
_cairo_array_index (&data, 0),
length);
_cairo_output_stream_printf (encrypted_output, " ND\n");
fail:
_cairo_array_fini (&data);
return status;
@ -826,10 +856,14 @@ _cairo_type2_charstrings_init (cairo_type2_charstrings_t *type2_subset,
if (status)
goto fail2;
status = cairo_type1_font_create_charstring (font, i,
font->scaled_font_subset->glyphs[i],
CAIRO_CHARSTRING_TYPE2,
&charstring);
if (i == 0) {
status = create_notdef_charstring (&charstring, CAIRO_CHARSTRING_TYPE2);
} else {
status = cairo_type1_font_create_charstring (font, i,
font->scaled_font_subset->glyphs[i],
CAIRO_CHARSTRING_TYPE2,
&charstring);
}
if (status)
goto fail2;

View File

@ -33,11 +33,6 @@
* Kristian Høgsberg <krh@redhat.com>
*/
/*
* Useful links:
* http://partners.adobe.com/public/developer/en/font/T1_SPEC.PDF
*/
#define _BSD_SOURCE /* for snprintf(), strdup() */
#include "cairoint.h"
#include "cairo-type1-private.h"

View File

@ -1907,7 +1907,7 @@ cairo_font_face_t *
cairo_win32_font_face_create_for_hfont (HFONT font)
{
LOGFONTW logfont;
GetObjectW (font, sizeof(logfont), &logfont);
GetObject (font, sizeof(logfont), &logfont);
if (logfont.lfEscapement != 0 || logfont.lfOrientation != 0 ||
logfont.lfWidth != 0) {

View File

@ -757,7 +757,7 @@ _cairo_win32_printing_surface_paint_linear_pattern (cairo_win32_surface_t *surfa
}
stop = i%num_rects + 1;
vert[i*2+1].x = (LONG)(d*(range_start + i/num_rects + pattern->base.stops[stop].offset));
vert[i*2+1].x = (LONG)(d*(range_start + i/num_rects + _cairo_fixed_to_double (pattern->base.stops[stop].x)));
vert[i*2+1].y = (LONG) clip.bottom;
if (extend == CAIRO_EXTEND_REFLECT && (range_start+(i/num_rects))%2)
stop = num_rects - stop;
@ -1419,9 +1419,6 @@ _cairo_win32_printing_surface_start_page (void *abstract_surface)
{
cairo_win32_surface_t *surface = abstract_surface;
XFORM xform;
double x_res, y_res;
cairo_matrix_t inverse_ctm;
cairo_status_t status;
SaveDC (surface->dc); /* Save application context first, before doing MWT */
@ -1434,17 +1431,6 @@ _cairo_win32_printing_surface_start_page (void *abstract_surface)
surface->ctm.x0 = xform.eDx;
surface->ctm.y0 = xform.eDy;
surface->has_ctm = !_cairo_matrix_is_identity (&surface->ctm);
inverse_ctm = surface->ctm;
status = cairo_matrix_invert (&inverse_ctm);
if (status)
return status;
x_res = (double) GetDeviceCaps(surface->dc, LOGPIXELSX);
y_res = (double) GetDeviceCaps(surface->dc, LOGPIXELSY);
cairo_matrix_transform_distance (&inverse_ctm, &x_res, &y_res);
_cairo_surface_set_resolution (&surface->base, x_res, y_res);
if (!ModifyWorldTransform (surface->dc, NULL, MWT_IDENTITY))
return _cairo_win32_print_gdi_error ("_cairo_win32_printing_surface_start_page:ModifyWorldTransform");
@ -1482,6 +1468,7 @@ cairo_surface_t *
cairo_win32_printing_surface_create (HDC hdc)
{
cairo_win32_surface_t *surface;
int xr, yr;
RECT rect;
surface = malloc (sizeof (cairo_win32_surface_t));
@ -1517,6 +1504,10 @@ cairo_win32_printing_surface_create (HDC hdc)
_cairo_surface_init (&surface->base, &cairo_win32_printing_surface_backend,
CAIRO_CONTENT_COLOR_ALPHA);
xr = GetDeviceCaps(hdc, LOGPIXELSX);
yr = GetDeviceCaps(hdc, LOGPIXELSY);
_cairo_surface_set_resolution (&surface->base, (double) xr, (double) yr);
return _cairo_paginated_surface_create (&surface->base,
CAIRO_CONTENT_COLOR_ALPHA,
surface->extents.width,

View File

@ -410,15 +410,9 @@ _cairo_win32_surface_create_similar_internal (void *abstract_src,
saved_dc_bitmap = SelectObject (ddb_dc, ddb);
new_surf = (cairo_win32_surface_t*) cairo_win32_surface_create (ddb_dc);
if (new_surf->base.status == CAIRO_STATUS_SUCCESS) {
new_surf->bitmap = ddb;
new_surf->saved_dc_bitmap = saved_dc_bitmap;
new_surf->is_dib = FALSE;
} else {
SelectObject (ddb_dc, saved_dc_bitmap);
DeleteDC (ddb_dc);
DeleteObject (ddb);
}
new_surf->bitmap = ddb;
new_surf->saved_dc_bitmap = saved_dc_bitmap;
new_surf->is_dib = FALSE;
}
return (cairo_surface_t*) new_surf;

View File

@ -300,17 +300,6 @@ _cairo_xlib_display_get (Display *dpy)
* back up to 6.7 or 6.8. */
if (VendorRelease (dpy) >= 60700000 && VendorRelease (dpy) <= 60802000)
display->buggy_repeat = TRUE;
/* But even the new modular server has bugs, (bad enough to
* crash the X server), that it so happens we can avoid with
* the exact same buggy_repeat workaround. We've verified that
* this bug exists as least as late as version 1.3.0.0, (which
* is in Fedora 8), and is gone again in version 1.4.99.901
* (from a Fedora 9 Beta). Versions between those are still
* unknown, but until we learn more, we'll assume that any 1.3
* version is buggy. */
if (VendorRelease (dpy) < 10400000)
display->buggy_repeat = TRUE;
} else if (strstr (ServerVendor (dpy), "XFree86") != NULL) {
if (VendorRelease (dpy) <= 40500000)
display->buggy_repeat = TRUE;

View File

@ -70,12 +70,6 @@ struct _cairo_xlib_display {
unsigned int closed :1;
};
typedef struct _cairo_xlib_visual_info {
VisualID visualid;
XColor colors[256];
unsigned long rgb333_to_pseudocolor[512];
} cairo_xlib_visual_info_t;
struct _cairo_xlib_screen_info {
cairo_xlib_screen_info_t *next;
cairo_reference_count_t ref_count;
@ -88,8 +82,6 @@ struct _cairo_xlib_screen_info {
GC gc[9];
unsigned int gc_needs_clip_reset;
cairo_array_t visuals;
};
cairo_private cairo_xlib_display_t *
@ -133,18 +125,4 @@ _cairo_xlib_screen_get_gc (cairo_xlib_screen_info_t *info, int depth);
cairo_private cairo_status_t
_cairo_xlib_screen_put_gc (cairo_xlib_screen_info_t *info, int depth, GC gc, cairo_bool_t reset_clip);
cairo_private cairo_status_t
_cairo_xlib_screen_get_visual_info (cairo_xlib_screen_info_t *info,
Visual *visual,
cairo_xlib_visual_info_t **out);
cairo_private cairo_status_t
_cairo_xlib_visual_info_create (Display *dpy,
int screen,
VisualID visualid,
cairo_xlib_visual_info_t **out);
cairo_private void
_cairo_xlib_visual_info_destroy (Display *dpy, cairo_xlib_visual_info_t *info);
#endif /* CAIRO_XLIB_PRIVATE_H */

View File

@ -269,8 +269,6 @@ _cairo_xlib_screen_info_destroy (cairo_xlib_screen_info_t *info)
{
cairo_xlib_screen_info_t **prev;
cairo_xlib_screen_info_t *list;
cairo_xlib_visual_info_t **visuals;
int i;
assert (CAIRO_REFERENCE_COUNT_HAS_REFERENCE (&info->ref_count));
@ -284,17 +282,12 @@ _cairo_xlib_screen_info_destroy (cairo_xlib_screen_info_t *info)
break;
}
}
visuals = _cairo_array_index (&info->visuals, 0);
for (i = 0; i < _cairo_array_num_elements (&info->visuals); i++)
_cairo_xlib_visual_info_destroy (info->display->display, visuals[i]);
CAIRO_MUTEX_UNLOCK (info->display->mutex);
_cairo_xlib_screen_info_close_display (info);
_cairo_xlib_display_destroy (info->display);
_cairo_array_fini (&info->visuals);
free (info);
}
@ -342,9 +335,6 @@ _cairo_xlib_screen_info_get (Display *dpy, Screen *screen)
memset (info->gc, 0, sizeof (info->gc));
info->gc_needs_clip_reset = 0;
_cairo_array_init (&info->visuals,
sizeof (cairo_xlib_visual_info_t*));
if (screen) {
int event_base, error_base;
info->has_render = (XRenderQueryExtension (dpy, &event_base, &error_base) &&
@ -421,62 +411,3 @@ _cairo_xlib_screen_put_gc (cairo_xlib_screen_info_t *info, int depth, GC gc, cai
return status;
}
cairo_status_t
_cairo_xlib_screen_get_visual_info (cairo_xlib_screen_info_t *info,
Visual *visual,
cairo_xlib_visual_info_t **out)
{
cairo_xlib_visual_info_t **visuals, *ret = NULL;
cairo_status_t status;
int i, n_visuals;
CAIRO_MUTEX_LOCK (info->display->mutex);
visuals = _cairo_array_index (&info->visuals, 0);
n_visuals = _cairo_array_num_elements (&info->visuals);
for (i = 0; i < n_visuals; i++) {
if (visuals[i]->visualid == visual->visualid) {
ret = visuals[i];
break;
}
}
CAIRO_MUTEX_UNLOCK (info->display->mutex);
if (ret != NULL) {
*out = ret;
return CAIRO_STATUS_SUCCESS;
}
status = _cairo_xlib_visual_info_create (info->display->display,
XScreenNumberOfScreen (info->screen),
visual->visualid,
&ret);
if (status)
return status;
CAIRO_MUTEX_LOCK (info->display->mutex);
if (n_visuals != _cairo_array_num_elements (&info->visuals)) {
/* check that another thread has not added our visual */
int new_visuals = _cairo_array_num_elements (&info->visuals);
visuals = _cairo_array_index (&info->visuals, 0);
for (i = n_visuals; i < new_visuals; i++) {
if (visuals[i]->visualid == visual->visualid) {
_cairo_xlib_visual_info_destroy (info->display->display, ret);
ret = visuals[i];
break;
}
}
if (i == new_visuals)
status = _cairo_array_append (&info->visuals, &ret);
} else
status = _cairo_array_append (&info->visuals, &ret);
CAIRO_MUTEX_UNLOCK (info->display->mutex);
if (status) {
_cairo_xlib_visual_info_destroy (info->display->display, ret);
return status;
}
*out = ret;
return CAIRO_STATUS_SUCCESS;
}

View File

@ -91,11 +91,6 @@ struct _cairo_xlib_surface {
cairo_filter_t filter;
int repeat;
XTransform xtransform;
uint32_t a_mask;
uint32_t r_mask;
uint32_t g_mask;
uint32_t b_mask;
};
enum {

View File

@ -48,16 +48,6 @@
typedef int (*cairo_xlib_error_func_t) (Display *display,
XErrorEvent *event);
static cairo_surface_t *
_cairo_xlib_surface_create_internal (Display *dpy,
Drawable drawable,
Screen *screen,
Visual *visual,
XRenderPictFormat *xrender_format,
int width,
int height,
int depth);
static cairo_status_t
_cairo_xlib_surface_ensure_gc (cairo_xlib_surface_t *surface);
@ -81,6 +71,10 @@ _cairo_xlib_surface_show_glyphs (void *abstract_dst,
int num_glyphs,
cairo_scaled_font_t *scaled_font);
#if CAIRO_HAS_XLIB_XRENDER_SURFACE
slim_hidden_proto (cairo_xlib_surface_create_with_xrender_format);
#endif
/*
* Instead of taking two round trips for each blending request,
* assume that if a particular drawable fails GetImage that it will
@ -179,11 +173,9 @@ _cairo_xlib_surface_create_similar_with_format (void *abstract_src,
depth);
surface = (cairo_xlib_surface_t *)
_cairo_xlib_surface_create_internal (dpy, pix,
src->screen, src->visual,
xrender_format,
width, height,
depth);
cairo_xlib_surface_create_with_xrender_format (dpy, pix, src->screen,
xrender_format,
width, height);
if (surface->base.status) {
XFreePixmap (dpy, pix);
return &surface->base;
@ -259,11 +251,10 @@ _cairo_xlib_surface_create_similar (void *abstract_src,
xrender_format->depth);
surface = (cairo_xlib_surface_t *)
_cairo_xlib_surface_create_internal (src->dpy, pix,
src->screen, src->visual,
xrender_format,
width, height,
xrender_format->depth);
cairo_xlib_surface_create_with_xrender_format (src->dpy, pix,
src->screen,
xrender_format,
width, height);
if (surface->base.status != CAIRO_STATUS_SUCCESS) {
XFreePixmap (src->dpy, pix);
return &surface->base;
@ -464,70 +455,18 @@ _swap_ximage_to_native (XImage *ximage)
}
}
/* Given a mask, (with a single sequence of contiguous 1 bits), return
* the number of 1 bits in 'width' and the number of 0 bits to its
* right in 'shift'. */
static inline void
_characterize_field (uint32_t mask, int *width, int *shift)
{
*width = _cairo_popcount (mask);
/* The final '& 31' is to force a 0 mask to result in 0 shift. */
*shift = _cairo_popcount ((mask - 1) & ~mask) & 31;
}
/* Convert a field of 'width' bits to 'new_width' bits with correct
* rounding. */
static inline uint32_t
_resize_field (uint32_t field, int width, int new_width)
{
if (width == 0)
return 0;
if (width >= new_width) {
return field >> (width - new_width);
} else {
uint32_t result = field << (new_width - width);
while (width < new_width) {
result |= result >> width;
width <<= 1;
}
return result;
}
}
/* Given a shifted field value, (described by 'width' and 'shift),
* resize it 8-bits and return that value.
*
* Note that the original field value must not have any non-field bits
* set.
*/
static inline uint32_t
_field_to_8 (uint32_t field, int width, int shift)
{
return _resize_field (field >> shift, width, 8);
}
/* Given an 8-bit value, convert it to a field of 'width', shift it up
* to 'shift, and return it. */
static inline uint32_t
_field_from_8 (uint32_t field, int width, int shift)
{
return _resize_field (field, 8, width) << shift;
}
static cairo_status_t
_get_image_surface (cairo_xlib_surface_t *surface,
cairo_rectangle_int_t *interest_rect,
cairo_image_surface_t **image_out,
cairo_rectangle_int_t *image_rect)
{
cairo_int_status_t status;
cairo_image_surface_t *image;
XImage *ximage;
unsigned short x1, y1, x2, y2;
short x1, y1, x2, y2;
cairo_format_masks_t masks;
pixman_format_code_t pixman_format;
cairo_format_masks_t xlib_masks;
cairo_status_t status;
x1 = 0;
y1 = 0;
@ -628,127 +567,55 @@ _get_image_surface (cairo_xlib_surface_t *surface,
_swap_ximage_to_native (ximage);
xlib_masks.bpp = ximage->bits_per_pixel;
xlib_masks.alpha_mask = surface->a_mask;
xlib_masks.red_mask = surface->r_mask;
xlib_masks.green_mask = surface->g_mask;
xlib_masks.blue_mask = surface->b_mask;
status = _pixman_format_from_masks (&xlib_masks, &pixman_format);
if (status == CAIRO_STATUS_SUCCESS) {
image = (cairo_image_surface_t*)
_cairo_image_surface_create_with_pixman_format ((unsigned char *) ximage->data,
pixman_format,
ximage->width,
ximage->height,
ximage->bytes_per_line);
status = image->base.status;
if (status) {
XDestroyImage (ximage);
return status;
}
/* Let the surface take ownership of the data */
_cairo_image_surface_assume_ownership_of_data (image);
ximage->data = NULL;
/*
* Compute the pixel format masks from either a XrenderFormat or
* else from a visual; failing that we assume the drawable is an
* alpha-only pixmap as it could only have been created that way
* through the cairo_xlib_surface_create_for_bitmap function.
*/
if (surface->xrender_format) {
masks.bpp = ximage->bits_per_pixel;
masks.red_mask = (unsigned long) surface->xrender_format->direct.redMask
<< surface->xrender_format->direct.red;
masks.green_mask = (unsigned long) surface->xrender_format->direct.greenMask
<< surface->xrender_format->direct.green;
masks.blue_mask = (unsigned long) surface->xrender_format->direct.blueMask
<< surface->xrender_format->direct.blue;
masks.alpha_mask = (unsigned long) surface->xrender_format->direct.alphaMask
<< surface->xrender_format->direct.alpha;
} else if (surface->visual) {
masks.bpp = ximage->bits_per_pixel;
masks.alpha_mask = 0;
masks.red_mask = surface->visual->red_mask;
masks.green_mask = surface->visual->green_mask;
masks.blue_mask = surface->visual->blue_mask;
} else {
cairo_format_t format;
unsigned char *data;
uint32_t *row;
uint32_t in_pixel, out_pixel;
unsigned int rowstride;
uint32_t a_mask=0, r_mask=0, g_mask=0, b_mask=0;
int a_width=0, r_width=0, g_width=0, b_width=0;
int a_shift=0, r_shift=0, g_shift=0, b_shift=0;
int x, y;
XColor *colors = NULL;
/* The visual we are dealing with is not supported by the
* standard pixman formats. So we must first convert the data
* to a supported format. */
if (surface->visual->class == TrueColor) {
cairo_bool_t has_color;
cairo_bool_t has_alpha;
has_color = (surface->r_mask ||
surface->g_mask ||
surface->b_mask);
has_alpha = surface->a_mask;
if (has_color) {
if (has_alpha) {
format = CAIRO_FORMAT_ARGB32;
} else {
format = CAIRO_FORMAT_RGB24;
}
} else {
/* XXX: Using CAIRO_FORMAT_A8 here would be more
* efficient, but would require slightly different code in
* the image conversion to put the alpha channel values
* into the right place. */
format = CAIRO_FORMAT_ARGB32;
}
a_mask = surface->a_mask;
r_mask = surface->r_mask;
g_mask = surface->g_mask;
b_mask = surface->b_mask;
_characterize_field (a_mask, &a_width, &a_shift);
_characterize_field (r_mask, &r_width, &r_shift);
_characterize_field (g_mask, &g_width, &g_shift);
_characterize_field (b_mask, &b_width, &b_shift);
} else {
cairo_xlib_visual_info_t *visual_info;
format = CAIRO_FORMAT_RGB24;
status = _cairo_xlib_screen_get_visual_info (surface->screen_info,
surface->visual,
&visual_info);
if (status) {
XDestroyImage (ximage);
return status;
}
colors = visual_info->colors;
}
image = (cairo_image_surface_t *) cairo_image_surface_create
(format, ximage->width, ximage->height);
status = image->base.status;
if (status) {
XDestroyImage (ximage);
return status;
}
data = cairo_image_surface_get_data (&image->base);
rowstride = cairo_image_surface_get_stride (&image->base) >> 2;
row = (uint32_t *) data;
for (y = 0; y < ximage->height; y++) {
for (x = 0; x < ximage->width; x++) {
in_pixel = XGetPixel (ximage, x, y);
if (surface->visual->class == TrueColor) {
out_pixel = (
_field_to_8 (in_pixel & a_mask, a_width, a_shift) << 24 |
_field_to_8 (in_pixel & r_mask, r_width, r_shift) << 16 |
_field_to_8 (in_pixel & g_mask, g_width, g_shift) << 8 |
_field_to_8 (in_pixel & b_mask, b_width, b_shift));
} else {
XColor *color;
color = &colors[in_pixel & 0xff];
out_pixel = (
_field_to_8 (color->red, 16, 0) << 16 |
_field_to_8 (color->green, 16, 0) << 8 |
_field_to_8 (color->blue, 16, 0));
}
row[x] = out_pixel;
}
row += rowstride;
}
masks.bpp = ximage->bits_per_pixel;
masks.red_mask = 0;
masks.green_mask = 0;
masks.blue_mask = 0;
if (surface->depth < 32)
masks.alpha_mask = (1 << surface->depth) - 1;
else
masks.alpha_mask = 0xffffffff;
}
pixman_format = _pixman_format_from_masks (&masks);
image = (cairo_image_surface_t*)
_cairo_image_surface_create_with_pixman_format ((unsigned char *) ximage->data,
pixman_format,
ximage->width,
ximage->height,
ximage->bytes_per_line);
status = image->base.status;
if (status) {
XDestroyImage (ximage);
return status;
}
/* Let the surface take ownership of the data */
_cairo_image_surface_assume_ownership_of_data (image);
ximage->data = NULL;
XDestroyImage (ximage);
*image_out = image;
@ -852,118 +719,39 @@ _draw_image_surface (cairo_xlib_surface_t *surface,
int dst_y)
{
XImage ximage;
cairo_format_masks_t image_masks;
uint32_t bpp, red, green, blue;
int native_byte_order = _native_byte_order_lsb () ? LSBFirst : MSBFirst;
cairo_status_t status;
cairo_bool_t own_data;
unsigned long *rgb333_to_pseudocolor = NULL;
_pixman_format_to_masks (image->pixman_format, &image_masks);
_pixman_format_to_masks (image->pixman_format, &bpp, &red, &green, &blue);
ximage.width = image->width;
ximage.height = image->height;
ximage.format = ZPixmap;
ximage.data = (char *)image->data;
ximage.byte_order = native_byte_order;
ximage.bitmap_unit = 32; /* always for libpixman */
ximage.bitmap_bit_order = native_byte_order;
ximage.bitmap_pad = 32; /* always for libpixman */
ximage.depth = surface->depth;
ximage.red_mask = surface->r_mask;
ximage.green_mask = surface->g_mask;
ximage.blue_mask = surface->b_mask;
ximage.depth = image->depth;
ximage.bytes_per_line = image->stride;
ximage.bits_per_pixel = bpp;
ximage.red_mask = red;
ximage.green_mask = green;
ximage.blue_mask = blue;
ximage.xoffset = 0;
if (image_masks.red_mask == surface->r_mask &&
image_masks.green_mask == surface->g_mask &&
image_masks.blue_mask == surface->b_mask)
{
ximage.bits_per_pixel = image_masks.bpp;
ximage.bytes_per_line = image->stride;
ximage.data = (char *)image->data;
own_data = FALSE;
XInitImage (&ximage);
} else {
unsigned int stride, rowstride;
int x, y;
uint32_t in_pixel, out_pixel, *row;
int a_width=0, r_width=0, g_width=0, b_width=0;
int a_shift=0, r_shift=0, g_shift=0, b_shift=0;
if (surface->depth > 16) {
ximage.bits_per_pixel = 32;
} else if (surface->depth > 8) {
ximage.bits_per_pixel = 16;
} else if (surface->depth > 1) {
ximage.bits_per_pixel = 8;
} else {
ximage.bits_per_pixel = 1;
}
stride = CAIRO_STRIDE_FOR_WIDTH_BPP (ximage.width,
ximage.bits_per_pixel);
ximage.bytes_per_line = stride;
ximage.data = _cairo_malloc_ab (stride, ximage.height);
if (ximage.data == NULL)
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
own_data = TRUE;
XInitImage (&ximage);
if (surface->visual->class == TrueColor) {
_characterize_field (surface->a_mask, &a_width, &a_shift);
_characterize_field (surface->r_mask, &r_width, &r_shift);
_characterize_field (surface->g_mask, &g_width, &g_shift);
_characterize_field (surface->b_mask, &b_width, &b_shift);
} else {
cairo_xlib_visual_info_t *visual_info;
status = _cairo_xlib_screen_get_visual_info (surface->screen_info,
surface->visual,
&visual_info);
if (status)
goto BAIL;
rgb333_to_pseudocolor = visual_info->rgb333_to_pseudocolor;
}
rowstride = cairo_image_surface_get_stride (&image->base) >> 2;
row = (uint32_t *) cairo_image_surface_get_data (&image->base);
for (y = 0; y < ximage.height; y++) {
for (x = 0; x < ximage.width; x++) {
int a, r, g, b;
in_pixel = row[x];
a = (in_pixel >> 24) & 0xff;
r = (in_pixel >> 16) & 0xff;
g = (in_pixel >> 8) & 0xff;
b = (in_pixel ) & 0xff;
if (surface->visual->class == TrueColor)
out_pixel = (_field_from_8 (a, a_width, a_shift) |
_field_from_8 (r, r_width, r_shift) |
_field_from_8 (g, g_width, g_shift) |
_field_from_8 (b, b_width, b_shift));
else
out_pixel = rgb333_to_pseudocolor[_field_from_8 (r, 3, 6) |
_field_from_8 (g, 3, 3) |
_field_from_8 (b, 3, 0)];
XPutPixel (&ximage, x, y, out_pixel);
}
row += rowstride;
}
}
XInitImage (&ximage);
status = _cairo_xlib_surface_ensure_gc (surface);
if (status)
goto BAIL;
return status;
XPutImage(surface->dpy, surface->drawable, surface->gc,
&ximage, src_x, src_y, dst_x, dst_y,
width, height);
BAIL:
if (own_data)
free (ximage.data);
return CAIRO_STATUS_SUCCESS;
return status;
}
static cairo_status_t
@ -2244,40 +2032,6 @@ _cairo_xlib_surface_create_internal (Display *dpy,
surface->clip_rects = surface->embedded_clip_rects;
surface->num_clip_rects = 0;
/*
* Compute the pixel format masks from either a XrenderFormat or
* else from a visual; failing that we assume the drawable is an
* alpha-only pixmap as it could only have been created that way
* through the cairo_xlib_surface_create_for_bitmap function.
*/
if (xrender_format) {
surface->a_mask = (unsigned long)
surface->xrender_format->direct.alphaMask
<< surface->xrender_format->direct.alpha;
surface->r_mask = (unsigned long)
surface->xrender_format->direct.redMask
<< surface->xrender_format->direct.red;
surface->g_mask = (unsigned long)
surface->xrender_format->direct.greenMask
<< surface->xrender_format->direct.green;
surface->b_mask = (unsigned long)
surface->xrender_format->direct.blueMask
<< surface->xrender_format->direct.blue;
} else if (visual) {
surface->a_mask = 0;
surface->r_mask = visual->red_mask;
surface->g_mask = visual->green_mask;
surface->b_mask = visual->blue_mask;
} else {
if (depth < 32)
surface->a_mask = (1 << depth) - 1;
else
surface->a_mask = 0xffffffff;
surface->r_mask = 0;
surface->g_mask = 0;
surface->b_mask = 0;
}
return (cairo_surface_t *) surface;
}
@ -2401,6 +2155,7 @@ cairo_xlib_surface_create_with_xrender_format (Display *dpy,
return _cairo_xlib_surface_create_internal (dpy, drawable, screen,
NULL, format, width, height, 0);
}
slim_hidden_def (cairo_xlib_surface_create_with_xrender_format);
/**
* cairo_xlib_surface_get_xrender_format:
@ -2910,6 +2665,7 @@ _cairo_xlib_surface_add_glyph (Display *dpy,
cairo_xlib_font_glyphset_info_t *glyphset_info;
if (!glyph_surface) {
status = _cairo_scaled_glyph_lookup (scaled_font,
_cairo_scaled_glyph_index (scaled_glyph),
CAIRO_SCALED_GLYPH_INFO_METRICS |
@ -2925,20 +2681,6 @@ _cairo_xlib_surface_add_glyph (Display *dpy,
already_had_glyph_surface = TRUE;
}
/* XXX XRenderAddGlyph does not handle a glyph surface larger than the
* maximum XRequest size.
*/
{
/* pessimistic length estimation in case we need to change formats */
int len = 4 * glyph_surface->width * glyph_surface->height;
int max_request_size = XMaxRequestSize (dpy) -
sz_xRenderAddGlyphsReq -
sz_xGlyphInfo -
4;
if (len >= max_request_size)
return CAIRO_INT_STATUS_UNSUPPORTED;
}
if (scaled_font->surface_private == NULL) {
status = _cairo_xlib_surface_font_init (dpy, scaled_font);
if (status)
@ -2952,18 +2694,17 @@ _cairo_xlib_surface_add_glyph (Display *dpy,
/* If the glyph surface has zero height or width, we create
* a clear 1x1 surface, to avoid various X server bugs.
*/
if (glyph_surface->width == 0 || glyph_surface->height == 0) {
if ((glyph_surface->width == 0) || (glyph_surface->height == 0)) {
cairo_t *cr;
cairo_surface_t *tmp_surface;
tmp_surface = cairo_image_surface_create (glyphset_info->format, 1, 1);
if (tmp_surface->status)
goto BAIL;
cr = cairo_create (tmp_surface);
cairo_set_operator (cr, CAIRO_OPERATOR_CLEAR);
cairo_paint (cr);
status = cairo_status (cr);
cairo_destroy (cr);
tmp_surface->device_transform = glyph_surface->base.device_transform;
@ -2986,17 +2727,17 @@ _cairo_xlib_surface_add_glyph (Display *dpy,
tmp_surface = cairo_image_surface_create (glyphset_info->format,
glyph_surface->width,
glyph_surface->height);
if (tmp_surface->status)
goto BAIL;
tmp_surface->device_transform = glyph_surface->base.device_transform;
tmp_surface->device_transform_inverse = glyph_surface->base.device_transform_inverse;
cr = cairo_create (tmp_surface);
cairo_set_source_surface (cr, &glyph_surface->base, 0, 0);
cairo_set_operator (cr, CAIRO_OPERATOR_SOURCE);
cairo_paint (cr);
status = cairo_status (cr);
cairo_destroy (cr);
glyph_surface = (cairo_image_surface_t *) tmp_surface;
@ -3080,7 +2821,7 @@ _cairo_xlib_surface_add_glyph (Display *dpy,
glyph_index = _cairo_scaled_glyph_index (scaled_glyph);
XRenderAddGlyphs (dpy, glyphset_info->glyphset,
&glyph_index, &glyph_info, 1,
&glyph_index, &(glyph_info), 1,
(char *) data,
glyph_surface->stride * glyph_surface->height);

View File

@ -1,148 +0,0 @@
/* Cairo - a vector graphics library with display and print output
*
* Copyright © 2008 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.
*
* The Initial Developer of the Original Code is Red Hat, Inc.
*
* Contributor(s):
* Carl D. Worth <cworth@cworth.org>
*/
#include "cairoint.h"
#include "cairo-xlib-private.h"
/* A perceptual distance metric between two colors. No sqrt needed
* since the square of the distance is still a valid metric. */
/* XXX: This is currently using linear distance in RGB space which is
* decidedly not perceptually linear. If someone cared a lot about the
* quality, they might choose something else here. Then again, they
* might also choose not to use a PseudoColor visual... */
static inline int
_color_distance (unsigned short r1, unsigned short g1, unsigned short b1,
unsigned short r2, unsigned short g2, unsigned short b2)
{
r1 >>= 8; g1 >>= 8; b1 >>= 8;
r2 >>= 8; g2 >>= 8; b2 >>= 8;
return ((r2 - r1) * (r2 - r1) +
(g2 - g1) * (g2 - g1) +
(b2 - b1) * (b2 - b1));
}
cairo_status_t
_cairo_xlib_visual_info_create (Display *dpy,
int screen,
VisualID visualid,
cairo_xlib_visual_info_t **out)
{
cairo_xlib_visual_info_t *info;
Colormap colormap = DefaultColormap (dpy, screen);
XColor color;
int gray, red, green, blue;
int i, index, distance, min_distance = 0;
const unsigned short index5_to_short[5] = {
0x0000, 0x4000, 0x8000, 0xc000, 0xffff
};
const unsigned short index8_to_short[8] = {
0x0000, 0x2492, 0x4924, 0x6db6,
0x9249, 0xb6db, 0xdb6d, 0xffff
};
info = malloc (sizeof (cairo_xlib_visual_info_t));
if (info == NULL)
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
info->visualid = visualid;
/* Allocate a 16-entry gray ramp and a 5x5x5 color cube. Give up
* as soon as failures start. */
for (gray = 0; gray < 16; gray++) {
color.red = (gray << 12) | (gray << 8) | (gray << 4) | gray;
color.green = (gray << 12) | (gray << 8) | (gray << 4) | gray;
color.blue = (gray << 12) | (gray << 8) | (gray << 4) | gray;
if (! XAllocColor (dpy, colormap, &color))
goto DONE_ALLOCATE;
}
/* XXX: Could do this in a more clever order to have the best
* possible results from early failure. Could also choose a cube
* uniformly distributed in a better space than RGB. */
for (red = 0; red < 5; red++) {
for (green = 0; green < 5; green++) {
for (blue = 0; blue < 5; blue++) {
color.red = index5_to_short[red];
color.green = index5_to_short[green];
color.blue = index5_to_short[blue];
color.pixel = 0;
color.flags = 0;
color.pad = 0;
if (! XAllocColor (dpy, colormap, &color))
goto DONE_ALLOCATE;
}
}
}
DONE_ALLOCATE:
for (i = 0; i < ARRAY_LENGTH (info->colors); i++)
info->colors[i].pixel = i;
XQueryColors (dpy, colormap, info->colors, ARRAY_LENGTH (info->colors));
/* Search for nearest colors within allocated colormap. */
for (red = 0; red < 8; red++) {
for (green = 0; green < 8; green++) {
for (blue = 0; blue < 8; blue++) {
index = (red << 6) | (green << 3) | (blue);
for (i = 0; i < 256; i++) {
distance = _color_distance (index8_to_short[red],
index8_to_short[green],
index8_to_short[blue],
info->colors[i].red,
info->colors[i].green,
info->colors[i].blue);
if (i == 0 || distance < min_distance) {
info->rgb333_to_pseudocolor[index] = info->colors[i].pixel;
min_distance = distance;
}
}
}
}
}
*out = info;
return CAIRO_STATUS_SUCCESS;
}
void
_cairo_xlib_visual_info_destroy (Display *dpy, cairo_xlib_visual_info_t *info)
{
/* No need for XFreeColors() whilst using DefaultColormap */
free (info);
}

View File

@ -634,7 +634,9 @@ slim_hidden_def(cairo_pop_group_to_source);
* operations. See #cairo_operator_t for details on the semantics of
* each available compositing operator.
*
* The default operator is %CAIRO_OPERATOR_OVER.
* XXX: I'd also like to direct the reader's attention to some
* (not-yet-written) section on cairo's imaging model. How would I do
* that if such a section existed? (cworth).
**/
void
cairo_set_operator (cairo_t *cr, cairo_operator_t op)
@ -664,9 +666,6 @@ slim_hidden_def (cairo_set_operator);
* The color components are floating point numbers in the range 0 to
* 1. If the values passed in are outside that range, they will be
* clamped.
*
* The default source pattern is opaque black, (that is, it is
* equivalent to cairo_set_source_rgb (cr, 0.0, 0.0, 0.0)).
**/
void
cairo_set_source_rgb (cairo_t *cr, double red, double green, double blue)
@ -699,9 +698,6 @@ cairo_set_source_rgb (cairo_t *cr, double red, double green, double blue)
* The color and alpha components are floating point numbers in the
* range 0 to 1. If the values passed in are outside that range, they
* will be clamped.
*
* The default source pattern is opaque black, (that is, it is
* equivalent to cairo_set_source_rgba (cr, 0.0, 0.0, 0.0, 1.0)).
**/
void
cairo_set_source_rgba (cairo_t *cr,
@ -784,9 +780,9 @@ slim_hidden_def (cairo_set_source_surface);
* that further modifications of the current transformation matrix
* will not affect the source pattern. See cairo_pattern_set_matrix().
*
* The default source pattern is a solid pattern that is opaque black,
* (that is, it is equivalent to cairo_set_source_rgb (cr, 0.0, 0.0,
* 0.0)).
* XXX: I'd also like to direct the reader's attention to some
* (not-yet-written) section on cairo's imaging model. How would I do
* that if such a section existed? (cworth).
**/
void
cairo_set_source (cairo_t *cr, cairo_pattern_t *source)
@ -895,8 +891,6 @@ cairo_set_antialias (cairo_t *cr, cairo_antialias_t antialias)
* (potentially self-intersecting) path. The current fill rule affects
* both cairo_fill() and cairo_clip(). See #cairo_fill_rule_t for details
* on the semantics of each available fill rule.
*
* The default fill rule is %CAIRO_FILL_RULE_WINDING.
**/
void
cairo_set_fill_rule (cairo_t *cr, cairo_fill_rule_t fill_rule)
@ -965,8 +959,6 @@ cairo_set_line_width (cairo_t *cr, double width)
* examined by cairo_stroke(), cairo_stroke_extents(), and
* cairo_stroke_to_path(), but does not have any effect during path
* construction.
*
* The default line cap style is %CAIRO_LINE_CAP_BUTT.
**/
void
cairo_set_line_cap (cairo_t *cr, cairo_line_cap_t line_cap)
@ -984,7 +976,7 @@ cairo_set_line_cap (cairo_t *cr, cairo_line_cap_t line_cap)
/**
* cairo_set_line_join:
* @cr: a cairo context
* @line_join: a line join style
* @line_join: a line joint style
*
* Sets the current line join style within the cairo context. See
* #cairo_line_join_t for details about how the available line join
@ -994,8 +986,6 @@ cairo_set_line_cap (cairo_t *cr, cairo_line_cap_t line_cap)
* examined by cairo_stroke(), cairo_stroke_extents(), and
* cairo_stroke_to_path(), but does not have any effect during path
* construction.
*
* The default line join style is %CAIRO_LINE_JOIN_MITER.
**/
void
cairo_set_line_join (cairo_t *cr, cairo_line_join_t line_join)
@ -1126,15 +1116,6 @@ cairo_get_dash (cairo_t *cr,
* examined by cairo_stroke(), cairo_stroke_extents(), and
* cairo_stroke_to_path(), but does not have any effect during path
* construction.
*
* The default miter limit value is 10.0, which will convert joins
* with interior angles less than 11 degrees to bevels instead of
* miters. For reference, a miter limit of 2.0 makes the miter cutoff
* at 60 degrees, and a miter limit of 1.414 makes the cutoff at 90
* degrees.
*
* A miter limit for a desired angle can be computed as: miter limit =
* 1/sin(angle/2)
**/
void
cairo_set_miter_limit (cairo_t *cr, double limit)
@ -2314,15 +2295,10 @@ cairo_in_fill (cairo_t *cr, double x, double y)
* taken into account.
*
* Note that if the line width is set to exactly zero, then
* cairo_stroke_extents() will return an empty rectangle. Contrast with
* cairo_stroke_extents will return an empty rectangle. Contrast with
* cairo_path_extents() which can be used to compute the non-empty
* bounds as the line width approaches zero.
*
* Note that cairo_stroke_extents() must necessarily do more work to
* compute the precise inked areas in light of the stroke parameters,
* so cairo_path_extents() may be more desirable for sake of
* performance if non-inked path extents are desired.
*
* See cairo_stroke(), cairo_set_line_width(), cairo_set_line_join(),
* cairo_set_line_cap(), cairo_set_dash(), and
* cairo_stroke_preserve().
@ -2368,13 +2344,8 @@ cairo_stroke_extents (cairo_t *cr,
* dimensions and clipping are not taken into account.
*
* Contrast with cairo_path_extents(), which is similar, but returns
* non-zero extents for some paths with no inked area, (such as a
* simple line segment).
*
* Note that cairo_fill_extents() must necessarily do more work to
* compute the precise inked areas in light of the fill rule, so
* cairo_path_extents() may be more desirable for sake of performance
* if the non-inked path extents are desired.
* non-zero extents for some paths no inked area, (such as a simple
* line segment).
*
* See cairo_fill(), cairo_set_fill_rule() and cairo_fill_preserve().
**/
@ -2590,38 +2561,13 @@ cairo_copy_clip_rectangle_list (cairo_t *cr)
* @slant: the slant for the font
* @weight: the weight for the font
*
* Note: The cairo_select_font_face() function call is part of what
* the cairo designers call the "toy" text API. It is convenient for
* short demos and simple programs, but it is not expected to be
* adequate for serious text-using applications.
*
* Selects a family and style of font from a simplified description as
* a family name, slant and weight. Cairo provides no operation to
* list available family names on the system (this is a "toy",
* remember"), but the standard CSS2 generic family names, ("serif",
* "sans-serif", "cursive", "fantasy", "monospace"), are likely to
* work as expected.
*
* For "real" font selection, see the font-backend-specific
* font_face_create functions for the font backend you are using. (For
* example, if you are using the freetype-based cairo-ft font backend,
* see cairo_ft_font_face_create_for_ft_face() or
* cairo_ft_font_face_create_for_pattern().) The resulting font face
* could then be used with cairo_scaled_font_create() and
* cairo_set_scaled_font().
*
* Similarly, when using the "real" font support, you can call
* directly into the underlying font system, (such as fontconfig or
* freetype), for operations such as listing available fonts, etc.
*
* It is expected that most applications will need to use a more
* comprehensive font handling and text layout library, (for example,
* pango), in conjunction with cairo.
*
* If text is drawn without a call to cairo_select_font_face(), (nor
* cairo_set_font_face() nor cairo_set_scaled_font()), the default
* family is "sans", slant is %CAIRO_FONT_SLANT_NORMAL, and weight is
* %CAIRO_FONT_WEIGHT_NORMAL.
* a family name, slant and weight. This function is meant to be used
* only for applications with simple font needs: Cairo doesn't provide
* for operations such as listing all available fonts on the system,
* and it is expected that most applications will need to use a more
* comprehensive font handling and text layout library in addition to
* cairo.
**/
void
cairo_select_font_face (cairo_t *cr,
@ -2736,10 +2682,6 @@ cairo_get_font_face (cairo_t *cr)
* cairo_set_font_matrix(). This results in a font size of @size user space
* units. (More precisely, this matrix will result in the font's
* em-square being a @size by @size square in user space.)
*
* If text is drawn without a call to cairo_set_font_size(), (nor
* cairo_set_font_matrix() nor cairo_set_scaled_font()), the default
* font size is 10.0.
**/
void
cairo_set_font_size (cairo_t *cr, double size)

View File

@ -373,8 +373,6 @@ cairo_pop_group_to_source (cairo_t *cr);
* #cairo_operator_t is used to set the compositing operator for all cairo
* drawing operations.
*
* The default operator is %CAIRO_OPERATOR_OVER.
*
* The operators marked as <firstterm>unbounded</firstterm> modify their
* destination even outside of the mask layer (that is, their effect is not
* bound by the mask layer). However, their effect can still be limited by
@ -475,8 +473,6 @@ cairo_set_antialias (cairo_t *cr, cairo_antialias_t antialias);
* (Note that filling is not actually implemented in this way. This
* is just a description of the rule that is applied.)
*
* The default fill rule is %CAIRO_FILL_RULE_WINDING.
*
* New entries may be added in future versions.
**/
typedef enum _cairo_fill_rule {
@ -496,9 +492,7 @@ cairo_set_line_width (cairo_t *cr, double width);
* @CAIRO_LINE_CAP_ROUND: use a round ending, the center of the circle is the end point
* @CAIRO_LINE_CAP_SQUARE: use squared ending, the center of the square is the end point
*
* Specifies how to render the endpoints of the path when stroking.
*
* The default line cap style is %CAIRO_LINE_CAP_BUTT.
* Specifies how to render the endpoint of a line when stroking.
**/
typedef enum _cairo_line_cap {
CAIRO_LINE_CAP_BUTT,
@ -519,8 +513,6 @@ cairo_set_line_cap (cairo_t *cr, cairo_line_cap_t line_cap);
* the line width from the joint point
*
* Specifies how to render the junction of two lines when stroking.
*
* The default line join style is %CAIRO_LINE_JOIN_MITER.
**/
typedef enum _cairo_line_join {
CAIRO_LINE_JOIN_MITER,
@ -1156,7 +1148,7 @@ cairo_font_face_status (cairo_font_face_t *font_face);
* @CAIRO_FONT_TYPE_TOY: The font was created using cairo's toy font api
* @CAIRO_FONT_TYPE_FT: The font is of type FreeType
* @CAIRO_FONT_TYPE_WIN32: The font is of type Win32
* @CAIRO_FONT_TYPE_QUARTZ: The font is of type Quartz (Since: 1.6)
* @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
@ -1191,7 +1183,7 @@ typedef enum _cairo_font_type {
CAIRO_FONT_TYPE_TOY,
CAIRO_FONT_TYPE_FT,
CAIRO_FONT_TYPE_WIN32,
CAIRO_FONT_TYPE_QUARTZ
CAIRO_FONT_TYPE_ATSUI
} cairo_font_type_t;
cairo_public cairo_font_type_t
@ -1797,18 +1789,13 @@ cairo_pattern_get_matrix (cairo_pattern_t *pattern,
* are fully transparent
* @CAIRO_EXTEND_REPEAT: the pattern is tiled by repeating
* @CAIRO_EXTEND_REFLECT: the pattern is tiled by reflecting
* at the edges (Implemented for surface patterns since 1.6)
* at the edges (not implemented for surface patterns currently)
* @CAIRO_EXTEND_PAD: pixels outside of the pattern copy
* the closest pixel from the source (Since 1.2; but only
* implemented for surface patterns since 1.6)
* the closest pixel from the source (Since 1.2; not implemented
* for surface patterns currently)
*
* #cairo_extend_t is used to describe how pattern color/alpha will be
* determined for areas "outside" the pattern's natural area, (for
* example, outside the surface bounds or outside the gradient
* geometry).
*
* The default extend mode is %CAIRO_EXTEND_NONE for surface patterns
* and %CAIRO_EXTEND_PAD for gradient patterns.
* #cairo_extend_t is used to describe how the area outside
* of a pattern will be drawn.
*
* New entries may be added in future versions.
**/

View File

@ -147,27 +147,6 @@ do { \
*/
#define CAIRO_BITSWAP8(c) ((((c) * 0x0802LU & 0x22110LU) | ((c) * 0x8020LU & 0x88440LU)) * 0x10101LU >> 16)
/* Return the number of 1 bits in mask.
*
* GCC 3.4 supports a "population count" builtin, which on many targets is
* implemented with a single instruction. There is a fallback definition
* in libgcc in case a target does not have one, which should be just as
* good as the open-coded solution below, (which is "HACKMEM 169").
*/
static inline int
_cairo_popcount (uint32_t mask)
{
#if __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4)
return __builtin_popcount (mask);
#else
register int y;
y = (mask >> 1) &033333333333;
y = mask - y - ((y >>1) & 033333333333);
return (((y + (y >> 3)) & 030707070707) % 077);
#endif
}
#ifdef WORDS_BIGENDIAN
#define CAIRO_BITSWAP8_IF_LITTLE_ENDIAN(c) (c)
#else
@ -238,7 +217,7 @@ cairo_private void
_cairo_array_fini (cairo_array_t *array);
cairo_private cairo_status_t
_cairo_array_grow_by (cairo_array_t *array, unsigned int additional);
_cairo_array_grow_by (cairo_array_t *array, int additional);
cairo_private void
_cairo_array_truncate (cairo_array_t *array, unsigned int num_elements);
@ -460,9 +439,9 @@ extern const cairo_private struct _cairo_scaled_font_backend cairo_win32_scaled_
#endif
#if CAIRO_HAS_QUARTZ_FONT
#if CAIRO_HAS_ATSUI_FONT
extern const cairo_private struct _cairo_scaled_font_backend cairo_quartz_scaled_font_backend;
extern const cairo_private struct _cairo_scaled_font_backend cairo_atsui_scaled_font_backend;
#endif
@ -768,7 +747,7 @@ struct _cairo_color {
#define CAIRO_EXTEND_SURFACE_DEFAULT CAIRO_EXTEND_NONE
#define CAIRO_EXTEND_GRADIENT_DEFAULT CAIRO_EXTEND_PAD
#define CAIRO_FILTER_DEFAULT CAIRO_FILTER_GOOD
#define CAIRO_FILTER_DEFAULT CAIRO_FILTER_BEST
struct _cairo_pattern {
cairo_pattern_type_t type;
@ -797,7 +776,7 @@ typedef struct _cairo_surface_pattern {
} cairo_surface_pattern_t;
typedef struct _cairo_gradient_stop {
double offset;
cairo_fixed_t x;
cairo_color_t color;
} cairo_gradient_stop_t;
@ -869,7 +848,7 @@ typedef struct _cairo_traps {
#define CAIRO_FONT_WEIGHT_DEFAULT CAIRO_FONT_WEIGHT_NORMAL
#define CAIRO_WIN32_FONT_FAMILY_DEFAULT "Arial"
#define CAIRO_QUARTZ_FONT_FAMILY_DEFAULT "Helvetica"
#define CAIRO_ATSUI_FONT_FAMILY_DEFAULT "Helvetica"
#define CAIRO_FT_FONT_FAMILY_DEFAULT ""
#if CAIRO_HAS_WIN32_FONT
@ -877,10 +856,10 @@ typedef struct _cairo_traps {
#define CAIRO_FONT_FAMILY_DEFAULT CAIRO_WIN32_FONT_FAMILY_DEFAULT
#define CAIRO_SCALED_FONT_BACKEND_DEFAULT &cairo_win32_scaled_font_backend
#elif CAIRO_HAS_QUARTZ_FONT
#elif CAIRO_HAS_ATSUI_FONT
#define CAIRO_FONT_FAMILY_DEFAULT CAIRO_QUARTZ_FONT_FAMILY_DEFAULT
#define CAIRO_SCALED_FONT_BACKEND_DEFAULT &cairo_quartz_scaled_font_backend
#define CAIRO_FONT_FAMILY_DEFAULT CAIRO_ATSUI_FONT_FAMILY_DEFAULT
#define CAIRO_SCALED_FONT_BACKEND_DEFAULT &cairo_atsui_scaled_font_backend
#elif CAIRO_HAS_FT_FONT
@ -1757,9 +1736,6 @@ _cairo_surface_intersect_clip_path (cairo_surface_t *surface,
double tolerance,
cairo_antialias_t antialias);
cairo_private cairo_clip_t *
_cairo_surface_get_clip (cairo_surface_t *surface);
cairo_private cairo_status_t
_cairo_surface_set_clip (cairo_surface_t *surface, cairo_clip_t *clip);
@ -1860,11 +1836,6 @@ _cairo_surface_has_device_transform (cairo_surface_t *surface);
#define CAIRO_FORMAT_INVALID ((unsigned int) -1)
#define CAIRO_FORMAT_VALID(format) ((format) <= CAIRO_FORMAT_A1)
/* pixman-required stride alignment in bytes. */
#define CAIRO_STRIDE_ALIGNMENT (sizeof (uint32_t))
#define CAIRO_STRIDE_FOR_WIDTH_BPP(w,bpp) \
(((bpp)*(w)+7)/8 + CAIRO_STRIDE_ALIGNMENT-1) & ~(CAIRO_STRIDE_ALIGNMENT-1)
#define CAIRO_CONTENT_VALID(content) ((content) && \
(((content) & ~(CAIRO_CONTENT_COLOR | \
CAIRO_CONTENT_ALPHA | \
@ -1884,13 +1855,15 @@ cairo_private cairo_surface_t *
_cairo_image_surface_create_for_pixman_image (pixman_image_t *pixman_image,
pixman_format_code_t pixman_format);
cairo_private cairo_int_status_t
_pixman_format_from_masks (cairo_format_masks_t *masks,
pixman_format_code_t *format_ret);
cairo_private pixman_format_code_t
_pixman_format_from_masks (cairo_format_masks_t *masks);
cairo_private void
_pixman_format_to_masks (pixman_format_code_t pixman_format,
cairo_format_masks_t *masks);
uint32_t *bpp,
uint32_t *red,
uint32_t *green,
uint32_t *blue);
cairo_private cairo_surface_t *
_cairo_image_surface_create_with_pixman_format (unsigned char *data,
@ -2236,7 +2209,7 @@ _cairo_utf8_to_ucs4 (const unsigned char *str,
uint32_t **result,
int *items_written);
#if CAIRO_HAS_WIN32_FONT+0 || CAIRO_HAS_QUARTZ_FONT+0
#if CAIRO_HAS_WIN32_FONT+0 || CAIRO_HAS_ATSUI_FONT+0
# define CAIRO_HAS_UTF8_TO_UTF16 1
#endif
#if CAIRO_HAS_UTF8_TO_UTF16
@ -2280,9 +2253,7 @@ slim_hidden_proto (cairo_get_matrix);
slim_hidden_proto (cairo_get_tolerance);
slim_hidden_proto (cairo_image_surface_create);
slim_hidden_proto (cairo_image_surface_create_for_data);
slim_hidden_proto (cairo_image_surface_get_data);
slim_hidden_proto (cairo_image_surface_get_height);
slim_hidden_proto (cairo_image_surface_get_stride);
slim_hidden_proto (cairo_image_surface_get_width);
slim_hidden_proto (cairo_format_stride_for_width);
slim_hidden_proto (cairo_line_to);

View File

@ -83,9 +83,6 @@ endif
CSRCS = \
pixman-access.c \
pixman-access-accessors.c \
pixman-combine.c \
pixman-compose.c \
pixman-compose-accessors.c \
pixman-compute-region.c \
@ -94,9 +91,6 @@ CSRCS = \
pixman-image.c \
pixman-pict.c \
pixman-region.c \
pixman-source.c \
pixman-transformed.c \
pixman-transformed-accessors.c \
pixman-trap.c \
pixman-utils.c \
$(NULL)
@ -106,7 +100,7 @@ CSRCS += pixman-mmx.c
DEFINES += -DUSE_MMX
endif
EXPORTS = pixman.h pixman-remap.h pixman-version.h
EXPORTS = pixman.h pixman-remap.h
LOCAL_INCLUDES += -I$(srcdir) -I$(srcdir)/../../cairo/src

View File

@ -1,3 +0,0 @@
#define PIXMAN_FB_ACCESSORS
#include "pixman-access.c"

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -717,87 +717,3 @@ pixman_image_fill_rectangles (pixman_op_t op,
return TRUE;
}
pixman_bool_t
pixman_image_can_get_solid (pixman_image_t *image)
{
if (image->type == SOLID)
return TRUE;
if (image->type != BITS ||
image->bits.width != 1 ||
image->bits.height != 1)
{
return FALSE;
}
if (image->common.repeat != PIXMAN_REPEAT_NORMAL)
return FALSE;
switch (image->bits.format)
{
case PIXMAN_a8r8g8b8:
case PIXMAN_x8r8g8b8:
case PIXMAN_a8b8g8r8:
case PIXMAN_x8b8g8r8:
case PIXMAN_r8g8b8:
case PIXMAN_b8g8r8:
case PIXMAN_r5g6b5:
case PIXMAN_b5g6r5:
return TRUE;
default:
return FALSE;
}
}
pixman_bool_t
pixman_image_is_opaque(pixman_image_t *image)
{
int i = 0;
int gradientNumberOfColors = 0;
if(image->common.alpha_map)
return FALSE;
switch(image->type)
{
case BITS:
if(PIXMAN_FORMAT_A(image->bits.format))
return FALSE;
break;
case LINEAR:
case CONICAL:
case RADIAL:
gradientNumberOfColors = image->gradient.n_stops;
i=0;
while(i<gradientNumberOfColors)
{
if(image->gradient.stops[i].color.alpha != 0xffff)
return FALSE;
i++;
}
break;
case SOLID:
if(Alpha(image->solid.color) != 0xff)
return FALSE;
break;
}
/* Convolution filters can introduce translucency if the sum of the weights
is lower than 1. */
if (image->common.filter == PIXMAN_FILTER_CONVOLUTION)
return FALSE;
if (image->common.repeat == PIXMAN_REPEAT_NONE)
{
if (image->common.filter != PIXMAN_FILTER_NEAREST)
return FALSE;
if (image->common.transform)
return FALSE;
}
return TRUE;
}

View File

@ -76,8 +76,9 @@
/* --------------- MMX primitivess ------------------------------------ */
#ifdef __GNUC__
typedef unsigned long long ullong;
#ifdef __GNUC__
typedef ullong mmxdatafield;
#endif
#ifdef _MSC_VER
@ -912,14 +913,8 @@ mmxCombineAddC (uint32_t *dest, uint32_t *src, uint32_t *mask, int width)
_mm_empty();
}
void
fbComposeSetupMMX(void)
void fbComposeSetupMMX(void)
{
static pixman_bool_t initialized = FALSE;
if (initialized)
return;
/* check if we have MMX support and initialize accordingly */
if (pixman_have_mmx())
{
@ -949,8 +944,6 @@ fbComposeSetupMMX(void)
pixman_composeFunctions.combineMaskU = mmxCombineMaskU;
}
initialized = TRUE;
}
@ -1623,7 +1616,7 @@ fbCompositeSolidMask_nx8x8888mmx (pixman_op_t op,
if (srca == 0)
return;
srcsrc = (ullong)src << 32 | src;
srcsrc = (unsigned long long)src << 32 | src;
fbComposeGetStart (pDst, xDst, yDst, uint32_t, dstStride, dstLine, 1);
fbComposeGetStart (pMask, xMask, yMask, uint8_t, maskStride, maskLine, 1);
@ -1666,7 +1659,7 @@ fbCompositeSolidMask_nx8x8888mmx (pixman_op_t op,
if (srca == 0xff && (m0 & m1) == 0xff)
{
*(ullong *)dst = srcsrc;
*(unsigned long long *)dst = srcsrc;
}
else if (m0 | m1)
{
@ -1987,7 +1980,7 @@ fbCompositeSolidMask_nx8x0565mmx (pixman_op_t op,
int dstStride, maskStride;
uint16_t w;
__m64 vsrc, vsrca, tmp;
ullong srcsrcsrcsrc, src16;
unsigned long long srcsrcsrcsrc, src16;
CHECKPOINT();
@ -2049,7 +2042,7 @@ fbCompositeSolidMask_nx8x0565mmx (pixman_op_t op,
if (srca == 0xff && (m0 & m1 & m2 & m3) == 0xff)
{
*(ullong *)dst = srcsrcsrcsrc;
*(unsigned long long *)dst = srcsrcsrcsrc;
}
else if (m0 | m1 | m2 | m3)
{
@ -2963,6 +2956,8 @@ fbCompositeOver_x888x8x8888mmx (pixman_op_t op,
uint32_t *dst, *dstLine;
uint8_t *mask, *maskLine;
int srcStride, maskStride, dstStride;
__m64 m;
uint32_t s, d;
uint16_t w;
fbComposeGetStart (pDst, xDst, yDst, uint32_t, dstStride, dstLine, 1);

View File

@ -26,9 +26,6 @@
*
* Based on work by Owen Taylor
*/
#ifndef _PIXMAN_MMX_H_
#define _PIXMAN_MMX_H_
#ifdef HAVE_DIX_CONFIG_H
#include <dix-config.h>
#endif
@ -316,5 +313,3 @@ fbCompositeOver_x888x8x8888mmx (pixman_op_t op,
uint16_t height);
#endif /* USE_MMX */
#endif /* _PIXMAN_MMX_H_ */

View File

@ -33,7 +33,6 @@
#include "pixman-private.h"
#include "pixman-mmx.h"
#include "pixman-sse.h"
#define FbFullMask(n) ((n) == 32 ? (uint32_t)-1 : ((((uint32_t) 1) << n) - 1))
@ -149,6 +148,9 @@ fbCompositeOver_x888x8x8888 (pixman_op_t op,
dst++;
}
}
fbFinishAccess (pMask->pDrawable);
fbFinishAccess (pDst->pDrawable);
}
static void
@ -337,6 +339,9 @@ fbCompositeSolidMask_nx8x8888 (pixman_op_t op,
dst++;
}
}
fbFinishAccess (pMask->pDrawable);
fbFinishAccess (pDst->pDrawable);
}
void
@ -410,6 +415,9 @@ fbCompositeSolidMask_nx8888x8888C (pixman_op_t op,
dst++;
}
}
fbFinishAccess (pMask->pDrawable);
fbFinishAccess (pDst->pDrawable);
}
void
@ -472,6 +480,9 @@ fbCompositeSolidMask_nx8x0888 (pixman_op_t op,
dst += 3;
}
}
fbFinishAccess (pMask->pDrawable);
fbFinishAccess (pDst->pDrawable);
}
void
@ -535,6 +546,9 @@ fbCompositeSolidMask_nx8x0565 (pixman_op_t op,
dst++;
}
}
fbFinishAccess (pMask->pDrawable);
fbFinishAccess (pDst->pDrawable);
}
void
@ -608,6 +622,9 @@ fbCompositeSolidMask_nx8888x0565C (pixman_op_t op,
dst++;
}
}
fbFinishAccess (pMask->pDrawable);
fbFinishAccess (pDst->pDrawable);
}
void
@ -654,6 +671,9 @@ fbCompositeSrc_8888x8888 (pixman_op_t op,
dst++;
}
}
fbFinishAccess (pSrc->pDrawable);
fbFinishAccess (pDst->pDrawable);
}
void
@ -703,6 +723,9 @@ fbCompositeSrc_8888x0888 (pixman_op_t op,
dst += 3;
}
}
fbFinishAccess (pSrc->pDrawable);
fbFinishAccess (pDst->pDrawable);
}
void
@ -755,6 +778,9 @@ fbCompositeSrc_8888x0565 (pixman_op_t op,
dst++;
}
}
fbFinishAccess (pDst->pDrawable);
fbFinishAccess (pSrc->pDrawable);
}
void
@ -805,6 +831,9 @@ fbCompositeSrcAdd_8000x8000 (pixman_op_t op,
dst++;
}
}
fbFinishAccess (pDst->pDrawable);
fbFinishAccess (pSrc->pDrawable);
}
void
@ -862,6 +891,9 @@ fbCompositeSrcAdd_8888x8888 (pixman_op_t op,
dst++;
}
}
fbFinishAccess (pDst->pDrawable);
fbFinishAccess (pSrc->pDrawable);
}
static void
@ -914,6 +946,9 @@ fbCompositeSrcAdd_8888x8x8 (pixman_op_t op,
WRITE(pDst, dst++, r);
}
}
fbFinishAccess(pDst->pDrawable);
fbFinishAccess(pMask->pDrawable);
}
void
@ -961,6 +996,8 @@ fbCompositeSrcAdd_1000x1000 (pixman_op_t op,
FALSE,
FALSE);
fbFinishAccess(pDst->pDrawable);
fbFinishAccess(pSrc->pDrawable);
#endif
}
@ -1021,6 +1058,8 @@ fbCompositeSolidMask_nx1xn (pixman_op_t op,
FB_ALLONES,
0x0);
fbFinishAccess (pDst->pDrawable);
fbFinishAccess (pMask->pDrawable);
#endif
}
@ -1091,6 +1130,9 @@ fbCompositeSrcSrc_nxn (pixman_op_t op,
reverse,
upsidedown);
fbFinishAccess(pSrc->pDrawable);
fbFinishAccess(pDst->pDrawable);
#endif
}
@ -1167,6 +1209,9 @@ fbCompositeSrc_8888xx888 (pixman_op_t op,
dst += dstStride;
src += srcStride;
}
fbFinishAccess(pSrc->pDrawable);
fbFinishAccess(pDst->pDrawable);
}
static void
@ -1261,6 +1306,38 @@ pixman_walk_composite_region (pixman_op_t op,
pixman_region_fini (&reg);
}
static pixman_bool_t
can_get_solid (pixman_image_t *image)
{
if (image->type == SOLID)
return TRUE;
if (image->type != BITS ||
image->bits.width != 1 ||
image->bits.height != 1)
{
return FALSE;
}
if (image->common.repeat != PIXMAN_REPEAT_NORMAL)
return FALSE;
switch (image->bits.format)
{
case PIXMAN_a8r8g8b8:
case PIXMAN_x8r8g8b8:
case PIXMAN_a8b8g8r8:
case PIXMAN_x8b8g8r8:
case PIXMAN_r8g8b8:
case PIXMAN_b8g8r8:
case PIXMAN_r5g6b5:
case PIXMAN_b5g6r5:
return TRUE;
default:
return FALSE;
}
}
#define SCANLINE_BUFFER_LENGTH 2048
static void
@ -1396,8 +1473,6 @@ static const FastPathInfo mmx_fast_paths[] =
{ PIXMAN_OP_SRC, PIXMAN_a8r8g8b8, PIXMAN_null, PIXMAN_a8r8g8b8, fbCompositeCopyAreammx, 0 },
{ PIXMAN_OP_SRC, PIXMAN_a8b8g8r8, PIXMAN_null, PIXMAN_a8b8g8r8, fbCompositeCopyAreammx, 0 },
{ PIXMAN_OP_SRC, PIXMAN_a8r8g8b8, PIXMAN_null, PIXMAN_x8r8g8b8, fbCompositeCopyAreammx, 0 },
{ PIXMAN_OP_SRC, PIXMAN_a8b8g8r8, PIXMAN_null, PIXMAN_x8b8g8r8, fbCompositeCopyAreammx, 0 },
{ PIXMAN_OP_SRC, PIXMAN_x8r8g8b8, PIXMAN_null, PIXMAN_x8r8g8b8, fbCompositeCopyAreammx, 0 },
{ PIXMAN_OP_SRC, PIXMAN_x8b8g8r8, PIXMAN_null, PIXMAN_x8b8g8r8, fbCompositeCopyAreammx, 0 },
{ PIXMAN_OP_SRC, PIXMAN_r5g6b5, PIXMAN_null, PIXMAN_r5g6b5, fbCompositeCopyAreammx, 0 },
@ -1408,13 +1483,6 @@ static const FastPathInfo mmx_fast_paths[] =
};
#endif
#ifdef USE_SSE2
static const FastPathInfo sse_fast_paths[] =
{
{ PIXMAN_OP_NONE },
};
#endif
static const FastPathInfo c_fast_paths[] =
{
{ PIXMAN_OP_OVER, PIXMAN_solid, PIXMAN_a8, PIXMAN_r5g6b5, fbCompositeSolidMask_nx8x0565, 0 },
@ -1522,7 +1590,7 @@ get_fast_path (const FastPathInfo *fast_paths,
if (info->op != op)
continue;
if ((info->src_format == PIXMAN_solid && pixman_image_can_get_solid (pSrc)) ||
if ((info->src_format == PIXMAN_solid && can_get_solid (pSrc)) ||
(pSrc->type == BITS && info->src_format == pSrc->bits.format))
{
valid_src = TRUE;
@ -1564,82 +1632,6 @@ get_fast_path (const FastPathInfo *fast_paths,
return NULL;
}
/*
* Operator optimizations based on source or destination opacity
*/
typedef struct
{
pixman_op_t op;
pixman_op_t opSrcDstOpaque;
pixman_op_t opSrcOpaque;
pixman_op_t opDstOpaque;
} OptimizedOperatorInfo;
static const OptimizedOperatorInfo optimized_operators[] =
{
/* Input Operator SRC&DST Opaque SRC Opaque DST Opaque */
{ PIXMAN_OP_OVER, PIXMAN_OP_SRC, PIXMAN_OP_SRC, PIXMAN_OP_OVER },
{ PIXMAN_OP_OVER_REVERSE, PIXMAN_OP_DST, PIXMAN_OP_OVER_REVERSE, PIXMAN_OP_DST },
{ PIXMAN_OP_IN, PIXMAN_OP_SRC, PIXMAN_OP_IN, PIXMAN_OP_SRC },
{ PIXMAN_OP_IN_REVERSE, PIXMAN_OP_DST, PIXMAN_OP_DST, PIXMAN_OP_IN_REVERSE },
{ PIXMAN_OP_OUT, PIXMAN_OP_CLEAR, PIXMAN_OP_OUT, PIXMAN_OP_CLEAR },
{ PIXMAN_OP_OUT_REVERSE, PIXMAN_OP_CLEAR, PIXMAN_OP_CLEAR, PIXMAN_OP_OUT_REVERSE },
{ PIXMAN_OP_ATOP, PIXMAN_OP_SRC, PIXMAN_OP_IN, PIXMAN_OP_OVER },
{ PIXMAN_OP_ATOP_REVERSE, PIXMAN_OP_DST, PIXMAN_OP_OVER_REVERSE, PIXMAN_OP_IN_REVERSE },
{ PIXMAN_OP_XOR, PIXMAN_OP_CLEAR, PIXMAN_OP_OUT, PIXMAN_OP_OUT_REVERSE },
{ PIXMAN_OP_SATURATE, PIXMAN_OP_DST, PIXMAN_OP_OVER_REVERSE, PIXMAN_OP_DST },
{ PIXMAN_OP_NONE }
};
/*
* Check if the current operator could be optimized
*/
static const OptimizedOperatorInfo*
pixman_operator_can_be_optimized(pixman_op_t op)
{
const OptimizedOperatorInfo *info;
for (info = optimized_operators; info->op != PIXMAN_OP_NONE; info++)
{
if(info->op == op)
return info;
}
return NULL;
}
/*
* Optimize the current operator based on opacity of source or destination
* The output operator should be mathematically equivalent to the source.
*/
static pixman_op_t
pixman_optimize_operator(pixman_op_t op, pixman_image_t *pSrc, pixman_image_t *pMask, pixman_image_t *pDst )
{
pixman_bool_t is_source_opaque;
pixman_bool_t is_dest_opaque;
const OptimizedOperatorInfo *info = pixman_operator_can_be_optimized(op);
if(!info || pMask)
return op;
is_source_opaque = pixman_image_is_opaque(pSrc);
is_dest_opaque = pixman_image_is_opaque(pDst);
if(is_source_opaque == FALSE && is_dest_opaque == FALSE)
return op;
if(is_source_opaque && is_dest_opaque)
return info->opSrcDstOpaque;
else if(is_source_opaque)
return info->opSrcOpaque;
else if(is_dest_opaque)
return info->opDstOpaque;
return op;
}
void
pixman_image_composite (pixman_op_t op,
pixman_image_t * pSrc,
@ -1654,29 +1646,28 @@ pixman_image_composite (pixman_op_t op,
uint16_t width,
uint16_t height)
{
pixman_bool_t srcRepeat = pSrc->type == BITS && pSrc->common.repeat == PIXMAN_REPEAT_NORMAL;
pixman_bool_t maskRepeat = FALSE;
pixman_bool_t srcTransform = pSrc->common.transform != NULL;
pixman_bool_t maskTransform = FALSE;
pixman_bool_t srcAlphaMap = pSrc->common.alpha_map != NULL;
pixman_bool_t maskAlphaMap = FALSE;
pixman_bool_t dstAlphaMap = pDst->common.alpha_map != NULL;
CompositeFunc func = NULL;
pixman_bool_t srcRepeat = pSrc->type == BITS && pSrc->common.repeat == PIXMAN_REPEAT_NORMAL;
pixman_bool_t maskRepeat = FALSE;
pixman_bool_t srcTransform = pSrc->common.transform != NULL;
pixman_bool_t maskTransform = FALSE;
pixman_bool_t srcAlphaMap = pSrc->common.alpha_map != NULL;
pixman_bool_t maskAlphaMap = FALSE;
pixman_bool_t dstAlphaMap = pDst->common.alpha_map != NULL;
CompositeFunc func = NULL;
#ifdef USE_SSE2
fbComposeSetupSSE();
#endif
#ifdef USE_MMX
fbComposeSetupMMX();
static pixman_bool_t mmx_setup = FALSE;
if (!mmx_setup)
{
fbComposeSetupMMX();
mmx_setup = TRUE;
}
#endif
if (srcRepeat && srcTransform &&
pSrc->bits.width == 1 &&
pSrc->bits.height == 1)
{
srcTransform = FALSE;
}
if (pMask && pMask->type == BITS)
{
@ -1691,20 +1682,10 @@ pixman_image_composite (pixman_op_t op,
if (maskRepeat && maskTransform &&
pMask->bits.width == 1 &&
pMask->bits.height == 1)
{
maskTransform = FALSE;
}
}
/*
* Check if we can replace our operator by a simpler one if the src or dest are opaque
* The output operator should be mathematically equivalent to the source.
*/
op = pixman_optimize_operator(op, pSrc, pMask, pDst);
if(op == PIXMAN_OP_DST)
return;
if ((pSrc->type == BITS || pixman_image_can_get_solid (pSrc)) && (!pMask || pMask->type == BITS)
if ((pSrc->type == BITS || can_get_solid (pSrc)) && (!pMask || pMask->type == BITS)
&& !srcTransform && !maskTransform
&& !maskAlphaMap && !srcAlphaMap && !dstAlphaMap
&& (pSrc->common.filter != PIXMAN_FILTER_CONVOLUTION)
@ -1725,16 +1706,9 @@ pixman_image_composite (pixman_op_t op,
ySrc == yMask &&
!pMask->common.component_alpha &&
!maskRepeat;
info = NULL;
#ifdef USE_SSE2
if (pixman_have_sse ())
info = get_fast_path (sse_fast_paths, op, pSrc, pMask, pDst, pixbuf);
if (!info)
#endif
#ifdef USE_MMX
info = NULL;
if (pixman_have_mmx())
info = get_fast_path (mmx_fast_paths, op, pSrc, pMask, pDst, pixbuf);
if (!info)
@ -1805,7 +1779,6 @@ pixman_image_composite (pixman_op_t op,
}
#ifdef USE_MMX
/* The CPU detection code needs to be in a file not compiled with
* "-mmmx -msse", as gcc would generate CMOV instructions otherwise
@ -2003,24 +1976,5 @@ pixman_have_mmx (void)
return mmx_present;
}
#ifdef USE_SSE2
pixman_bool_t
pixman_have_sse (void)
{
static pixman_bool_t initialized = FALSE;
static pixman_bool_t sse_present;
if (!initialized)
{
unsigned int features = detectCPUFeatures();
sse_present = (features & (MMX|MMX_Extensions|SSE|SSE2)) == (MMX|MMX_Extensions|SSE|SSE2);
initialized = TRUE;
}
return sse_present;
}
#endif
#endif /* __amd64__ */
#endif

View File

@ -148,12 +148,6 @@ typedef struct point point_t;
typedef FASTCALL void (*CombineMaskU) (uint32_t *src, const uint32_t *mask, int width);
typedef FASTCALL void (*CombineFuncU) (uint32_t *dest, const uint32_t *src, int width);
typedef FASTCALL void (*CombineFuncC) (uint32_t *dest, uint32_t *src, uint32_t *mask, int width);
typedef FASTCALL void (*fetchProc)(bits_image_t *pict, int x, int y, int width,
uint32_t *buffer);
typedef FASTCALL uint32_t (*fetchPixelProc)(bits_image_t *pict, int offset, int line);
typedef FASTCALL void (*storeProc)(pixman_image_t *, uint32_t *bits,
const uint32_t *values, int x, int width,
const pixman_indexed_t *);
typedef struct _FbComposeData {
uint8_t op;
@ -183,32 +177,6 @@ void pixman_composite_rect_general_accessors (const FbComposeData *data,
void pixman_composite_rect_general (const FbComposeData *data,
uint32_t *scanline_buffer);
fetchProc pixman_fetchProcForPicture (bits_image_t *);
fetchPixelProc pixman_fetchPixelProcForPicture (bits_image_t *);
storeProc pixman_storeProcForPicture (bits_image_t *);
fetchProc pixman_fetchProcForPicture_accessors (bits_image_t *);
fetchPixelProc pixman_fetchPixelProcForPicture_accessors (bits_image_t *);
storeProc pixman_storeProcForPicture_accessors (bits_image_t *);
void pixmanFetchSourcePict(source_image_t *, int x, int y, int width,
uint32_t *buffer, uint32_t *mask, uint32_t maskBits);
void fbFetchTransformed(bits_image_t *, int x, int y, int width,
uint32_t *buffer, uint32_t *mask, uint32_t maskBits);
void fbStoreExternalAlpha(bits_image_t *, int x, int y, int width,
uint32_t *buffer);
void fbFetchExternalAlpha(bits_image_t *, int x, int y, int width,
uint32_t *buffer, uint32_t *mask, uint32_t maskBits);
void fbFetchTransformed_accessors(bits_image_t *, int x, int y, int width,
uint32_t *buffer, uint32_t *mask,
uint32_t maskBits);
void fbStoreExternalAlpha_accessors(bits_image_t *, int x, int y, int width,
uint32_t *buffer);
void fbFetchExternalAlpha_accessors(bits_image_t *, int x, int y, int width,
uint32_t *buffer, uint32_t *mask,
uint32_t maskBits);
/* end */
typedef enum
@ -333,7 +301,6 @@ union pixman_image
solid_fill_t solid;
};
#define LOG2_BITMAP_PAD 5
#define FB_STIP_SHIFT LOG2_BITMAP_PAD
#define FB_STIP_UNIT (1 << FB_STIP_SHIFT)
@ -706,6 +673,10 @@ union pixman_image
} \
} while (0)
/* FIXME */
#define fbPrepareAccess(x)
#define fbFinishAccess(x)
#else
#define READ(img, ptr) (*(ptr))
@ -714,7 +685,8 @@ union pixman_image
memcpy(dst, src, size)
#define MEMSET_WRAPPED(img, dst, val, size) \
memset(dst, val, size)
#define fbPrepareAccess(x)
#define fbFinishAccess(x)
#endif
#define fbComposeGetSolid(img, res, fmt) \
@ -839,12 +811,6 @@ pixman_rasterize_edges_accessors (pixman_image_t *image,
pixman_fixed_t t,
pixman_fixed_t b);
pixman_bool_t
pixman_image_is_opaque(pixman_image_t *image);
pixman_bool_t
pixman_image_can_get_solid (pixman_image_t *image);
#ifdef PIXMAN_TIMING

View File

@ -1,681 +0,0 @@
/*
*
* Copyright © 2000 Keith Packard, member of The XFree86 Project, Inc.
* 2005 Lars Knoll & Zack Rusin, Trolltech
*
* Permission to use, copy, modify, distribute, and sell this software and its
* documentation for any purpose is hereby granted without fee, provided that
* the above copyright notice appear in all copies and that both that
* copyright notice and this permission notice appear in supporting
* documentation, and that the name of Keith Packard not be used in
* advertising or publicity pertaining to distribution of the software without
* specific, written prior permission. Keith Packard makes no
* representations about the suitability of this software for any purpose. It
* is provided "as is" without express or implied warranty.
*
* THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS
* SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
* FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY
* SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
* AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
* SOFTWARE.
*/
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#include <math.h>
#include "pixman-private.h"
typedef struct
{
uint32_t left_ag;
uint32_t left_rb;
uint32_t right_ag;
uint32_t right_rb;
int32_t left_x;
int32_t right_x;
int32_t stepper;
pixman_gradient_stop_t *stops;
int num_stops;
unsigned int spread;
int need_reset;
} GradientWalker;
static void
_gradient_walker_init (GradientWalker *walker,
gradient_t *gradient,
unsigned int spread)
{
walker->num_stops = gradient->n_stops;
walker->stops = gradient->stops;
walker->left_x = 0;
walker->right_x = 0x10000;
walker->stepper = 0;
walker->left_ag = 0;
walker->left_rb = 0;
walker->right_ag = 0;
walker->right_rb = 0;
walker->spread = spread;
walker->need_reset = TRUE;
}
static void
_gradient_walker_reset (GradientWalker *walker,
pixman_fixed_32_32_t pos)
{
int32_t x, left_x, right_x;
pixman_color_t *left_c, *right_c;
int n, count = walker->num_stops;
pixman_gradient_stop_t * stops = walker->stops;
static const pixman_color_t transparent_black = { 0, 0, 0, 0 };
switch (walker->spread)
{
case PIXMAN_REPEAT_NORMAL:
x = (int32_t)pos & 0xFFFF;
for (n = 0; n < count; n++)
if (x < stops[n].x)
break;
if (n == 0) {
left_x = stops[count-1].x - 0x10000;
left_c = &stops[count-1].color;
} else {
left_x = stops[n-1].x;
left_c = &stops[n-1].color;
}
if (n == count) {
right_x = stops[0].x + 0x10000;
right_c = &stops[0].color;
} else {
right_x = stops[n].x;
right_c = &stops[n].color;
}
left_x += (pos - x);
right_x += (pos - x);
break;
case PIXMAN_REPEAT_PAD:
for (n = 0; n < count; n++)
if (pos < stops[n].x)
break;
if (n == 0) {
left_x = INT32_MIN;
left_c = &stops[0].color;
} else {
left_x = stops[n-1].x;
left_c = &stops[n-1].color;
}
if (n == count) {
right_x = INT32_MAX;
right_c = &stops[n-1].color;
} else {
right_x = stops[n].x;
right_c = &stops[n].color;
}
break;
case PIXMAN_REPEAT_REFLECT:
x = (int32_t)pos & 0xFFFF;
if ((int32_t)pos & 0x10000)
x = 0x10000 - x;
for (n = 0; n < count; n++)
if (x < stops[n].x)
break;
if (n == 0) {
left_x = -stops[0].x;
left_c = &stops[0].color;
} else {
left_x = stops[n-1].x;
left_c = &stops[n-1].color;
}
if (n == count) {
right_x = 0x20000 - stops[n-1].x;
right_c = &stops[n-1].color;
} else {
right_x = stops[n].x;
right_c = &stops[n].color;
}
if ((int32_t)pos & 0x10000) {
pixman_color_t *tmp_c;
int32_t tmp_x;
tmp_x = 0x10000 - right_x;
right_x = 0x10000 - left_x;
left_x = tmp_x;
tmp_c = right_c;
right_c = left_c;
left_c = tmp_c;
x = 0x10000 - x;
}
left_x += (pos - x);
right_x += (pos - x);
break;
default: /* RepeatNone */
for (n = 0; n < count; n++)
if (pos < stops[n].x)
break;
if (n == 0)
{
left_x = INT32_MIN;
right_x = stops[0].x;
left_c = right_c = (pixman_color_t*) &transparent_black;
}
else if (n == count)
{
left_x = stops[n-1].x;
right_x = INT32_MAX;
left_c = right_c = (pixman_color_t*) &transparent_black;
}
else
{
left_x = stops[n-1].x;
right_x = stops[n].x;
left_c = &stops[n-1].color;
right_c = &stops[n].color;
}
}
walker->left_x = left_x;
walker->right_x = right_x;
walker->left_ag = ((left_c->alpha >> 8) << 16) | (left_c->green >> 8);
walker->left_rb = ((left_c->red & 0xff00) << 8) | (left_c->blue >> 8);
walker->right_ag = ((right_c->alpha >> 8) << 16) | (right_c->green >> 8);
walker->right_rb = ((right_c->red & 0xff00) << 8) | (right_c->blue >> 8);
if ( walker->left_x == walker->right_x ||
( walker->left_ag == walker->right_ag &&
walker->left_rb == walker->right_rb ) )
{
walker->stepper = 0;
}
else
{
int32_t width = right_x - left_x;
walker->stepper = ((1 << 24) + width/2)/width;
}
walker->need_reset = FALSE;
}
#define GRADIENT_WALKER_NEED_RESET(w,x) \
( (w)->need_reset || (x) < (w)->left_x || (x) >= (w)->right_x)
/* the following assumes that GRADIENT_WALKER_NEED_RESET(w,x) is FALSE */
static uint32_t
_gradient_walker_pixel (GradientWalker *walker,
pixman_fixed_32_32_t x)
{
int dist, idist;
uint32_t t1, t2, a, color;
if (GRADIENT_WALKER_NEED_RESET (walker, x))
_gradient_walker_reset (walker, x);
dist = ((int)(x - walker->left_x)*walker->stepper) >> 16;
idist = 256 - dist;
/* combined INTERPOLATE and premultiply */
t1 = walker->left_rb*idist + walker->right_rb*dist;
t1 = (t1 >> 8) & 0xff00ff;
t2 = walker->left_ag*idist + walker->right_ag*dist;
t2 &= 0xff00ff00;
color = t2 & 0xff000000;
a = t2 >> 24;
t1 = t1*a + 0x800080;
t1 = (t1 + ((t1 >> 8) & 0xff00ff)) >> 8;
t2 = (t2 >> 8)*a + 0x800080;
t2 = (t2 + ((t2 >> 8) & 0xff00ff));
return (color | (t1 & 0xff00ff) | (t2 & 0xff00));
}
void pixmanFetchSourcePict(source_image_t * pict, int x, int y, int width,
uint32_t *buffer, uint32_t *mask, uint32_t maskBits)
{
#if 0
SourcePictPtr pGradient = pict->pSourcePict;
#endif
GradientWalker walker;
uint32_t *end = buffer + width;
gradient_t *gradient;
if (pict->common.type == SOLID)
{
register uint32_t color = ((solid_fill_t *)pict)->color;
while (buffer < end)
*(buffer++) = color;
return;
}
gradient = (gradient_t *)pict;
_gradient_walker_init (&walker, gradient, pict->common.repeat);
if (pict->common.type == LINEAR) {
pixman_vector_t v, unit;
pixman_fixed_32_32_t l;
pixman_fixed_48_16_t dx, dy, a, b, off;
linear_gradient_t *linear = (linear_gradient_t *)pict;
/* reference point is the center of the pixel */
v.vector[0] = pixman_int_to_fixed(x) + pixman_fixed_1/2;
v.vector[1] = pixman_int_to_fixed(y) + pixman_fixed_1/2;
v.vector[2] = pixman_fixed_1;
if (pict->common.transform) {
if (!pixman_transform_point_3d (pict->common.transform, &v))
return;
unit.vector[0] = pict->common.transform->matrix[0][0];
unit.vector[1] = pict->common.transform->matrix[1][0];
unit.vector[2] = pict->common.transform->matrix[2][0];
} else {
unit.vector[0] = pixman_fixed_1;
unit.vector[1] = 0;
unit.vector[2] = 0;
}
dx = linear->p2.x - linear->p1.x;
dy = linear->p2.y - linear->p1.y;
l = dx*dx + dy*dy;
if (l != 0) {
a = (dx << 32) / l;
b = (dy << 32) / l;
off = (-a*linear->p1.x - b*linear->p1.y)>>16;
}
if (l == 0 || (unit.vector[2] == 0 && v.vector[2] == pixman_fixed_1)) {
pixman_fixed_48_16_t inc, t;
/* affine transformation only */
if (l == 0) {
t = 0;
inc = 0;
} else {
t = ((a*v.vector[0] + b*v.vector[1]) >> 16) + off;
inc = (a * unit.vector[0] + b * unit.vector[1]) >> 16;
}
if (pict->class == SOURCE_IMAGE_CLASS_VERTICAL)
{
register uint32_t color;
color = _gradient_walker_pixel( &walker, t );
while (buffer < end)
*(buffer++) = color;
}
else
{
if (!mask) {
while (buffer < end)
{
*(buffer) = _gradient_walker_pixel (&walker, t);
buffer += 1;
t += inc;
}
} else {
while (buffer < end) {
if (*mask++ & maskBits)
{
*(buffer) = _gradient_walker_pixel (&walker, t);
}
buffer += 1;
t += inc;
}
}
}
}
else /* projective transformation */
{
pixman_fixed_48_16_t t;
if (pict->class == SOURCE_IMAGE_CLASS_VERTICAL)
{
register uint32_t color;
if (v.vector[2] == 0)
{
t = 0;
}
else
{
pixman_fixed_48_16_t x, y;
x = ((pixman_fixed_48_16_t) v.vector[0] << 16) / v.vector[2];
y = ((pixman_fixed_48_16_t) v.vector[1] << 16) / v.vector[2];
t = ((a * x + b * y) >> 16) + off;
}
color = _gradient_walker_pixel( &walker, t );
while (buffer < end)
*(buffer++) = color;
}
else
{
while (buffer < end)
{
if (!mask || *mask++ & maskBits)
{
if (v.vector[2] == 0) {
t = 0;
} else {
pixman_fixed_48_16_t x, y;
x = ((pixman_fixed_48_16_t)v.vector[0] << 16) / v.vector[2];
y = ((pixman_fixed_48_16_t)v.vector[1] << 16) / v.vector[2];
t = ((a*x + b*y) >> 16) + off;
}
*(buffer) = _gradient_walker_pixel (&walker, t);
}
++buffer;
v.vector[0] += unit.vector[0];
v.vector[1] += unit.vector[1];
v.vector[2] += unit.vector[2];
}
}
}
} else {
/*
* In the radial gradient problem we are given two circles (c,r) and
* (c,r) that define the gradient itself. Then, for any point p, we
* must compute the value(s) of t within [0.0, 1.0] representing the
* circle(s) that would color the point.
*
* There are potentially two values of t since the point p can be
* colored by both sides of the circle, (which happens whenever one
* circle is not entirely contained within the other).
*
* If we solve for a value of t that is outside of [0.0, 1.0] then we
* use the extend mode (NONE, REPEAT, REFLECT, or PAD) to map to a
* value within [0.0, 1.0].
*
* Here is an illustration of the problem:
*
* p
* p
*
* · r
* p ·
* θ
*
* r · c
* θ ·
*
* c
*
* Given (c,r), (c,r) and p, we must find an angle θ such that two
* points p and p on the two circles are collinear with p. Then, the
* desired value of t is the ratio of the length of pp to the length
* of pp.
*
* So, we have six unknown values: (px, py), (px, py), θ and t.
* We can also write six equations that constrain the problem:
*
* Point p is a distance r from c at an angle of θ:
*
* 1. px = cx + r·cos θ
* 2. py = cy + r·sin θ
*
* Point p is a distance r from c at an angle of θ:
*
* 3. px = cx + r2·cos θ
* 4. py = cy + r2·sin θ
*
* Point p lies at a fraction t along the line segment pp:
*
* 5. px = t·px + (1-t)·px
* 6. py = t·py + (1-t)·py
*
* To solve, first subtitute 1-4 into 5 and 6:
*
* px = t·(cx + r·cos θ) + (1-t)·(cx + r·cos θ)
* py = t·(cy + r·sin θ) + (1-t)·(cy + r·sin θ)
*
* Then solve each for cos θ and sin θ expressed as a function of t:
*
* cos θ = (-(cx - cx)·t + (px - cx)) / ((r-r)·t + r)
* sin θ = (-(cy - cy)·t + (py - cy)) / ((r-r)·t + r)
*
* To simplify this a bit, we define new variables for several of the
* common terms as shown below:
*
* p
* p
*
* · r
* p ·
* pdy
* c
* r ·
* · cdy
*
* c pdx cdx
*
* cdx = (cx - cx)
* cdy = (cy - cy)
* dr = r-r
* pdx = px - cx
* pdy = py - cy
*
* Note that cdx, cdy, and dr do not depend on point p at all, so can
* be pre-computed for the entire gradient. The simplifed equations
* are now:
*
* cos θ = (-cdx·t + pdx) / (dr·t + r)
* sin θ = (-cdy·t + pdy) / (dr·t + r)
*
* Finally, to get a single function of t and eliminate the last
* unknown θ, we use the identity sin²θ + cos²θ = 1. First, square
* each equation, (we knew a quadratic was coming since it must be
* possible to obtain two solutions in some cases):
*
* cos²θ = (cdx²t² - 2·cdx·pdx·t + pdx²) / (dr²·t² + 2·r·dr·t + r²)
* sin²θ = (cdy²t² - 2·cdy·pdy·t + pdy²) / (dr²·t² + 2·r·dr·t + r²)
*
* Then add both together, set the result equal to 1, and express as a
* standard quadratic equation in t of the form At² + Bt + C = 0
*
* (cdx² + cdy² - dr²)·t² - 2·(cdx·pdx + cdy·pdy + r·dr)·t + (pdx² + pdy² - r²) = 0
*
* In other words:
*
* A = cdx² + cdy² - dr²
* B = -2·(pdx·cdx + pdy·cdy + r·dr)
* C = pdx² + pdy² - r²
*
* And again, notice that A does not depend on p, so can be
* precomputed. From here we just use the quadratic formula to solve
* for t:
*
* t = (-2·B ± (B² - 4·A·C)) / 2·A
*/
/* radial or conical */
pixman_bool_t affine = TRUE;
double cx = 1.;
double cy = 0.;
double cz = 0.;
double rx = x + 0.5;
double ry = y + 0.5;
double rz = 1.;
if (pict->common.transform) {
pixman_vector_t v;
/* reference point is the center of the pixel */
v.vector[0] = pixman_int_to_fixed(x) + pixman_fixed_1/2;
v.vector[1] = pixman_int_to_fixed(y) + pixman_fixed_1/2;
v.vector[2] = pixman_fixed_1;
if (!pixman_transform_point_3d (pict->common.transform, &v))
return;
cx = pict->common.transform->matrix[0][0]/65536.;
cy = pict->common.transform->matrix[1][0]/65536.;
cz = pict->common.transform->matrix[2][0]/65536.;
rx = v.vector[0]/65536.;
ry = v.vector[1]/65536.;
rz = v.vector[2]/65536.;
affine = pict->common.transform->matrix[2][0] == 0 && v.vector[2] == pixman_fixed_1;
}
if (pict->common.type == RADIAL) {
radial_gradient_t *radial = (radial_gradient_t *)pict;
if (affine) {
while (buffer < end) {
if (!mask || *mask++ & maskBits)
{
double pdx, pdy;
double B, C;
double det;
double c1x = radial->c1.x / 65536.0;
double c1y = radial->c1.y / 65536.0;
double r1 = radial->c1.radius / 65536.0;
pixman_fixed_48_16_t t;
pdx = rx - c1x;
pdy = ry - c1y;
B = -2 * ( pdx * radial->cdx
+ pdy * radial->cdy
+ r1 * radial->dr);
C = (pdx * pdx + pdy * pdy - r1 * r1);
det = (B * B) - (4 * radial->A * C);
if (det < 0.0)
det = 0.0;
if (radial->A < 0)
t = (pixman_fixed_48_16_t) ((- B - sqrt(det)) / (2.0 * radial->A) * 65536);
else
t = (pixman_fixed_48_16_t) ((- B + sqrt(det)) / (2.0 * radial->A) * 65536);
*(buffer) = _gradient_walker_pixel (&walker, t);
}
++buffer;
rx += cx;
ry += cy;
}
} else {
/* projective */
while (buffer < end) {
if (!mask || *mask++ & maskBits)
{
double pdx, pdy;
double B, C;
double det;
double c1x = radial->c1.x / 65536.0;
double c1y = radial->c1.y / 65536.0;
double r1 = radial->c1.radius / 65536.0;
pixman_fixed_48_16_t t;
double x, y;
if (rz != 0) {
x = rx/rz;
y = ry/rz;
} else {
x = y = 0.;
}
pdx = x - c1x;
pdy = y - c1y;
B = -2 * ( pdx * radial->cdx
+ pdy * radial->cdy
+ r1 * radial->dr);
C = (pdx * pdx + pdy * pdy - r1 * r1);
det = (B * B) - (4 * radial->A * C);
if (det < 0.0)
det = 0.0;
if (radial->A < 0)
t = (pixman_fixed_48_16_t) ((- B - sqrt(det)) / (2.0 * radial->A) * 65536);
else
t = (pixman_fixed_48_16_t) ((- B + sqrt(det)) / (2.0 * radial->A) * 65536);
*(buffer) = _gradient_walker_pixel (&walker, t);
}
++buffer;
rx += cx;
ry += cy;
rz += cz;
}
}
} else /* SourcePictTypeConical */ {
conical_gradient_t *conical = (conical_gradient_t *)pict;
double a = conical->angle/(180.*65536);
if (affine) {
rx -= conical->center.x/65536.;
ry -= conical->center.y/65536.;
while (buffer < end) {
double angle;
if (!mask || *mask++ & maskBits)
{
pixman_fixed_48_16_t t;
angle = atan2(ry, rx) + a;
t = (pixman_fixed_48_16_t) (angle * (65536. / (2*M_PI)));
*(buffer) = _gradient_walker_pixel (&walker, t);
}
++buffer;
rx += cx;
ry += cy;
}
} else {
while (buffer < end) {
double x, y;
double angle;
if (!mask || *mask++ & maskBits)
{
pixman_fixed_48_16_t t;
if (rz != 0) {
x = rx/rz;
y = ry/rz;
} else {
x = y = 0.;
}
x -= conical->center.x/65536.;
y -= conical->center.y/65536.;
angle = atan2(y, x) + a;
t = (pixman_fixed_48_16_t) (angle * (65536. / (2*M_PI)));
*(buffer) = _gradient_walker_pixel (&walker, t);
}
++buffer;
rx += cx;
ry += cy;
rz += cz;
}
}
}
}
}

View File

@ -1,51 +0,0 @@
/*
* Copyright © 2008 Rodrigo Kumpera
*
* Permission to use, copy, modify, distribute, and sell this software and its
* documentation for any purpose is hereby granted without fee, provided that
* the above copyright notice appear in all copies and that both that
* copyright notice and this permission notice appear in supporting
* documentation, and that the name of Red Hat not be used in advertising or
* publicity pertaining to distribution of the software without specific,
* written prior permission. Red Hat makes no representations about the
* suitability of this software for any purpose. It is provided "as is"
* without express or implied warranty.
*
* THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS
* SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
* FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY
* SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
* AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
* SOFTWARE.
*
* Author: Rodrigo Kumpera (kumpera@gmail.com)
*
*/
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#include "pixman-sse.h"
#ifdef USE_SSE2
void
fbComposeSetupSSE(void)
{
static pixman_bool_t initialized = FALSE;
if (initialized)
return;
/* check if we have SSE2 support and initialize accordingly */
if (pixman_have_sse())
{
}
initialized = TRUE;
}
#endif /* USE_SSE2 */

View File

@ -1,53 +0,0 @@
/*
* Copyright © 2008 Rodrigo Kumpera
*
* Permission to use, copy, modify, distribute, and sell this software and its
* documentation for any purpose is hereby granted without fee, provided that
* the above copyright notice appear in all copies and that both that
* copyright notice and this permission notice appear in supporting
* documentation, and that the name of Red Hat not be used in advertising or
* publicity pertaining to distribution of the software without specific,
* written prior permission. Red Hat makes no representations about the
* suitability of this software for any purpose. It is provided "as is"
* without express or implied warranty.
*
* THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS
* SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
* FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY
* SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
* AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
* SOFTWARE.
*
* Author: Rodrigo Kumpera (kumpera@gmail.com)
*
*/
#ifndef _PIXMAN_SSE_H_
#define _PIXMAN_SSE_H_
#ifdef HAVE_DIX_CONFIG_H
#include <dix-config.h>
#endif
#include "pixman-private.h"
#ifdef USE_SSE2
#if !defined(__amd64__) && !defined(__x86_64__)
pixman_bool_t pixman_have_sse(void);
#else
#define pixman_have_sse() TRUE
#endif
#else
#define pixman_have_sse() FALSE
#endif
#ifdef USE_SSE2
void fbComposeSetupSSE(void);
#endif /* USE_SSE2 */
#endif /* _PIXMAN_SSE_H_ */

View File

@ -1,3 +0,0 @@
#define PIXMAN_FB_ACCESSORS
#include "pixman-transformed.c"

View File

@ -1,726 +0,0 @@
/*
*
* Copyright © 2000 Keith Packard, member of The XFree86 Project, Inc.
* 2005 Lars Knoll & Zack Rusin, Trolltech
*
* Permission to use, copy, modify, distribute, and sell this software and its
* documentation for any purpose is hereby granted without fee, provided that
* the above copyright notice appear in all copies and that both that
* copyright notice and this permission notice appear in supporting
* documentation, and that the name of Keith Packard not be used in
* advertising or publicity pertaining to distribution of the software without
* specific, written prior permission. Keith Packard makes no
* representations about the suitability of this software for any purpose. It
* is provided "as is" without express or implied warranty.
*
* THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS
* SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
* FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY
* SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
* AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
* SOFTWARE.
*/
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#include <stdlib.h>
#include "pixman-private.h"
#ifdef PIXMAN_FB_ACCESSORS
#define FETCH_PROC_FOR_PICTURE pixman_fetchProcForPicture_accessors
#define FETCH_PIXEL_PROC_FOR_PICTURE pixman_fetchPixelProcForPicture_accessors
#define STORE_PROC_FOR_PICTURE pixman_storeProcForPicture_accessors
#define FB_FETCH_TRANSFORMED fbFetchTransformed_accessors
#define FB_FETCH_EXTERNAL_ALPHA fbFetchExternalAlpha_accessors
#define FB_STORE_EXTERNAL_ALPHA fbStoreExternalAlpha_accessors
#else
#define FETCH_PROC_FOR_PICTURE pixman_fetchProcForPicture
#define FETCH_PIXEL_PROC_FOR_PICTURE pixman_fetchPixelProcForPicture
#define STORE_PROC_FOR_PICTURE pixman_storeProcForPicture
#define FB_FETCH_TRANSFORMED fbFetchTransformed
#define FB_FETCH_EXTERNAL_ALPHA fbFetchExternalAlpha
#define FB_STORE_EXTERNAL_ALPHA fbStoreExternalAlpha
#endif
/*
* Fetch from region strategies
*/
typedef FASTCALL uint32_t (*fetchFromRegionProc)(bits_image_t *pict, int x, int y, uint32_t *buffer, fetchPixelProc fetch, pixman_box16_t *box);
static inline uint32_t
fbFetchFromNoRegion(bits_image_t *pict, int x, int y, uint32_t *buffer, fetchPixelProc fetch, pixman_box16_t *box)
{
return fetch (pict, x, y);
}
static uint32_t
fbFetchFromNRectangles(bits_image_t *pict, int x, int y, uint32_t *buffer, fetchPixelProc fetch, pixman_box16_t *box)
{
pixman_box16_t box2;
if (pixman_region_contains_point (pict->common.src_clip, x, y, &box2))
return fbFetchFromNoRegion(pict, x, y, buffer, fetch, box);
else
return 0;
}
static uint32_t
fbFetchFromOneRectangle(bits_image_t *pict, int x, int y, uint32_t *buffer, fetchPixelProc fetch, pixman_box16_t *box)
{
pixman_box16_t box2 = *box;
return ((x < box2.x1) | (x >= box2.x2) | (y < box2.y1) | (y >= box2.y2)) ?
0 : fbFetchFromNoRegion(pict, x, y, buffer, fetch, box);
}
/*
* Fetching Algorithms
*/
static void
fbFetchTransformed_Nearest_Normal(bits_image_t * pict, int width, uint32_t *buffer, uint32_t *mask, uint32_t maskBits, pixman_bool_t affine, pixman_vector_t v, pixman_vector_t unit)
{
pixman_box16_t* box = NULL;
fetchPixelProc fetch;
fetchFromRegionProc fetchFromRegion;
int x, y, i;
/* initialize the two function pointers */
fetch = FETCH_PIXEL_PROC_FOR_PICTURE(pict);
if(pixman_region_n_rects (pict->common.src_clip) == 1)
fetchFromRegion = fbFetchFromNoRegion;
else
fetchFromRegion = fbFetchFromNRectangles;
for ( i = 0; i < width; ++i)
{
if (!mask || mask[i] & maskBits)
{
if (!v.vector[2])
{
*(buffer + i) = 0;
}
else
{
if (!affine)
{
y = MOD(DIV(v.vector[1],v.vector[2]), pict->height);
x = MOD(DIV(v.vector[0],v.vector[2]), pict->width);
}
else
{
y = MOD(v.vector[1]>>16, pict->height);
x = MOD(v.vector[0]>>16, pict->width);
}
*(buffer + i) = fetchFromRegion(pict, x, y, buffer, fetch, box);
}
}
v.vector[0] += unit.vector[0];
v.vector[1] += unit.vector[1];
v.vector[2] += unit.vector[2];
}
}
static void
fbFetchTransformed_Nearest_Pad(bits_image_t * pict, int width, uint32_t *buffer, uint32_t *mask, uint32_t maskBits, pixman_bool_t affine, pixman_vector_t v, pixman_vector_t unit)
{
pixman_box16_t *box = NULL;
fetchPixelProc fetch;
fetchFromRegionProc fetchFromRegion;
int x, y, i;
/* initialize the two function pointers */
fetch = FETCH_PIXEL_PROC_FOR_PICTURE(pict);
if(pixman_region_n_rects (pict->common.src_clip) == 1)
fetchFromRegion = fbFetchFromNoRegion;
else
fetchFromRegion = fbFetchFromNRectangles;
for (i = 0; i < width; ++i)
{
if (!mask || mask[i] & maskBits)
{
if (!v.vector[2])
{
*(buffer + i) = 0;
}
else
{
if (!affine)
{
y = CLIP(DIV(v.vector[1], v.vector[2]), 0, pict->height-1);
x = CLIP(DIV(v.vector[0], v.vector[2]), 0, pict->width-1);
}
else
{
y = CLIP(v.vector[1]>>16, 0, pict->height-1);
x = CLIP(v.vector[0]>>16, 0, pict->width-1);
}
*(buffer + i) = fetchFromRegion(pict, x, y, buffer, fetch, box);
}
}
v.vector[0] += unit.vector[0];
v.vector[1] += unit.vector[1];
v.vector[2] += unit.vector[2];
}
}
static void
fbFetchTransformed_Nearest_General(bits_image_t * pict, int width, uint32_t *buffer, uint32_t *mask, uint32_t maskBits, pixman_bool_t affine, pixman_vector_t v, pixman_vector_t unit)
{
pixman_box16_t *box = NULL;
fetchPixelProc fetch;
fetchFromRegionProc fetchFromRegion;
int x, y, i;
/* initialize the two function pointers */
fetch = FETCH_PIXEL_PROC_FOR_PICTURE(pict);
if(pixman_region_n_rects (pict->common.src_clip) == 1)
{
box = &(pict->common.src_clip->extents);
fetchFromRegion = fbFetchFromOneRectangle;
}
else
{
fetchFromRegion = fbFetchFromNRectangles;
}
for (i = 0; i < width; ++i) {
if (!mask || mask[i] & maskBits)
{
if (!v.vector[2]) {
*(buffer + i) = 0;
} else {
if (!affine) {
y = DIV(v.vector[1],v.vector[2]);
x = DIV(v.vector[0],v.vector[2]);
} else {
y = v.vector[1]>>16;
x = v.vector[0]>>16;
}
*(buffer + i) = fetchFromRegion(pict, x, y, buffer, fetch, box);
}
}
v.vector[0] += unit.vector[0];
v.vector[1] += unit.vector[1];
v.vector[2] += unit.vector[2];
}
}
static void
fbFetchTransformed_Bilinear_Normal(bits_image_t * pict, int width, uint32_t *buffer, uint32_t *mask, uint32_t maskBits, pixman_bool_t affine, pixman_vector_t v, pixman_vector_t unit)
{
pixman_box16_t *box = NULL;
fetchPixelProc fetch;
fetchFromRegionProc fetchFromRegion;
int i;
/* initialize the two function pointers */
fetch = FETCH_PIXEL_PROC_FOR_PICTURE(pict);
if(pixman_region_n_rects (pict->common.src_clip) == 1)
fetchFromRegion = fbFetchFromNoRegion;
else
fetchFromRegion = fbFetchFromNRectangles;
for (i = 0; i < width; ++i) {
if (!mask || mask[i] & maskBits)
{
if (!v.vector[2]) {
*(buffer + i) = 0;
} else {
int x1, x2, y1, y2, distx, idistx, disty, idisty;
uint32_t tl, tr, bl, br, r;
uint32_t ft, fb;
if (!affine) {
pixman_fixed_48_16_t div;
div = ((pixman_fixed_48_16_t)v.vector[0] << 16)/v.vector[2];
x1 = div >> 16;
distx = ((pixman_fixed_t)div >> 8) & 0xff;
div = ((pixman_fixed_48_16_t)v.vector[1] << 16)/v.vector[2];
y1 = div >> 16;
disty = ((pixman_fixed_t)div >> 8) & 0xff;
} else {
x1 = v.vector[0] >> 16;
distx = (v.vector[0] >> 8) & 0xff;
y1 = v.vector[1] >> 16;
disty = (v.vector[1] >> 8) & 0xff;
}
x2 = x1 + 1;
y2 = y1 + 1;
idistx = 256 - distx;
idisty = 256 - disty;
x1 = MOD (x1, pict->width);
x2 = MOD (x2, pict->width);
y1 = MOD (y1, pict->height);
y2 = MOD (y2, pict->height);
tl = fetchFromRegion(pict, x1, y1, buffer, fetch, box);
tr = fetchFromRegion(pict, x2, y1, buffer, fetch, box);
bl = fetchFromRegion(pict, x1, y2, buffer, fetch, box);
br = fetchFromRegion(pict, x2, y2, buffer, fetch, box);
ft = FbGet8(tl,0) * idistx + FbGet8(tr,0) * distx;
fb = FbGet8(bl,0) * idistx + FbGet8(br,0) * distx;
r = (((ft * idisty + fb * disty) >> 16) & 0xff);
ft = FbGet8(tl,8) * idistx + FbGet8(tr,8) * distx;
fb = FbGet8(bl,8) * idistx + FbGet8(br,8) * distx;
r |= (((ft * idisty + fb * disty) >> 8) & 0xff00);
ft = FbGet8(tl,16) * idistx + FbGet8(tr,16) * distx;
fb = FbGet8(bl,16) * idistx + FbGet8(br,16) * distx;
r |= (((ft * idisty + fb * disty)) & 0xff0000);
ft = FbGet8(tl,24) * idistx + FbGet8(tr,24) * distx;
fb = FbGet8(bl,24) * idistx + FbGet8(br,24) * distx;
r |= (((ft * idisty + fb * disty) << 8) & 0xff000000);
*(buffer + i) = r;
}
}
v.vector[0] += unit.vector[0];
v.vector[1] += unit.vector[1];
v.vector[2] += unit.vector[2];
}
}
static void
fbFetchTransformed_Bilinear_Pad(bits_image_t * pict, int width, uint32_t *buffer, uint32_t *mask, uint32_t maskBits, pixman_bool_t affine, pixman_vector_t v, pixman_vector_t unit)
{
pixman_box16_t *box = NULL;
fetchPixelProc fetch;
fetchFromRegionProc fetchFromRegion;
int i;
/* initialize the two function pointers */
fetch = FETCH_PIXEL_PROC_FOR_PICTURE(pict);
if(pixman_region_n_rects (pict->common.src_clip) == 1)
fetchFromRegion = fbFetchFromNoRegion;
else
fetchFromRegion = fbFetchFromNRectangles;
for (i = 0; i < width; ++i) {
if (!mask || mask[i] & maskBits)
{
if (!v.vector[2]) {
*(buffer + i) = 0;
} else {
int x1, x2, y1, y2, distx, idistx, disty, idisty;
uint32_t tl, tr, bl, br, r;
uint32_t ft, fb;
if (!affine) {
pixman_fixed_48_16_t div;
div = ((pixman_fixed_48_16_t)v.vector[0] << 16)/v.vector[2];
x1 = div >> 16;
distx = ((pixman_fixed_t)div >> 8) & 0xff;
div = ((pixman_fixed_48_16_t)v.vector[1] << 16)/v.vector[2];
y1 = div >> 16;
disty = ((pixman_fixed_t)div >> 8) & 0xff;
} else {
x1 = v.vector[0] >> 16;
distx = (v.vector[0] >> 8) & 0xff;
y1 = v.vector[1] >> 16;
disty = (v.vector[1] >> 8) & 0xff;
}
x2 = x1 + 1;
y2 = y1 + 1;
idistx = 256 - distx;
idisty = 256 - disty;
x1 = CLIP (x1, 0, pict->width-1);
x2 = CLIP (x2, 0, pict->width-1);
y1 = CLIP (y1, 0, pict->height-1);
y2 = CLIP (y2, 0, pict->height-1);
tl = fetchFromRegion(pict, x1, y1, buffer, fetch, box);
tr = fetchFromRegion(pict, x2, y1, buffer, fetch, box);
bl = fetchFromRegion(pict, x1, y2, buffer, fetch, box);
br = fetchFromRegion(pict, x2, y2, buffer, fetch, box);
ft = FbGet8(tl,0) * idistx + FbGet8(tr,0) * distx;
fb = FbGet8(bl,0) * idistx + FbGet8(br,0) * distx;
r = (((ft * idisty + fb * disty) >> 16) & 0xff);
ft = FbGet8(tl,8) * idistx + FbGet8(tr,8) * distx;
fb = FbGet8(bl,8) * idistx + FbGet8(br,8) * distx;
r |= (((ft * idisty + fb * disty) >> 8) & 0xff00);
ft = FbGet8(tl,16) * idistx + FbGet8(tr,16) * distx;
fb = FbGet8(bl,16) * idistx + FbGet8(br,16) * distx;
r |= (((ft * idisty + fb * disty)) & 0xff0000);
ft = FbGet8(tl,24) * idistx + FbGet8(tr,24) * distx;
fb = FbGet8(bl,24) * idistx + FbGet8(br,24) * distx;
r |= (((ft * idisty + fb * disty) << 8) & 0xff000000);
*(buffer + i) = r;
}
}
v.vector[0] += unit.vector[0];
v.vector[1] += unit.vector[1];
v.vector[2] += unit.vector[2];
}
}
static void
fbFetchTransformed_Bilinear_General(bits_image_t * pict, int width, uint32_t *buffer, uint32_t *mask, uint32_t maskBits, pixman_bool_t affine, pixman_vector_t v, pixman_vector_t unit)
{
pixman_box16_t *box = NULL;
fetchPixelProc fetch;
fetchFromRegionProc fetchFromRegion;
int i;
/* initialize the two function pointers */
fetch = FETCH_PIXEL_PROC_FOR_PICTURE(pict);
if(pixman_region_n_rects (pict->common.src_clip) == 1)
{
box = &(pict->common.src_clip->extents);
fetchFromRegion = fbFetchFromOneRectangle;
}
else
{
fetchFromRegion = fbFetchFromNRectangles;
}
for (i = 0; i < width; ++i)
{
if (!mask || mask[i] & maskBits)
{
if (!v.vector[2]) {
*(buffer + i) = 0;
} else {
int x1, x2, y1, y2, distx, idistx, disty, idisty;
uint32_t tl, tr, bl, br, r;
uint32_t ft, fb;
if (!affine) {
pixman_fixed_48_16_t div;
div = ((pixman_fixed_48_16_t)v.vector[0] << 16)/v.vector[2];
x1 = div >> 16;
distx = ((pixman_fixed_t)div >> 8) & 0xff;
div = ((pixman_fixed_48_16_t)v.vector[1] << 16)/v.vector[2];
y1 = div >> 16;
disty = ((pixman_fixed_t)div >> 8) & 0xff;
} else {
x1 = v.vector[0] >> 16;
distx = (v.vector[0] >> 8) & 0xff;
y1 = v.vector[1] >> 16;
disty = (v.vector[1] >> 8) & 0xff;
}
x2 = x1 + 1;
y2 = y1 + 1;
idistx = 256 - distx;
idisty = 256 - disty;
tl = fetchFromRegion(pict, x1, y1, buffer, fetch, box);
tr = fetchFromRegion(pict, x2, y1, buffer, fetch, box);
bl = fetchFromRegion(pict, x1, y2, buffer, fetch, box);
br = fetchFromRegion(pict, x2, y2, buffer, fetch, box);
ft = FbGet8(tl,0) * idistx + FbGet8(tr,0) * distx;
fb = FbGet8(bl,0) * idistx + FbGet8(br,0) * distx;
r = (((ft * idisty + fb * disty) >> 16) & 0xff);
ft = FbGet8(tl,8) * idistx + FbGet8(tr,8) * distx;
fb = FbGet8(bl,8) * idistx + FbGet8(br,8) * distx;
r |= (((ft * idisty + fb * disty) >> 8) & 0xff00);
ft = FbGet8(tl,16) * idistx + FbGet8(tr,16) * distx;
fb = FbGet8(bl,16) * idistx + FbGet8(br,16) * distx;
r |= (((ft * idisty + fb * disty)) & 0xff0000);
ft = FbGet8(tl,24) * idistx + FbGet8(tr,24) * distx;
fb = FbGet8(bl,24) * idistx + FbGet8(br,24) * distx;
r |= (((ft * idisty + fb * disty) << 8) & 0xff000000);
*(buffer + i) = r;
}
}
v.vector[0] += unit.vector[0];
v.vector[1] += unit.vector[1];
v.vector[2] += unit.vector[2];
}
}
static void
fbFetchTransformed_Convolution(bits_image_t * pict, int width, uint32_t *buffer, uint32_t *mask, uint32_t maskBits, pixman_bool_t affine, pixman_vector_t v, pixman_vector_t unit)
{
pixman_box16_t dummy;
fetchPixelProc fetch;
int i;
pixman_fixed_t *params = pict->common.filter_params;
int32_t cwidth = pixman_fixed_to_int(params[0]);
int32_t cheight = pixman_fixed_to_int(params[1]);
int xoff = (params[0] - pixman_fixed_1) >> 1;
int yoff = (params[1] - pixman_fixed_1) >> 1;
fetch = FETCH_PIXEL_PROC_FOR_PICTURE(pict);
params += 2;
for (i = 0; i < width; ++i) {
if (!mask || mask[i] & maskBits)
{
if (!v.vector[2]) {
*(buffer + i) = 0;
} else {
int x1, x2, y1, y2, x, y;
int32_t srtot, sgtot, sbtot, satot;
pixman_fixed_t *p = params;
if (!affine) {
pixman_fixed_48_16_t tmp;
tmp = ((pixman_fixed_48_16_t)v.vector[0] << 16)/v.vector[2] - xoff;
x1 = pixman_fixed_to_int(tmp);
tmp = ((pixman_fixed_48_16_t)v.vector[1] << 16)/v.vector[2] - yoff;
y1 = pixman_fixed_to_int(tmp);
} else {
x1 = pixman_fixed_to_int(v.vector[0] - xoff);
y1 = pixman_fixed_to_int(v.vector[1] - yoff);
}
x2 = x1 + cwidth;
y2 = y1 + cheight;
srtot = sgtot = sbtot = satot = 0;
for (y = y1; y < y2; y++) {
int ty;
switch (pict->common.repeat) {
case PIXMAN_REPEAT_NORMAL:
ty = MOD (y, pict->height);
break;
case PIXMAN_REPEAT_PAD:
ty = CLIP (y, 0, pict->height-1);
break;
default:
ty = y;
}
for (x = x1; x < x2; x++) {
if (*p) {
int tx;
switch (pict->common.repeat) {
case PIXMAN_REPEAT_NORMAL:
tx = MOD (x, pict->width);
break;
case PIXMAN_REPEAT_PAD:
tx = CLIP (x, 0, pict->width-1);
break;
default:
tx = x;
}
if (pixman_region_contains_point (pict->common.src_clip, tx, ty, &dummy)) {
uint32_t c = fetch(pict, tx, ty);
srtot += Red(c) * *p;
sgtot += Green(c) * *p;
sbtot += Blue(c) * *p;
satot += Alpha(c) * *p;
}
}
p++;
}
}
satot >>= 16;
srtot >>= 16;
sgtot >>= 16;
sbtot >>= 16;
if (satot < 0) satot = 0; else if (satot > 0xff) satot = 0xff;
if (srtot < 0) srtot = 0; else if (srtot > 0xff) srtot = 0xff;
if (sgtot < 0) sgtot = 0; else if (sgtot > 0xff) sgtot = 0xff;
if (sbtot < 0) sbtot = 0; else if (sbtot > 0xff) sbtot = 0xff;
*(buffer + i) = ((satot << 24) |
(srtot << 16) |
(sgtot << 8) |
(sbtot ));
}
}
v.vector[0] += unit.vector[0];
v.vector[1] += unit.vector[1];
v.vector[2] += unit.vector[2];
}
}
static void
adjust (pixman_vector_t *v, pixman_vector_t *u, pixman_fixed_t adjustment)
{
int delta_v = (adjustment * v->vector[2]) >> 16;
int delta_u = (adjustment * u->vector[2]) >> 16;
v->vector[0] += delta_v;
v->vector[1] += delta_v;
u->vector[0] += delta_u;
u->vector[1] += delta_u;
}
void
FB_FETCH_TRANSFORMED(bits_image_t * pict, int x, int y, int width, uint32_t *buffer, uint32_t *mask, uint32_t maskBits)
{
uint32_t *bits;
int32_t stride;
pixman_vector_t v;
pixman_vector_t unit;
pixman_bool_t affine = TRUE;
bits = pict->bits;
stride = pict->rowstride;
/* reference point is the center of the pixel */
v.vector[0] = pixman_int_to_fixed(x) + pixman_fixed_1 / 2;
v.vector[1] = pixman_int_to_fixed(y) + pixman_fixed_1 / 2;
v.vector[2] = pixman_fixed_1;
/* when using convolution filters or PIXMAN_REPEAT_PAD one might get here without a transform */
if (pict->common.transform)
{
if (!pixman_transform_point_3d (pict->common.transform, &v))
return;
unit.vector[0] = pict->common.transform->matrix[0][0];
unit.vector[1] = pict->common.transform->matrix[1][0];
unit.vector[2] = pict->common.transform->matrix[2][0];
affine = v.vector[2] == pixman_fixed_1 && unit.vector[2] == 0;
}
else
{
unit.vector[0] = pixman_fixed_1;
unit.vector[1] = 0;
unit.vector[2] = 0;
}
/* This allows filtering code to pretend that pixels are located at integer coordinates */
adjust (&v, &unit, -(pixman_fixed_1 / 2));
if (pict->common.filter == PIXMAN_FILTER_NEAREST || pict->common.filter == PIXMAN_FILTER_FAST)
{
/* Round down to closest integer, ensuring that 0.5 rounds to 0, not 1 */
adjust (&v, &unit, pixman_fixed_1 / 2 - pixman_fixed_e);
if (pict->common.repeat == PIXMAN_REPEAT_NORMAL)
{
fbFetchTransformed_Nearest_Normal(pict, width, buffer, mask, maskBits, affine, v, unit);
}
else if (pict->common.repeat == PIXMAN_REPEAT_PAD)
{
fbFetchTransformed_Nearest_Pad(pict, width, buffer, mask, maskBits, affine, v, unit);
}
else
{
fbFetchTransformed_Nearest_General(pict, width, buffer, mask, maskBits, affine, v, unit);
}
} else if (pict->common.filter == PIXMAN_FILTER_BILINEAR ||
pict->common.filter == PIXMAN_FILTER_GOOD ||
pict->common.filter == PIXMAN_FILTER_BEST)
{
if (pict->common.repeat == PIXMAN_REPEAT_NORMAL)
{
fbFetchTransformed_Bilinear_Normal(pict, width, buffer, mask, maskBits, affine, v, unit);
}
else if (pict->common.repeat == PIXMAN_REPEAT_PAD)
{
fbFetchTransformed_Bilinear_Pad(pict, width, buffer, mask, maskBits, affine, v, unit);
}
else
{
fbFetchTransformed_Bilinear_General(pict, width, buffer, mask, maskBits, affine, v, unit);
}
}
else if (pict->common.filter == PIXMAN_FILTER_CONVOLUTION)
{
/* Round to closest integer, ensuring that 0.5 rounds to 0, not 1 */
adjust (&v, &unit, pixman_fixed_1 / 2 - pixman_fixed_e);
fbFetchTransformed_Convolution(pict, width, buffer, mask, maskBits, affine, v, unit);
}
}
#define SCANLINE_BUFFER_LENGTH 2048
void
FB_FETCH_EXTERNAL_ALPHA(bits_image_t * pict, int x, int y, int width,
uint32_t *buffer, uint32_t *mask, uint32_t maskBits)
{
int i;
uint32_t _alpha_buffer[SCANLINE_BUFFER_LENGTH];
uint32_t *alpha_buffer = _alpha_buffer;
if (!pict->common.alpha_map) {
FB_FETCH_TRANSFORMED (pict, x, y, width, buffer, mask, maskBits);
return;
}
if (width > SCANLINE_BUFFER_LENGTH)
alpha_buffer = (uint32_t *) pixman_malloc_ab (width, sizeof(uint32_t));
FB_FETCH_TRANSFORMED(pict, x, y, width, buffer, mask, maskBits);
FB_FETCH_TRANSFORMED((bits_image_t *)pict->common.alpha_map, x - pict->common.alpha_origin.x,
y - pict->common.alpha_origin.y, width, alpha_buffer,
mask, maskBits);
for (i = 0; i < width; ++i) {
if (!mask || mask[i] & maskBits)
{
int a = alpha_buffer[i]>>24;
*(buffer + i) = (a << 24)
| (div_255(Red(*(buffer + i)) * a) << 16)
| (div_255(Green(*(buffer + i)) * a) << 8)
| (div_255(Blue(*(buffer + i)) * a));
}
}
if (alpha_buffer != _alpha_buffer)
free(alpha_buffer);
}
void
FB_STORE_EXTERNAL_ALPHA(bits_image_t * pict, int x, int y, int width,
uint32_t *buffer)
{
uint32_t *bits, *alpha_bits;
int32_t stride, astride;
int ax, ay;
storeProc store;
storeProc astore;
const pixman_indexed_t * indexed = pict->indexed;
const pixman_indexed_t * aindexed;
if (!pict->common.alpha_map) {
// XXX[AGP]: This should never happen!
// fbStore(pict, x, y, width, buffer);
abort();
return;
}
store = STORE_PROC_FOR_PICTURE(pict);
astore = STORE_PROC_FOR_PICTURE(pict->common.alpha_map);
aindexed = pict->common.alpha_map->indexed;
ax = x;
ay = y;
bits = pict->bits;
stride = pict->rowstride;
alpha_bits = pict->common.alpha_map->bits;
astride = pict->common.alpha_map->rowstride;
bits += y*stride;
alpha_bits += (ay - pict->common.alpha_origin.y)*astride;
store((pixman_image_t *)pict, bits, buffer, x, width, indexed);
astore((pixman_image_t *)pict->common.alpha_map,
alpha_bits, buffer, ax - pict->common.alpha_origin.x, width, aindexed);
}

View File

@ -49,7 +49,7 @@ pixman_add_traps (pixman_image_t * image,
height = image->bits.height;
bpp = PIXMAN_FORMAT_BPP (image->bits.format);
x_off_fixed = pixman_int_to_fixed(x_off);
x_off_fixed = pixman_int_to_fixed(y_off);
y_off_fixed = pixman_int_to_fixed(y_off);
while (ntrap--)
@ -83,6 +83,8 @@ pixman_add_traps (pixman_image_t * image,
}
traps++;
}
fbFinishAccess (pPicture->pDrawable);
}
static void

View File

@ -407,183 +407,3 @@ pixman_malloc_abc (unsigned int a,
else
return malloc (a * b * c);
}
/**
* pixman_version:
*
* Returns the version of the pixman library encoded in a single
* integer as per %PIXMAN_VERSION_ENCODE. The encoding ensures that
* later versions compare greater than earlier versions.
*
* A run-time comparison to check that pixman's version is greater than
* or equal to version X.Y.Z could be performed as follows:
*
* <informalexample><programlisting>
* if (pixman_version() >= PIXMAN_VERSION_ENCODE(X,Y,Z)) {...}
* </programlisting></informalexample>
*
* See also pixman_version_string() as well as the compile-time
* equivalents %PIXMAN_VERSION and %PIXMAN_VERSION_STRING.
*
* Return value: the encoded version.
**/
int
pixman_version (void)
{
return PIXMAN_VERSION;
}
/**
* pixman_version_string:
*
* Returns the version of the pixman library as a human-readable string
* of the form "X.Y.Z".
*
* See also pixman_version() as well as the compile-time equivalents
* %PIXMAN_VERSION_STRING and %PIXMAN_VERSION.
*
* Return value: a string containing the version.
**/
const char*
pixman_version_string (void)
{
return PIXMAN_VERSION_STRING;
}
/**
* pixman_format_supported_destination:
* @format: A pixman_format_code_t format
*
* Return value: whether the provided format code is a supported
* format for a pixman surface used as a destination in
* rendering.
*
* Currently, all pixman_format_code_t values are supported
* except for the YUV formats.
**/
pixman_bool_t
pixman_format_supported_destination (pixman_format_code_t format)
{
switch (format) {
/* 32 bpp formats */
case PIXMAN_a8r8g8b8:
case PIXMAN_x8r8g8b8:
case PIXMAN_a8b8g8r8:
case PIXMAN_x8b8g8r8:
case PIXMAN_r8g8b8:
case PIXMAN_b8g8r8:
case PIXMAN_r5g6b5:
case PIXMAN_b5g6r5:
/* 16 bpp formats */
case PIXMAN_a1r5g5b5:
case PIXMAN_x1r5g5b5:
case PIXMAN_a1b5g5r5:
case PIXMAN_x1b5g5r5:
case PIXMAN_a4r4g4b4:
case PIXMAN_x4r4g4b4:
case PIXMAN_a4b4g4r4:
case PIXMAN_x4b4g4r4:
/* 8bpp formats */
case PIXMAN_a8:
case PIXMAN_r3g3b2:
case PIXMAN_b2g3r3:
case PIXMAN_a2r2g2b2:
case PIXMAN_a2b2g2r2:
case PIXMAN_c8:
case PIXMAN_g8:
case PIXMAN_x4a4:
/* Collides with PIXMAN_c8
case PIXMAN_x4c4:
*/
/* Collides with PIXMAN_g8
case PIXMAN_x4g4:
*/
/* 4bpp formats */
case PIXMAN_a4:
case PIXMAN_r1g2b1:
case PIXMAN_b1g2r1:
case PIXMAN_a1r1g1b1:
case PIXMAN_a1b1g1r1:
case PIXMAN_c4:
case PIXMAN_g4:
/* 1bpp formats */
case PIXMAN_a1:
case PIXMAN_g1:
return TRUE;
/* YUV formats */
case PIXMAN_yuy2:
case PIXMAN_yv12:
default:
return FALSE;
}
}
/**
* pixman_format_supported_source:
* @format: A pixman_format_code_t format
*
* Return value: whether the provided format code is a supported
* format for a pixman surface used as a source in
* rendering.
*
* Currently, all pixman_format_code_t values are supported.
**/
pixman_bool_t
pixman_format_supported_source (pixman_format_code_t format)
{
switch (format) {
/* 32 bpp formats */
case PIXMAN_a8r8g8b8:
case PIXMAN_x8r8g8b8:
case PIXMAN_a8b8g8r8:
case PIXMAN_x8b8g8r8:
case PIXMAN_r8g8b8:
case PIXMAN_b8g8r8:
case PIXMAN_r5g6b5:
case PIXMAN_b5g6r5:
/* 16 bpp formats */
case PIXMAN_a1r5g5b5:
case PIXMAN_x1r5g5b5:
case PIXMAN_a1b5g5r5:
case PIXMAN_x1b5g5r5:
case PIXMAN_a4r4g4b4:
case PIXMAN_x4r4g4b4:
case PIXMAN_a4b4g4r4:
case PIXMAN_x4b4g4r4:
/* 8bpp formats */
case PIXMAN_a8:
case PIXMAN_r3g3b2:
case PIXMAN_b2g3r3:
case PIXMAN_a2r2g2b2:
case PIXMAN_a2b2g2r2:
case PIXMAN_c8:
case PIXMAN_g8:
case PIXMAN_x4a4:
/* Collides with PIXMAN_c8
case PIXMAN_x4c4:
*/
/* Collides with PIXMAN_g8
case PIXMAN_x4g4:
*/
/* 4bpp formats */
case PIXMAN_a4:
case PIXMAN_r1g2b1:
case PIXMAN_b1g2r1:
case PIXMAN_a1r1g1b1:
case PIXMAN_a1b1g1r1:
case PIXMAN_c4:
case PIXMAN_g4:
/* 1bpp formats */
case PIXMAN_a1:
case PIXMAN_g1:
/* YUV formats */
case PIXMAN_yuy2:
case PIXMAN_yv12:
return TRUE;
default:
return FALSE;
}
}

View File

@ -1,50 +0,0 @@
/*
* Copyright © 2008 Red Hat, Inc.
*
* Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software and associated documentation
* files (the "Software"), to deal in the Software without
* restriction, including without limitation the rights to use, copy,
* modify, merge, publish, distribute, sublicense, and/or sell copies
* of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*
* Author: Carl D. Worth <cworth@cworth.org>
*/
#ifndef PIXMAN_VERSION_H__
#define PIXMAN_VERSION_H__
#ifndef PIXMAN_H__
# error pixman-version.h should only be included by pixman.h
#endif
#define PIXMAN_VERSION_MAJOR 0
#define PIXMAN_VERSION_MINOR 10
#define PIXMAN_VERSION_MICRO 0
#define PIXMAN_VERSION_STRING "0.10.0"
#define PIXMAN_VERSION_ENCODE(major, minor, micro) ( \
((major) * 10000) \
+ ((minor) * 100) \
+ ((micro) * 1))
#define PIXMAN_VERSION PIXMAN_VERSION_ENCODE( \
PIXMAN_VERSION_MAJOR, \
PIXMAN_VERSION_MINOR, \
PIXMAN_VERSION_MICRO)
#endif /* PIXMAN_VERSION_H__ */

View File

@ -69,8 +69,6 @@ SOFTWARE.
#ifndef PIXMAN_H__
#define PIXMAN_H__
#include <pixman-version.h>
/*
* Standard integers
*/
@ -274,12 +272,6 @@ typedef enum
PIXMAN_REGION_PART
} pixman_region_overlap_t;
PIXMAN_EXPORT
int pixman_version (void);
PIXMAN_EXPORT
const char* pixman_version_string (void);
/* This function exists only to make it possible to preserve the X ABI - it should
* go away at first opportunity.
*/
@ -503,13 +495,6 @@ typedef enum {
PIXMAN_yv12 = PIXMAN_FORMAT(12,PIXMAN_TYPE_YV12,0,0,0,0),
} pixman_format_code_t;
/* Querying supported format values. */
PIXMAN_EXPORT
pixman_bool_t pixman_format_supported_destination (pixman_format_code_t format);
PIXMAN_EXPORT
pixman_bool_t pixman_format_supported_source (pixman_format_code_t format);
/* Constructors */
PIXMAN_EXPORT
pixman_image_t *pixman_image_create_solid_fill (pixman_color_t *color);
@ -563,6 +548,10 @@ pixman_bool_t pixman_image_set_filter (pixman_image_t
const pixman_fixed_t *filter_params,
int n_filter_params);
PIXMAN_EXPORT
void pixman_image_set_filter_params (pixman_image_t *image,
pixman_fixed_t *params,
int n_params);
PIXMAN_EXPORT
void pixman_image_set_source_clipping (pixman_image_t *image,
pixman_bool_t source_clipping);
PIXMAN_EXPORT

View File

@ -54,7 +54,7 @@
#include "gfxFontTest.h"
#include "gfxFontUtils.h"
#include "cairo-quartz.h"
#include "cairo-atsui.h"
#include "gfxQuartzSurface.h"
#include "gfxQuartzFontCache.h"
@ -116,7 +116,7 @@ gfxAtsuiFont::gfxAtsuiFont(MacOSFontEntry *aFontEntry,
InitMetrics(fontID, fontRef);
mFontFace = cairo_quartz_font_face_create_for_atsu_font_id(fontID);
mFontFace = cairo_atsui_font_face_create_for_atsu_font_id(fontID);
cairo_matrix_t sizeMatrix, ctm;
cairo_matrix_init_identity(&ctm);