backout [mq]: cairo-rollback.patch

This commit is contained in:
vladimir@pobox.com 2008-04-06 16:34:08 -07:00
Родитель 7ffac589e5
Коммит 5202d05ee6
68 изменённых файлов: 6269 добавлений и 7562 удалений

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

@ -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

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

@ -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 *****

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

@ -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

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

@ -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);
}

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

@ -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;

Разница между файлами не показана из-за своего большого размера Загрузить разницу

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

@ -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 */

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

@ -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"

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

@ -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

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

@ -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@

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

@ -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:

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

@ -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;
}

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

@ -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

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

@ -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);

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

@ -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)

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

@ -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,

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

@ -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,

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

@ -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);

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

@ -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;
}

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

@ -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)

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

@ -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;

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

@ -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);

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

@ -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));

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

@ -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");

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

@ -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);
}

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

@ -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 */

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

@ -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.
*

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

@ -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 */

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

@ -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;

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

@ -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;

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

@ -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;
}

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

@ -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;

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

@ -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;

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

@ -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);

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

@ -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;

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

@ -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"

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

@ -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) {

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

@ -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,

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

@ -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;

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

@ -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;

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

@ -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 */

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

@ -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;
}

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

@ -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 {

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

@ -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);

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

@ -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);
}

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

@ -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)

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

@ -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.
**/

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

@ -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);

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

@ -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

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

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

Разница между файлами не показана из-за своего большого размера Загрузить разницу

Разница между файлами не показана из-за своего большого размера Загрузить разницу

Разница между файлами не показана из-за своего большого размера Загрузить разницу

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

@ -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;
}

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

@ -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);

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

@ -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_ */

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

@ -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

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

@ -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

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

@ -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;
}
}
}
}
}

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

@ -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 */

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

@ -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_ */

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

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

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

@ -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);
}

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

@ -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

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

@ -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;
}
}

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

@ -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__ */

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

@ -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

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

@ -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);