зеркало из https://github.com/mozilla/pjs.git
backout [mq]: cairo-rollback.patch
This commit is contained in:
Родитель
7ffac589e5
Коммит
5202d05ee6
|
@ -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 (®);
|
||||
}
|
||||
|
||||
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 p₁p to the length
|
||||
* of p₁p₂.
|
||||
*
|
||||
* So, we have six unknown values: (p₁x, p₁y), (p₂x, p₂y), θ 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. p₁x = c₁x + r₁·cos θ
|
||||
* 2. p₁y = c₁y + r₁·sin θ
|
||||
*
|
||||
* Point p₂ is a distance r₂ from c₂ at an angle of θ:
|
||||
*
|
||||
* 3. p₂x = c₂x + r2·cos θ
|
||||
* 4. p₂y = c₂y + r2·sin θ
|
||||
*
|
||||
* Point p lies at a fraction t along the line segment p₁p₂:
|
||||
*
|
||||
* 5. px = t·p₂x + (1-t)·p₁x
|
||||
* 6. py = t·p₂y + (1-t)·p₁y
|
||||
*
|
||||
* To solve, first subtitute 1-4 into 5 and 6:
|
||||
*
|
||||
* px = t·(c₂x + r₂·cos θ) + (1-t)·(c₁x + r₁·cos θ)
|
||||
* py = t·(c₂y + r₂·sin θ) + (1-t)·(c₁y + r₁·sin θ)
|
||||
*
|
||||
* Then solve each for cos θ and sin θ expressed as a function of t:
|
||||
*
|
||||
* cos θ = (-(c₂x - c₁x)·t + (px - c₁x)) / ((r₂-r₁)·t + r₁)
|
||||
* sin θ = (-(c₂y - c₁y)·t + (py - c₁y)) / ((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 = (c₂x - c₁x)
|
||||
* cdy = (c₂y - c₁y)
|
||||
* dr = r₂-r₁
|
||||
* pdx = px - c₁x
|
||||
* pdy = py - c₁y
|
||||
*
|
||||
* 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);
|
||||
|
|
Загрузка…
Ссылка в новой задаче