b=453765; Upgrade cairo to 1.7.4-136-g5ea2555; r=me

--HG--
rename : gfx/cairo/libpixman/src/pixman-sse.c => gfx/cairo/libpixman/src/pixman-sse2.c
rename : gfx/cairo/libpixman/src/pixman-sse.h => gfx/cairo/libpixman/src/pixman-sse2.h
This commit is contained in:
Vladimir Vukicevic 2008-09-04 21:44:42 -07:00
Родитель edf086ccfa
Коммит fb36f5d923
89 изменённых файлов: 3463 добавлений и 1390 удалений

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

@ -7,8 +7,8 @@ http://www.cairographics.org/.
VERSIONS:
cairo (1.6.4-350-g1a9809b)
pixman (pixman-0.11.8-7-gdb3fb5e)
cairo (1.7.4-136-g5ea2555)
pixman (pixman-0.11.8-17-gf9d3f37)
***** NOTE FOR VISUAL C++ 6.0 *****

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

@ -0,0 +1,26 @@
diff --git a/gfx/cairo/cairo/src/cairo-version.c b/gfx/cairo/cairo/src/cairo-version.c
--- a/gfx/cairo/cairo/src/cairo-version.c
+++ b/gfx/cairo/cairo/src/cairo-version.c
@@ -42,7 +42,7 @@
/* get the "real" version info instead of dummy cairo-version.h */
#undef CAIRO_VERSION_H
-#include "../cairo-version.h"
+#include "cairo-features.h"
/**
* cairo_version:
diff --git a/gfx/cairo/cairo/src/cairo-version.h b/gfx/cairo/cairo/src/cairo-version.h
--- a/gfx/cairo/cairo/src/cairo-version.h
+++ b/gfx/cairo/cairo/src/cairo-version.h
@@ -7,8 +7,10 @@
#ifndef CAIRO_VERSION_H
#define CAIRO_VERSION_H
+#if 0
#define CAIRO_VERSION_MAJOR USE_cairo_version_OR_cairo_version_string_INSTEAD
#define CAIRO_VERSION_MINOR USE_cairo_version_OR_cairo_version_string_INSTEAD
#define CAIRO_VERSION_MICRO USE_cairo_version_OR_cairo_version_string_INSTEAD
+#endif
#endif

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

@ -119,10 +119,11 @@ CSRCS = \
cairo-traps.c \
cairo-unicode.c \
cairo-user-font.c \
cairo-version.c \
cairo-wideint.c \
$(NULL)
EXPORTS = cairo.h cairo-features.h cairo-platform.h cairo-deprecated.h cairo-rename.h
EXPORTS = cairo.h cairo-version.h cairo-features.h cairo-platform.h cairo-deprecated.h cairo-rename.h
# cairo-type1-subset.c should be here, but it's only supported on freetype platforms

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

@ -621,7 +621,7 @@ _cairo_analysis_surface_has_show_text_glyphs (void *abstract_surface)
{
cairo_analysis_surface_t *surface = abstract_surface;
return _cairo_surface_has_show_text_glyphs (surface->target);
return cairo_surface_has_show_text_glyphs (surface->target);
}
static cairo_int_status_t

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

@ -239,22 +239,21 @@ _cairo_cache_lookup (cairo_cache_t *cache,
*
* Remove a random entry from the cache.
*
* Return value: %CAIRO_STATUS_SUCCESS if an entry was successfully
* removed. %CAIRO_INT_STATUS_CACHE_EMPTY if there are no entries that
* can be removed.
* Return value: %TRUE if an entry was successfully removed.
* %FALSE if there are no entries that can be removed.
**/
static cairo_int_status_t
static cairo_bool_t
_cairo_cache_remove_random (cairo_cache_t *cache)
{
cairo_cache_entry_t *entry;
entry = _cairo_hash_table_random_entry (cache->hash_table, NULL);
if (entry == NULL)
return CAIRO_INT_STATUS_CACHE_EMPTY;
return FALSE;
_cairo_cache_remove (cache, entry);
return CAIRO_STATUS_SUCCESS;
return TRUE;
}
/**
@ -269,20 +268,14 @@ _cairo_cache_remove_random (cairo_cache_t *cache)
**/
static void
_cairo_cache_shrink_to_accommodate (cairo_cache_t *cache,
unsigned long additional)
unsigned long additional)
{
cairo_int_status_t status;
if (cache->freeze_count)
return;
while (cache->size + additional > cache->max_size) {
status = _cairo_cache_remove_random (cache);
if (status) {
if (status == CAIRO_INT_STATUS_CACHE_EMPTY)
return;
ASSERT_NOT_REACHED;
}
if (! _cairo_cache_remove_random (cache))
return;
}
}

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

@ -41,6 +41,9 @@
#define _BSD_SOURCE /* for snprintf(), strdup() */
#include "cairoint.h"
#if CAIRO_HAS_FONT_SUBSET
#include "cairo-scaled-font-subsets-private.h"
#include "cairo-truetype-subset-private.h"
#include <string.h>
@ -2282,3 +2285,5 @@ _cairo_cff_fallback_fini (cairo_cff_subset_t *subset)
free (subset->widths);
free (subset->data);
}
#endif /* CAIRO_HAS_FONT_SUBSET */

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

@ -36,8 +36,11 @@
#ifndef CAIRO_CLIP_PRIVATE_H
#define CAIRO_CLIP_PRIVATE_H
#include "cairo-types-private.h"
#include "cairo-compiler-private.h"
#include "cairo-path-fixed-private.h"
#include "cairo-reference-count-private.h"
#include "cairo-region-private.h"
extern const cairo_private cairo_rectangle_list_t _cairo_rectangles_nil;

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

@ -59,7 +59,7 @@ _cairo_clip_init (cairo_clip_t *clip, cairo_surface_t *target)
clip->surface = NULL;
clip->surface_rect.x = 0;
clip->surface_rect.y = 0;
clip->surface_rect.width = 0;
clip->surface_rect.width = 0;
clip->surface_rect.height = 0;
clip->serial = 0;
@ -86,6 +86,7 @@ _cairo_clip_init_copy (cairo_clip_t *clip, cairo_clip_t *other)
if (other->has_region) {
cairo_status_t status;
status = _cairo_region_copy (&clip->region, &other->region);
if (status) {
_cairo_region_fini (&clip->region);
@ -380,14 +381,13 @@ _cairo_clip_intersect_region (cairo_clip_t *clip,
if (status)
return status;
status = CAIRO_STATUS_SUCCESS;
if (!clip->has_region) {
status = _cairo_region_copy (&clip->region, &region);
if (status == CAIRO_STATUS_SUCCESS)
clip->has_region = TRUE;
} else {
cairo_region_t intersection;
_cairo_region_init (&intersection);
status = _cairo_region_intersect (&intersection,
@ -727,7 +727,7 @@ _cairo_clip_int_rect_to_user (cairo_gstate_t *gstate,
user_rect->x = x1;
user_rect->y = y1;
user_rect->width = x2 - x1;
user_rect->width = x2 - x1;
user_rect->height = y2 - y1;
return is_tight;
@ -764,9 +764,12 @@ _cairo_clip_copy_rectangle_list (cairo_clip_t *clip, cairo_gstate_t *gstate)
}
for (i = 0; i < n_boxes; ++i) {
cairo_rectangle_int_t clip_rect = { boxes[i].p1.x, boxes[i].p1.y,
boxes[i].p2.x - boxes[i].p1.x,
boxes[i].p2.y - boxes[i].p1.y };
cairo_rectangle_int_t clip_rect;
clip_rect.x = boxes[i].p1.x;
clip_rect.y = boxes[i].p1.y;
clip_rect.width = boxes[i].p2.x - boxes[i].p1.x;
clip_rect.height = boxes[i].p2.y - boxes[i].p1.y;
if (!_cairo_clip_int_rect_to_user(gstate, &clip_rect, &rectangles[i])) {
_cairo_error_throw (CAIRO_STATUS_CLIP_NOT_REPRESENTABLE);

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

@ -38,7 +38,9 @@
#ifndef CAIRO_COMPILER_PRIVATE_H
#define CAIRO_COMPILER_PRIVATE_H
CAIRO_BEGIN_DECLS
#if HAVE_CONFIG_H
#include "config.h"
#endif
#if __GNUC__ >= 3 && defined(__ELF__) && !defined(__sun)
# define slim_hidden_proto(name) slim_hidden_proto1(name, slim_hidden_int_name(name)) cairo_private
@ -108,6 +110,7 @@ CAIRO_BEGIN_DECLS
#endif
#ifndef __GNUC__
#undef __attribute__
#define __attribute__(x)
#endif
@ -125,6 +128,4 @@ CAIRO_BEGIN_DECLS
#define inline __inline__
#endif
CAIRO_END_DECLS
#endif

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

@ -63,7 +63,7 @@
/*
* CompositeTrapezoids works (without antialiasing).
*/
#define DFB_COMPOSITE_TRAPEZOIDS 0
#define DFB_COMPOSITE_TRAPEZOIDS 1
/*
* ShowGlyphs works fine.
@ -71,7 +71,11 @@
#define DFB_SHOW_GLYPHS 1
D_DEBUG_DOMAIN (Cairo_DirectFB, "Cairo/DirectFB", "Cairo DirectFB backend");
D_DEBUG_DOMAIN( CairoDFB_Acquire, "CairoDFB/Acquire", "Cairo DirectFB Acquire" );
D_DEBUG_DOMAIN( CairoDFB_Clip, "CairoDFB/Clip", "Cairo DirectFB Clipping" );
D_DEBUG_DOMAIN( CairoDFB_Font, "CairoDFB/Font", "Cairo DirectFB Font Rendering" );
D_DEBUG_DOMAIN( CairoDFB_Render, "CairoDFB/Render", "Cairo DirectFB Rendering" );
D_DEBUG_DOMAIN( CairoDFB_Surface, "CairoDFB/Surface", "Cairo DirectFB Surface" );
/*****************************************************************************/
@ -339,7 +343,7 @@ _directfb_acquire_surface (cairo_directfb_surface_t *surface,
cairo_format_t cairo_format;
void *data;
int pitch;
if (surface->format == (cairo_format_t) -1) {
DFBSurfaceCapabilities caps;
@ -366,7 +370,7 @@ _directfb_acquire_surface (cairo_directfb_surface_t *surface,
cairo_format = _cairo_format_from_content (surface->content);
if (!surface->tmpsurface) {
D_DEBUG_AT (Cairo_DirectFB, "Allocating buffer for surface %p.\n", surface);
D_DEBUG_AT (CairoDFB_Acquire, "Allocating buffer for surface %p.\n", surface);
surface->tmpsurface =
_directfb_buffer_surface_create (surface->dfb,
@ -377,13 +381,13 @@ _directfb_acquire_surface (cairo_directfb_surface_t *surface,
}
buffer = surface->tmpsurface;
surface->dfbsurface->GetCapabilities (surface->dfbsurface, &caps);
/* surface->dfbsurface->GetCapabilities (surface->dfbsurface, &caps);
if (caps & DSCAPS_FLIPPING) {
DFBRegion region = { .x1 = source_rect.x, .y1 = source_rect.y,
.x2 = source_rect.x + source_rect.w - 1,
.y2 = source_rect.y + source_rect.h - 1 };
surface->dfbsurface->Flip (surface->dfbsurface, &region, DSFLIP_BLIT);
}
} */
buffer->Blit (buffer, surface->dfbsurface, &source_rect, 0, 0);
}
else {
@ -396,7 +400,7 @@ _directfb_acquire_surface (cairo_directfb_surface_t *surface,
*image_extra = buffer;
if (buffer->Lock (buffer, lock_flags, &data, &pitch)) {
D_DEBUG_AT (Cairo_DirectFB, "Couldn't lock surface!\n");
D_DEBUG_AT (CairoDFB_Acquire, "Couldn't lock surface!\n");
goto ERROR;
}
@ -443,7 +447,7 @@ _cairo_directfb_surface_create_similar (void *abstract_src,
cairo_directfb_surface_t *surface;
cairo_format_t format;
D_DEBUG_AT (Cairo_DirectFB,
D_DEBUG_AT (CairoDFB_Surface,
"%s( src=%p, content=0x%x, width=%d, height=%d).\n",
__FUNCTION__, source, content, width, height);
@ -497,8 +501,7 @@ _cairo_directfb_surface_finish (void *data)
{
cairo_directfb_surface_t *surface = (cairo_directfb_surface_t *)data;
D_DEBUG_AT (Cairo_DirectFB,
"%s( surface=%p ).\n", __FUNCTION__, surface);
D_DEBUG_AT (CairoDFB_Surface, "%s( surface=%p ).\n", __FUNCTION__, surface);
if (surface->clips) {
free (surface->clips);
@ -534,7 +537,7 @@ _cairo_directfb_surface_acquire_source_image (void *abstract_s
{
cairo_directfb_surface_t *surface = abstract_surface;
D_DEBUG_AT (Cairo_DirectFB,
D_DEBUG_AT (CairoDFB_Acquire,
"%s( surface=%p ).\n", __FUNCTION__, surface);
return _directfb_acquire_surface (surface, NULL, image_out,
@ -549,7 +552,7 @@ _cairo_directfb_surface_release_source_image (void *abstract_su
cairo_directfb_surface_t *surface = abstract_surface;
IDirectFBSurface *buffer = image_extra;
D_DEBUG_AT (Cairo_DirectFB,
D_DEBUG_AT (CairoDFB_Acquire,
"%s( surface=%p ).\n", __FUNCTION__, surface);
buffer->Unlock (buffer);
@ -566,13 +569,13 @@ _cairo_directfb_surface_acquire_dest_image (void *abstract_s
{
cairo_directfb_surface_t *surface = abstract_surface;
D_DEBUG_AT (Cairo_DirectFB,
"%s( surface=%p, interest_rect={ %d %d %d %d } ).\n",
__FUNCTION__, surface,
D_DEBUG_AT (CairoDFB_Acquire,
"%s( surface=%p (%dx%d), interest_rect={ %u %u %u %u } ).\n",
__FUNCTION__, surface, surface->width, surface->height,
interest_rect ? interest_rect->x : 0,
interest_rect ? interest_rect->y : 0,
interest_rect ? interest_rect->width : surface->width,
interest_rect ? interest_rect->height : surface->height);
interest_rect ? interest_rect->width : (unsigned) surface->width,
interest_rect ? interest_rect->height : (unsigned) surface->height);
return _directfb_acquire_surface (surface, interest_rect, image_out,
image_rect_out, image_extra, DSLF_READ | DSLF_WRITE);
@ -588,7 +591,7 @@ _cairo_directfb_surface_release_dest_image (void *abstract_surf
cairo_directfb_surface_t *surface = abstract_surface;
IDirectFBSurface *buffer = image_extra;
D_DEBUG_AT (Cairo_DirectFB,
D_DEBUG_AT (CairoDFB_Acquire,
"%s( surface=%p ).\n", __FUNCTION__, surface);
buffer->Unlock (buffer);
@ -618,7 +621,7 @@ _cairo_directfb_surface_clone_similar (void *abstract_surface,
cairo_directfb_surface_t *surface = abstract_surface;
cairo_directfb_surface_t *clone;
D_DEBUG_AT (Cairo_DirectFB,
D_DEBUG_AT (CairoDFB_Surface,
"%s( surface=%p, src=%p ).\n", __FUNCTION__, surface, src);
if (src->backend == surface->base.backend) {
@ -726,7 +729,7 @@ _directfb_prepare_composite (cairo_directfb_surface_t *dst,
sblend == DSBF_INVDESTALPHA) /* Doesn't work correctly */
return CAIRO_INT_STATUS_UNSUPPORTED;
D_DEBUG_AT (Cairo_DirectFB, "Replacing src pattern by mask pattern.\n");
D_DEBUG_AT (CairoDFB_Render, "Replacing src pattern by mask pattern.\n");
tmp = src_pattern;
tmp_x = *src_x; tmp_y = *src_y;
@ -883,7 +886,7 @@ _cairo_directfb_surface_composite (cairo_operator_t op,
DFBAccelerationMask accel, mask;
cairo_int_status_t ret;
D_DEBUG_AT (Cairo_DirectFB,
D_DEBUG_AT (CairoDFB_Render,
"%s( op=%d, src_pattern=%p, mask_pattern=%p, dst=%p,"
" src_x=%d, src_y=%d, mask_x=%d, mask_y=%d, dst_x=%d,"
" dst_y=%d, width=%u, height=%u ).\n",
@ -900,7 +903,7 @@ _cairo_directfb_surface_composite (cairo_operator_t op,
dst->dfbsurface->GetAccelerationMask (dst->dfbsurface, src->dfbsurface, &mask);
if (!(mask & accel)) {
D_DEBUG_AT (Cairo_DirectFB, "No acceleration (%08x)!\n", accel);
D_DEBUG_AT (CairoDFB_Render, "No acceleration (%08x)!\n", accel);
if (accel != DFXL_BLIT) {
_directfb_finish_composite (dst, src_pattern, &src->base, &src_attr);
return CAIRO_INT_STATUS_UNSUPPORTED;
@ -920,7 +923,7 @@ _cairo_directfb_surface_composite (cairo_operator_t op,
sr.h = height;
if (src_attr.extend == CAIRO_EXTEND_NONE) {
D_DEBUG_AT (Cairo_DirectFB, "Running Blit().\n");
D_DEBUG_AT (CairoDFB_Render, "Running Blit().\n");
RUN_CLIPPED( dst, NULL,
dst->dfbsurface->Blit (dst->dfbsurface,
@ -934,7 +937,7 @@ _cairo_directfb_surface_composite (cairo_operator_t op,
clip.x2 = dst_x + width - 1;
clip.y2 = dst_y + height - 1;
D_DEBUG_AT (Cairo_DirectFB, "Running TileBlit().\n");
D_DEBUG_AT (CairoDFB_Render, "Running TileBlit().\n");
RUN_CLIPPED( dst, &clip,
dst->dfbsurface->TileBlit (dst->dfbsurface,
@ -961,7 +964,7 @@ _cairo_directfb_surface_composite (cairo_operator_t op,
dr.w = width;
dr.h = height;
D_DEBUG_AT (Cairo_DirectFB, "Running StretchBlit().\n");
D_DEBUG_AT (CairoDFB_Render, "Running StretchBlit().\n");
RUN_CLIPPED (dst, NULL,
dst->dfbsurface->StretchBlit (dst->dfbsurface,
@ -1019,7 +1022,7 @@ _cairo_directfb_surface_composite (cairo_operator_t op,
clip.x2 = dst_x + width - 1;
clip.y2 = dst_y + height - 1;
D_DEBUG_AT (Cairo_DirectFB, "Running TextureTriangles().\n");
D_DEBUG_AT (CairoDFB_Render, "Running TextureTriangles().\n");
RUN_CLIPPED (dst, &clip,
dst->dfbsurface->TextureTriangles (dst->dfbsurface,
@ -1052,7 +1055,7 @@ _cairo_directfb_surface_fill_rectangles (void *abstract_surface
DFBRectangle r[n_rects];
int i;
D_DEBUG_AT (Cairo_DirectFB,
D_DEBUG_AT (CairoDFB_Render,
"%s( dst=%p, op=%d, color=%p, rects=%p, n_rects=%d ).\n",
__FUNCTION__, dst, op, color, rects, n_rects);
@ -1128,7 +1131,7 @@ _cairo_directfb_surface_composite_trapezoids (cairo_operator_t op,
cairo_status_t ret;
DFBAccelerationMask accel;
D_DEBUG_AT (Cairo_DirectFB,
D_DEBUG_AT (CairoDFB_Render,
"%s( op=%d, pattern=%p, dst=%p, antialias=%d,"
" src_x=%d, src_y=%d, dst_x=%d, dst_y=%d,"
" width=%u, height=%u, traps=%p, num_traps=%d ).\n",
@ -1235,7 +1238,7 @@ _cairo_directfb_surface_composite_trapezoids (cairo_operator_t op,
#undef ADD_TRI
D_DEBUG_AT (Cairo_DirectFB, "Running TextureTriangles().\n");
D_DEBUG_AT (CairoDFB_Render, "Running TextureTriangles().\n");
RUN_CLIPPED (dst, NULL,
dst->dfbsurface->TextureTriangles (dst->dfbsurface, src->dfbsurface,
@ -1256,7 +1259,7 @@ _cairo_directfb_surface_set_clip_region (void *abstract_surface,
{
cairo_directfb_surface_t *surface = abstract_surface;
D_DEBUG_AT (Cairo_DirectFB,
D_DEBUG_AT (CairoDFB_Clip,
"%s( surface=%p, region=%p ).\n",
__FUNCTION__, surface, region);
@ -1267,6 +1270,8 @@ _cairo_directfb_surface_set_clip_region (void *abstract_surface,
int i;
status = _cairo_region_get_boxes (region, &n_boxes, &boxes);
if (n_boxes == 0)
return CAIRO_STATUS_SUCCESS;
if (status)
return status;
@ -1310,7 +1315,7 @@ _cairo_directfb_abstract_surface_get_extents (void *abstract_su
{
cairo_directfb_surface_t *surface = abstract_surface;
D_DEBUG_AT (Cairo_DirectFB,
D_DEBUG_AT (CairoDFB_Surface,
"%s( surface=%p, rectangle=%p ).\n",
__FUNCTION__, surface, rectangle);
@ -1379,21 +1384,29 @@ _directfb_acquire_font_cache (cairo_directfb_surface_t *surface,
int h = 8;
int i;
D_DEBUG_AT (CairoDFB_Font, "%s( %p [%d] )\n", __FUNCTION__, glyphs, num_glyphs );
if (scaled_font->surface_private) {
cache = scaled_font->surface_private;
x = cache->x;
y = cache->y;
}
_cairo_cache_freeze( scaled_font->glyphs );
for (i = 0; i < num_glyphs; i++) {
cairo_scaled_glyph_t *scaled_glyph;
cairo_image_surface_t *img;
D_DEBUG_AT (CairoDFB_Font, " -> [%2d] = %4lu\n", i, glyphs[i].index );
ret = _cairo_scaled_glyph_lookup (scaled_font, glyphs[i].index,
CAIRO_SCALED_GLYPH_INFO_SURFACE,
&scaled_glyph);
if (ret)
if (ret) {
_cairo_cache_thaw( scaled_font->glyphs );
return ret;
}
img = scaled_glyph->surface;
switch (img->format) {
@ -1402,19 +1415,26 @@ _directfb_acquire_font_cache (cairo_directfb_surface_t *surface,
case CAIRO_FORMAT_ARGB32:
break;
default:
D_DEBUG_AT (Cairo_DirectFB,
"Unsupported font format %d!\n", img->format);
D_DEBUG_AT (CairoDFB_Font,
" -> Unsupported font format %d!\n", img->format);
_cairo_cache_thaw( scaled_font->glyphs );
return CAIRO_INT_STATUS_UNSUPPORTED;
}
points[n].x = _cairo_lround (glyphs[i].x - img->base.device_transform.x0);
points[n].y = _cairo_lround (glyphs[i].y - img->base.device_transform.y0);
// D_DEBUG_AT (CairoDFB_Font, " (%4d,%4d) [%2d]\n", points[n].x, points[n].y, n );
if (points[n].x >= surface->width ||
points[n].y >= surface->height ||
points[n].x+img->width <= 0 ||
points[n].y+img->height <= 0)
continue;
{
D_DEBUG_AT (CairoDFB_Font,
" -> Unsupported font format %d!\n", img->format);
continue;
}
if (!scaled_glyph->surface_private) {
DFBRectangle *rect;
@ -1436,30 +1456,31 @@ _directfb_acquire_font_cache (cairo_directfb_surface_t *surface,
/* Remember glyph location */
rect = malloc (sizeof(DFBRectangle));
if (!rect)
if (!rect) {
_cairo_cache_thaw( scaled_font->glyphs );
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
}
*rect = rects[n];
scaled_glyph->surface_private = rect;
chars[num_chars++] = scaled_glyph;
/*D_DEBUG_AT (Cairo_DirectFB,
"Glyph %lu will be loaded at (%d,%d).\n",
glyphs[i].index, rects[n].x, rects[n].y);*/
D_DEBUG_AT (CairoDFB_Font, " -> loading at %4d,%2d <- rect %p, img %p, entry %p\n",
rects[n].x, rects[n].y, rect, scaled_glyph->surface, scaled_glyph);
}
else {
rects[n] = *((DFBRectangle *)scaled_glyph->surface_private);
/*D_DEBUG_AT (Cairo_DirectFB,
"Glyph %lu already loaded at (%d,%d).\n",
glyphs[i].index, rects[n].x, rects[n].y);*/
D_DEBUG_AT (CairoDFB_Font, " -> exists at %4d,%2d\n", rects[n].x, rects[n].y);
}
n++;
}
if (!n)
if (!n) {
_cairo_cache_thaw( scaled_font->glyphs );
return CAIRO_INT_STATUS_NOTHING_TO_DO;
}
h += y;
w = MAX (w, 8);
@ -1472,12 +1493,13 @@ _directfb_acquire_font_cache (cairo_directfb_surface_t *surface,
w = MAX (w, cache->width);
h = MAX (h, cache->height);
D_DEBUG_AT (Cairo_DirectFB,
"Reallocating font cache (%dx%d).\n", w, h);
D_DEBUG_AT (CairoDFB_Font, " -> Reallocating font cache (%dx%d).\n", w, h);
new_cache = _directfb_allocate_font_cache (surface->dfb, w, h);
if (!new_cache)
if (!new_cache) {
_cairo_cache_thaw( scaled_font->glyphs );
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
}
new_cache->dfbsurface->Blit (new_cache->dfbsurface,
cache->dfbsurface, NULL, 0, 0);
@ -1487,12 +1509,13 @@ _directfb_acquire_font_cache (cairo_directfb_surface_t *surface,
}
}
else {
D_DEBUG_AT (Cairo_DirectFB,
"Allocating font cache (%dx%d).\n", w, h);
D_DEBUG_AT (CairoDFB_Font, " -> Allocating font cache (%dx%d).\n", w, h);
cache = _directfb_allocate_font_cache (surface->dfb, w, h);
if (!cache)
if (!cache) {
_cairo_cache_thaw( scaled_font->glyphs );
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
}
scaled_font->surface_backend = &cairo_directfb_surface_backend;
scaled_font->surface_private = cache;
@ -1504,17 +1527,30 @@ _directfb_acquire_font_cache (cairo_directfb_surface_t *surface,
if (cache->dfbsurface->Lock (cache->dfbsurface,
DSLF_WRITE, (void *)&data, &pitch))
{
_cairo_cache_thaw( scaled_font->glyphs );
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
}
D_DEBUG_AT (CairoDFB_Font, " => %d chars to load, cache %dx%d\n", num_chars, cache->width, cache->height);
for (i = 0; i < num_chars; i++) {
cairo_image_surface_t *img = chars[i]->surface;
DFBRectangle *rect = chars[i]->surface_private;
unsigned char *dst = data;
unsigned char *src = img->data;
unsigned char *src;
int j;
D_DEBUG_AT (CairoDFB_Font, " -> loading [%2d] <- rect %p, img %p, entry %p\n", i, rect, img, chars[i]);
src = img->data;
D_DEBUG_AT (CairoDFB_Font, " from %p\n", src);
dst += rect->y * pitch + (_directfb_argb_font ? (rect->x<<2) : rect->x);
D_DEBUG_AT (CairoDFB_Font, " to %4d,%2d (%p)\n", rect->x, rect->y, dst);
if (img->format == CAIRO_FORMAT_A1) {
for (h = rect->h; h; h--) {
if (_directfb_argb_font) {
@ -1563,9 +1599,13 @@ _directfb_acquire_font_cache (cairo_directfb_surface_t *surface,
cache->dfbsurface->Unlock (cache->dfbsurface);
}
_cairo_cache_thaw( scaled_font->glyphs );
cache->x = x;
cache->y = y;
D_DEBUG_AT (CairoDFB_Font, " => cache %d,%d, %p [%d]\n", x, y, cache, n);
*ret_cache = cache;
*ret_num = n;
@ -1577,7 +1617,7 @@ _cairo_directfb_surface_scaled_font_fini (cairo_scaled_font_t *scaled_font)
{
cairo_directfb_font_cache_t *cache = scaled_font->surface_private;
D_DEBUG_AT (Cairo_DirectFB,
D_DEBUG_AT (CairoDFB_Font,
"%s( scaled_font=%p ).\n", __FUNCTION__, scaled_font);
if (cache) {
@ -1590,7 +1630,7 @@ static void
_cairo_directfb_surface_scaled_glyph_fini (cairo_scaled_glyph_t *scaled_glyph,
cairo_scaled_font_t *scaled_font)
{
D_DEBUG_AT (Cairo_DirectFB,
D_DEBUG_AT (CairoDFB_Font,
"%s( scaled_glyph=%p, scaled_font=%p ).\n",
__FUNCTION__, scaled_glyph, scaled_font);
@ -1620,7 +1660,7 @@ _cairo_directfb_surface_show_glyphs (void *abstract_dst,
DFBPoint points[num_glyphs];
int num;
D_DEBUG_AT (Cairo_DirectFB,
D_DEBUG_AT (CairoDFB_Font,
"%s( dst=%p, op=%d, pattern=%p, glyphs=%p, num_glyphs=%d, scaled_font=%p ).\n",
__FUNCTION__, dst, op, pattern, glyphs, num_glyphs, scaled_font);
@ -1661,7 +1701,7 @@ _cairo_directfb_surface_show_glyphs (void *abstract_dst,
dst->dfbsurface->SetDstBlendFunction (dst->dfbsurface, dblend);
dst->dfbsurface->SetColor (dst->dfbsurface, color.r, color.g, color.b, color.a);
D_DEBUG_AT (Cairo_DirectFB, "Running BatchBlit().\n");
D_DEBUG_AT (CairoDFB_Font, "Running BatchBlit().\n");
RUN_CLIPPED (dst, NULL,
dst->dfbsurface->BatchBlit (dst->dfbsurface,
@ -1759,7 +1799,7 @@ cairo_directfb_surface_backend_init (IDirectFB *dfb)
cairo_directfb_surface_backend.scaled_glyph_fini = NULL;
cairo_directfb_surface_backend.show_glyphs = NULL;
#endif
D_DEBUG_AT (Cairo_DirectFB, "Acceleration disabled.\n");
D_DEBUG_AT (CairoDFB_Surface, "Acceleration disabled.\n");
}
else {
DFBGraphicsDeviceDescription dsc;
@ -1767,19 +1807,19 @@ cairo_directfb_surface_backend_init (IDirectFB *dfb)
dfb->GetDeviceDescription (dfb, &dsc);
#if DFB_COMPOSITE
if (!(dsc.acceleration_mask & DFXL_BLIT))
cairo_directfb_surface_backend.composite = NULL;
// if (!(dsc.acceleration_mask & DFXL_BLIT))
// cairo_directfb_surface_backend.composite = NULL;
#endif
#if DFB_COMPOSITE_TRAPEZOIDS
if (!(dsc.acceleration_mask & DFXL_TEXTRIANGLES))
cairo_directfb_surface_backend.composite_trapezoids = NULL;
// if (!(dsc.acceleration_mask & DFXL_TEXTRIANGLES))
// cairo_directfb_surface_backend.composite_trapezoids = NULL;
#endif
}
if (getenv ("CAIRO_DIRECTFB_ARGB_FONT")) {
_directfb_argb_font = 1;
D_DEBUG_AT (Cairo_DirectFB, "Using ARGB fonts.\n");
D_DEBUG_AT (CairoDFB_Surface, "Using ARGB fonts.\n");
}
done = 1;

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

@ -0,0 +1,14 @@
#ifndef CAIRO_FEATURES_H
#define CAIRO_FEATURES_H
#define HAVE_WINDOWS_H 1
#define CAIRO_HAS_SVG_SURFACE 1
#define CAIRO_HAS_PDF_SURFACE 1
#define CAIRO_HAS_PS_SURFACE 1
#define CAIRO_HAS_WIN32_SURFACE 1
#define CAIRO_HAS_WIN32_FONT 1
#define CAIRO_HAS_PNG_FUNCTIONS 1
#endif

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

@ -52,11 +52,9 @@
#endif
#define CAIRO_VERSION_MAJOR 1
#define CAIRO_VERSION_MINOR 6
#define CAIRO_VERSION_MINOR 7
#define CAIRO_VERSION_MICRO 4
#define CAIRO_VERSION_STRING "1.6.4"
@PS_SURFACE_FEATURE@
@PDF_SURFACE_FEATURE@

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

@ -41,19 +41,78 @@
#define _BSD_SOURCE /* for strdup() */
#include "cairoint.h"
/* Forward declare so we can use it as an arbitrary backend for
* _cairo_font_face_nil.
*/
static const cairo_font_face_backend_t _cairo_toy_font_face_backend;
/* #cairo_font_face_t */
const cairo_font_face_t _cairo_font_face_nil = {
{ 0 }, /* hash_entry */
CAIRO_STATUS_NO_MEMORY, /* status */
const cairo_toy_font_face_t _cairo_font_face_nil = {
{
{ 0 }, /* hash_entry */
CAIRO_STATUS_NO_MEMORY, /* status */
CAIRO_REFERENCE_COUNT_INVALID, /* ref_count */
{ 0, 0, 0, NULL }, /* user_data */
{ 0, 0, 0, NULL }, /* user_data */
&_cairo_toy_font_face_backend
},
CAIRO_FONT_FAMILY_DEFAULT, /* family */
TRUE, /* owns_family */
CAIRO_FONT_SLANT_DEFAULT, /* slant */
CAIRO_FONT_WEIGHT_DEFAULT /* weight */
};
static const cairo_toy_font_face_t _cairo_font_face_null_pointer = {
{
{ 0 }, /* hash_entry */
CAIRO_STATUS_NULL_POINTER, /* status */
CAIRO_REFERENCE_COUNT_INVALID, /* ref_count */
{ 0, 0, 0, NULL }, /* user_data */
&_cairo_toy_font_face_backend
},
CAIRO_FONT_FAMILY_DEFAULT, /* family */
TRUE, /* owns_family */
CAIRO_FONT_SLANT_DEFAULT, /* slant */
CAIRO_FONT_WEIGHT_DEFAULT /* weight */
};
static const cairo_toy_font_face_t _cairo_font_face_invalid_string = {
{
{ 0 }, /* hash_entry */
CAIRO_STATUS_INVALID_STRING, /* status */
CAIRO_REFERENCE_COUNT_INVALID, /* ref_count */
{ 0, 0, 0, NULL }, /* user_data */
&_cairo_toy_font_face_backend
},
CAIRO_FONT_FAMILY_DEFAULT, /* family */
TRUE, /* owns_family */
CAIRO_FONT_SLANT_DEFAULT, /* slant */
CAIRO_FONT_WEIGHT_DEFAULT /* weight */
};
static const cairo_toy_font_face_t _cairo_font_face_invalid_slant = {
{
{ 0 }, /* hash_entry */
CAIRO_STATUS_INVALID_SLANT, /* status */
CAIRO_REFERENCE_COUNT_INVALID, /* ref_count */
{ 0, 0, 0, NULL }, /* user_data */
&_cairo_toy_font_face_backend
},
CAIRO_FONT_FAMILY_DEFAULT, /* family */
TRUE, /* owns_family */
CAIRO_FONT_SLANT_DEFAULT, /* slant */
CAIRO_FONT_WEIGHT_DEFAULT /* weight */
};
static const cairo_toy_font_face_t _cairo_font_face_invalid_weight = {
{
{ 0 }, /* hash_entry */
CAIRO_STATUS_INVALID_WEIGHT, /* status */
CAIRO_REFERENCE_COUNT_INVALID, /* ref_count */
{ 0, 0, 0, NULL }, /* user_data */
&_cairo_toy_font_face_backend
},
CAIRO_FONT_FAMILY_DEFAULT, /* family */
TRUE, /* owns_family */
CAIRO_FONT_SLANT_DEFAULT, /* slant */
CAIRO_FONT_WEIGHT_DEFAULT /* weight */
};
cairo_status_t
@ -371,7 +430,7 @@ _cairo_toy_font_face_keys_equal (const void *key_a,
}
/**
* _cairo_toy_font_face_create:
* cairo_toy_font_face_create:
* @family: a font family name, encoded in UTF-8
* @slant: the slant for the font
* @weight: the weight for the font
@ -380,18 +439,57 @@ _cairo_toy_font_face_keys_equal (const void *key_a,
* These font faces are used in implementation of the the #cairo_t "toy"
* font API.
*
* Return value: a newly created #cairo_font_face_t, destroy with
* cairo_font_face_destroy()
* If @family is the zero-length string "", the platform-specific default
* family is assumed. The default family then can be queried using
* cairo_toy_font_face_get_family().
*
* The cairo_select_font_face() function uses this to create font faces.
* See that function for limitations of toy font faces.
*
* Return value: a newly created #cairo_font_face_t. Free with
* cairo_font_face_destroy() when you are done using it.
*
* Since: 1.8
**/
cairo_font_face_t *
_cairo_toy_font_face_create (const char *family,
cairo_font_slant_t slant,
cairo_font_weight_t weight)
cairo_toy_font_face_create (const char *family,
cairo_font_slant_t slant,
cairo_font_weight_t weight)
{
cairo_status_t status;
cairo_toy_font_face_t key, *font_face;
cairo_hash_table_t *hash_table;
if (family == NULL)
return (cairo_font_face_t*) &_cairo_font_face_null_pointer;
/* Make sure we've got valid UTF-8 for the family */
status = _cairo_utf8_to_ucs4 (family, -1, NULL, NULL);
if (status == CAIRO_STATUS_INVALID_STRING)
return (cairo_font_face_t*) &_cairo_font_face_invalid_string;
else if (status)
return (cairo_font_face_t*) &_cairo_font_face_nil;
switch (slant) {
case CAIRO_FONT_SLANT_NORMAL:
case CAIRO_FONT_SLANT_ITALIC:
case CAIRO_FONT_SLANT_OBLIQUE:
break;
default:
return (cairo_font_face_t*) &_cairo_font_face_invalid_slant;
}
switch (weight) {
case CAIRO_FONT_WEIGHT_NORMAL:
case CAIRO_FONT_WEIGHT_BOLD:
break;
default:
return (cairo_font_face_t*) &_cairo_font_face_invalid_weight;
}
if (*family == '\0')
family = CAIRO_FONT_FAMILY_DEFAULT;
hash_table = _cairo_toy_font_face_hash_table_lock ();
if (hash_table == NULL)
goto UNWIND;
@ -444,6 +542,7 @@ _cairo_toy_font_face_create (const char *family,
UNWIND:
return (cairo_font_face_t*) &_cairo_font_face_nil;
}
slim_hidden_def (cairo_toy_font_face_create);
static void
_cairo_toy_font_face_destroy (void *abstract_face)
@ -493,6 +592,77 @@ _cairo_toy_font_face_scaled_font_create (void *abstract_font_face
scaled_font));
}
static cairo_bool_t
_cairo_font_face_is_toy (cairo_font_face_t *font_face)
{
return font_face->backend == &_cairo_toy_font_face_backend;
}
/**
* cairo_toy_font_face_get_family:
* @font_face: A toy font face
*
* Gets the familly name of a toy font.
*
* Return value: The family name. This string is owned by the font face
* and remains valid as long as the font face is alive (referenced).
*
* Since: 1.8
**/
const char *
cairo_toy_font_face_get_family (cairo_font_face_t *font_face)
{
cairo_toy_font_face_t *toy_font_face = (cairo_toy_font_face_t *) font_face;
if (! _cairo_font_face_is_toy (font_face)) {
if (_cairo_font_face_set_error (font_face, CAIRO_STATUS_FONT_TYPE_MISMATCH))
return CAIRO_FONT_FAMILY_DEFAULT;
}
assert (toy_font_face->owns_family);
return toy_font_face->family;
}
/**
* cairo_toy_font_face_get_slant:
* @font_face: A toy font face
*
* Gets the slant a toy font.
*
* Return value: The slant value
*
* Since: 1.8
**/
cairo_font_slant_t
cairo_toy_font_face_get_slant (cairo_font_face_t *font_face)
{
cairo_toy_font_face_t *toy_font_face = (cairo_toy_font_face_t *) font_face;
if (! _cairo_font_face_is_toy (font_face)) {
if (_cairo_font_face_set_error (font_face, CAIRO_STATUS_FONT_TYPE_MISMATCH))
return CAIRO_FONT_SLANT_DEFAULT;
}
return toy_font_face->slant;
}
/**
* cairo_toy_font_face_get_weight:
* @font_face: A toy font face
*
* Gets the weight a toy font.
*
* Return value: The weight value
*
* Since: 1.8
**/
cairo_font_weight_t
cairo_toy_font_face_get_weight (cairo_font_face_t *font_face)
{
cairo_toy_font_face_t *toy_font_face = (cairo_toy_font_face_t *) font_face;
if (! _cairo_font_face_is_toy (font_face)) {
if (_cairo_font_face_set_error (font_face, CAIRO_STATUS_FONT_TYPE_MISMATCH))
return CAIRO_FONT_WEIGHT_DEFAULT;
}
return toy_font_face->weight;
}
static const cairo_font_face_backend_t _cairo_toy_font_face_backend = {
CAIRO_FONT_TYPE_TOY,
_cairo_toy_font_face_destroy,

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

@ -39,6 +39,7 @@
static const cairo_font_options_t _cairo_font_options_nil = {
CAIRO_ANTIALIAS_DEFAULT,
CAIRO_SUBPIXEL_ORDER_DEFAULT,
CAIRO_LCD_FILTER_DEFAULT,
CAIRO_HINT_STYLE_DEFAULT,
CAIRO_HINT_METRICS_DEFAULT
};
@ -54,6 +55,7 @@ _cairo_font_options_init_default (cairo_font_options_t *options)
{
options->antialias = CAIRO_ANTIALIAS_DEFAULT;
options->subpixel_order = CAIRO_SUBPIXEL_ORDER_DEFAULT;
options->lcd_filter = CAIRO_LCD_FILTER_DEFAULT;
options->hint_style = CAIRO_HINT_STYLE_DEFAULT;
options->hint_metrics = CAIRO_HINT_METRICS_DEFAULT;
}
@ -64,6 +66,7 @@ _cairo_font_options_init_copy (cairo_font_options_t *options,
{
options->antialias = other->antialias;
options->subpixel_order = other->subpixel_order;
options->lcd_filter = other->lcd_filter;
options->hint_style = other->hint_style;
options->hint_metrics = other->hint_metrics;
}
@ -189,6 +192,8 @@ cairo_font_options_merge (cairo_font_options_t *options,
options->antialias = other->antialias;
if (other->subpixel_order != CAIRO_SUBPIXEL_ORDER_DEFAULT)
options->subpixel_order = other->subpixel_order;
if (other->lcd_filter != CAIRO_LCD_FILTER_DEFAULT)
options->lcd_filter = other->lcd_filter;
if (other->hint_style != CAIRO_HINT_STYLE_DEFAULT)
options->hint_style = other->hint_style;
if (other->hint_metrics != CAIRO_HINT_METRICS_DEFAULT)
@ -221,6 +226,7 @@ cairo_font_options_equal (const cairo_font_options_t *options,
return (options->antialias == other->antialias &&
options->subpixel_order == other->subpixel_order &&
options->lcd_filter == other->lcd_filter &&
options->hint_style == other->hint_style &&
options->hint_metrics == other->hint_metrics);
}
@ -246,7 +252,8 @@ cairo_font_options_hash (const cairo_font_options_t *options)
return ((options->antialias) |
(options->subpixel_order << 4) |
(options->hint_style << 8) |
(options->lcd_filter << 8) |
(options->hint_style << 12) |
(options->hint_metrics << 16));
}
slim_hidden_def (cairo_font_options_hash);
@ -327,6 +334,49 @@ cairo_font_options_get_subpixel_order (const cairo_font_options_t *options)
return options->subpixel_order;
}
/**
* cairo_font_options_set_lcd_filter:
* @options: a #cairo_font_options_t
* @lcd_filter: the new LCD filter
*
* Sets the LCD filter for the font options object. The LCD filter
* specifies how pixels are filtered when rendered with an antialiasing
* mode of %CAIRO_ANTIALIAS_SUBPIXEL. See the documentation for
* #cairo_lcd_filter_t for full details.
*
* Since: 1.8
**/
void
cairo_font_options_set_lcd_filter (cairo_font_options_t *options,
cairo_lcd_filter_t lcd_filter)
{
if (cairo_font_options_status (options))
return;
options->lcd_filter = lcd_filter;
}
slim_hidden_def (cairo_font_options_set_lcd_filter);
/**
* cairo_font_options_get_lcd_filter:
* @options: a #cairo_font_options_t
*
* Gets the LCD filter for the font options object.
* See the documentation for #cairo_lcd_filter_t for full details.
*
* Return value: the LCD filter for the font options object
*
* Since: 1.8
**/
cairo_lcd_filter_t
cairo_font_options_get_lcd_filter (const cairo_font_options_t *options)
{
if (cairo_font_options_status ((cairo_font_options_t *) options))
return CAIRO_LCD_FILTER_DEFAULT;
return options->lcd_filter;
}
/**
* cairo_font_options_set_hint_style:
* @options: a #cairo_font_options_t

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

@ -23,6 +23,7 @@
#define CAIRO_FREELIST_H
#include "cairo-types-private.h"
#include "cairo-compiler-private.h"
/* Opaque implementation types. */
typedef struct _cairo_freelist cairo_freelist_t;

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

@ -57,6 +57,30 @@
#include FT_SYNTHESIS_H
#endif
#if HAVE_FT_LIBRARY_SETLCDFILTER
#include FT_LCD_FILTER_H
#endif
/* Fontconfig version older than 2.6 didn't have these options */
#ifndef FC_LCD_FILTER
#define FC_LCD_FILTER "lcdfilter"
#endif
/* Some Ubuntu versions defined FC_LCD_FILTER without defining the following */
#ifndef FC_LCD_NONE
#define FC_LCD_NONE 0
#define FC_LCD_DEFAULT 1
#define FC_LCD_LIGHT 2
#define FC_LCD_LEGACY 3
#endif
/* FreeType version older than 2.3.5(?) didn't have these options */
#ifndef FT_LCD_FILTER_NONE
#define FT_LCD_FILTER_NONE 0
#define FT_LCD_FILTER_DEFAULT 1
#define FT_LCD_FILTER_LIGHT 2
#define FT_LCD_FILTER_LEGACY 16
#endif
#define DOUBLE_TO_26_6(d) ((FT_F26Dot6)((d) * 64.0))
#define DOUBLE_FROM_26_6(t) ((double)(t) / 64.0)
#define DOUBLE_TO_16_16(d) ((FT_Fixed)((d) * 65536.0))
@ -541,7 +565,7 @@ _has_unlocked_face (void *entry)
* This differs from _cairo_ft_scaled_font_lock_face in that it doesn't
* set the scale on the face, but just returns it at the last scale.
*/
FT_Face
cairo_warn FT_Face
_cairo_ft_unscaled_font_lock_face (cairo_ft_unscaled_font_t *unscaled)
{
cairo_ft_unscaled_font_map_t *font_map;
@ -622,7 +646,7 @@ _compute_transform (cairo_ft_font_transform_t *sf,
* freetype's transformation.
*/
status = _cairo_matrix_compute_scale_factors (scale,
status = _cairo_matrix_compute_basis_scale_factors (scale,
&x_scale, &y_scale,
1);
if (status)
@ -743,23 +767,286 @@ _cairo_ft_unscaled_font_set_scale (cairo_ft_unscaled_font_t *unscaled,
return CAIRO_STATUS_SUCCESS;
}
/* Empirically-derived subpixel filtering values thanks to Keith
* Packard and libXft. */
static const int filters[3][3] = {
/* red */
#if 0
{ 65538*4/7,65538*2/7,65538*1/7 },
/* green */
{ 65536*1/4, 65536*2/4, 65537*1/4 },
/* blue */
{ 65538*1/7,65538*2/7,65538*4/7 },
/* we sometimes need to convert the glyph bitmap in a FT_GlyphSlot
* into a different format. For example, we want to convert a
* FT_PIXEL_MODE_LCD or FT_PIXEL_MODE_LCD_V bitmap into a 32-bit
* ARGB or ABGR bitmap.
*
* this function prepares a target descriptor for this operation.
*
* input :: target bitmap descriptor. The function will set its
* 'width', 'rows' and 'pitch' fields, and only these
*
* slot :: the glyph slot containing the source bitmap. this
* function assumes that slot->format == FT_GLYPH_FORMAT_BITMAP
*
* mode :: the requested final rendering mode. supported values are
* MONO, NORMAL (i.e. gray), LCD and LCD_V
*
* the function returns the size in bytes of the corresponding buffer,
* it's up to the caller to allocate the corresponding memory block
* before calling _fill_xrender_bitmap
*
* it also returns -1 in case of error (e.g. incompatible arguments,
* like trying to convert a gray bitmap into a monochrome one)
*/
static int
_compute_xrender_bitmap_size(FT_Bitmap *target,
FT_GlyphSlot slot,
FT_Render_Mode mode)
{
FT_Bitmap *ftbit;
int width, height, pitch;
if (slot->format != FT_GLYPH_FORMAT_BITMAP)
return -1;
/* compute the size of the final bitmap */
ftbit = &slot->bitmap;
width = ftbit->width;
height = ftbit->rows;
pitch = (width + 3) & ~3;
switch (ftbit->pixel_mode) {
case FT_PIXEL_MODE_MONO:
if (mode == FT_RENDER_MODE_MONO) {
pitch = (((width + 31) & ~31) >> 3);
break;
}
/* fall-through */
case FT_PIXEL_MODE_GRAY:
if (mode == FT_RENDER_MODE_LCD ||
mode == FT_RENDER_MODE_LCD_V)
{
/* each pixel is replicated into a 32-bit ARGB value */
pitch = width * 4;
}
break;
case FT_PIXEL_MODE_LCD:
if (mode != FT_RENDER_MODE_LCD)
return -1;
/* horz pixel triplets are packed into 32-bit ARGB values */
width /= 3;
pitch = width * 4;
break;
case FT_PIXEL_MODE_LCD_V:
if (mode != FT_RENDER_MODE_LCD_V)
return -1;
/* vert pixel triplets are packed into 32-bit ARGB values */
height /= 3;
pitch = width * 4;
break;
default: /* unsupported source format */
return -1;
}
target->width = width;
target->rows = height;
target->pitch = pitch;
target->buffer = NULL;
return pitch * height;
}
/* this functions converts the glyph bitmap found in a FT_GlyphSlot
* into a different format (see _compute_xrender_bitmap_size)
*
* you should call this function after _compute_xrender_bitmap_size
*
* target :: target bitmap descriptor. Note that its 'buffer' pointer
* must point to memory allocated by the caller
*
* slot :: the glyph slot containing the source bitmap
*
* mode :: the requested final rendering mode
*
* bgr :: boolean, set if BGR or VBGR pixel ordering is needed
*/
static void
_fill_xrender_bitmap(FT_Bitmap *target,
FT_GlyphSlot slot,
FT_Render_Mode mode,
int bgr)
{
FT_Bitmap *ftbit = &slot->bitmap;
unsigned char *srcLine = ftbit->buffer;
unsigned char *dstLine = target->buffer;
int src_pitch = ftbit->pitch;
int width = target->width;
int height = target->rows;
int pitch = target->pitch;
int subpixel;
int h;
subpixel = (mode == FT_RENDER_MODE_LCD ||
mode == FT_RENDER_MODE_LCD_V);
if (src_pitch < 0)
srcLine -= src_pitch * (ftbit->rows - 1);
target->pixel_mode = ftbit->pixel_mode;
switch (ftbit->pixel_mode) {
case FT_PIXEL_MODE_MONO:
if (subpixel) {
/* convert mono to ARGB32 values */
for (h = height; h > 0; h--, srcLine += src_pitch, dstLine += pitch) {
int x;
for (x = 0; x < width; x++) {
if (srcLine[(x >> 3)] & (0x80 >> (x & 7)))
((unsigned int *) dstLine)[x] = 0xffffffffU;
}
}
target->pixel_mode = FT_PIXEL_MODE_LCD;
} else if (mode == FT_RENDER_MODE_NORMAL) {
/* convert mono to 8-bit gray */
for (h = height; h > 0; h--, srcLine += src_pitch, dstLine += pitch) {
int x;
for (x = 0; x < width; x++) {
if (srcLine[(x >> 3)] & (0x80 >> (x & 7)))
dstLine[x] = 0xff;
}
}
target->pixel_mode = FT_PIXEL_MODE_GRAY;
} else {
/* copy mono to mono */
int bytes = (width + 7) >> 3;
for (h = height; h > 0; h--, srcLine += src_pitch, dstLine += pitch)
memcpy (dstLine, srcLine, bytes);
}
break;
case FT_PIXEL_MODE_GRAY:
if (subpixel) {
/* convert gray to ARGB32 values */
for (h = height; h > 0; h--, srcLine += src_pitch, dstLine += pitch) {
int x;
unsigned int *dst = (unsigned int *) dstLine;
for (x = 0; x < width; x++) {
unsigned int pix = srcLine[x];
pix |= (pix << 8);
pix |= (pix << 16);
dst[x] = pix;
}
}
target->pixel_mode = FT_PIXEL_MODE_LCD;
} else {
/* copy gray into gray */
for (h = height; h > 0; h--, srcLine += src_pitch, dstLine += pitch)
memcpy (dstLine, srcLine, width);
}
break;
case FT_PIXEL_MODE_LCD:
if (!bgr) {
/* convert horizontal RGB into ARGB32 */
for (h = height; h > 0; h--, srcLine += src_pitch, dstLine += pitch) {
int x;
unsigned char *src = srcLine;
unsigned int *dst = (unsigned int *) dstLine;
for (x = 0; x < width; x++, src += 3) {
unsigned int pix;
pix = ((unsigned int)src[0] << 16) |
((unsigned int)src[1] << 8) |
((unsigned int)src[2] ) |
((unsigned int)src[1] << 24) ;
dst[x] = pix;
}
}
} else {
/* convert horizontal BGR into ARGB32 */
for (h = height; h > 0; h--, srcLine += src_pitch, dstLine += pitch) {
int x;
unsigned char *src = srcLine;
unsigned int *dst = (unsigned int *) dstLine;
for (x = 0; x < width; x++, src += 3) {
unsigned int pix;
pix = ((unsigned int)src[2] << 16) |
((unsigned int)src[1] << 8) |
((unsigned int)src[0] ) |
((unsigned int)src[1] << 24) ;
dst[x] = pix;
}
}
}
break;
default: /* FT_PIXEL_MODE_LCD_V */
/* convert vertical RGB into ARGB32 */
if (!bgr) {
for (h = height; h > 0; h--, srcLine += 3 * src_pitch, dstLine += pitch) {
int x;
unsigned char* src = srcLine;
unsigned int* dst = (unsigned int *) dstLine;
for (x = 0; x < width; x++, src += 1) {
unsigned int pix;
#if 1
pix = ((unsigned int)src[0] << 16) |
((unsigned int)src[src_pitch] << 8) |
((unsigned int)src[src_pitch*2] ) |
0xFF000000 ;
#else
pix = ((unsigned int)src[0] << 16) |
((unsigned int)src[src_pitch] << 8) |
((unsigned int)src[src_pitch*2] ) |
((unsigned int)src[src_pitch] << 24) ;
#endif
{ 65538*9/13,65538*3/13,65538*1/13 },
/* green */
{ 65538*1/6, 65538*4/6, 65538*1/6 },
/* blue */
{ 65538*1/13,65538*3/13,65538*9/13 },
};
dst[x] = pix;
}
}
} else {
for (h = height; h > 0; h--, srcLine += 3*src_pitch, dstLine += pitch) {
int x;
unsigned char *src = srcLine;
unsigned int *dst = (unsigned int *) dstLine;
for (x = 0; x < width; x++, src += 1) {
unsigned int pix;
pix = ((unsigned int)src[src_pitch * 2] << 16) |
((unsigned int)src[src_pitch] << 8) |
((unsigned int)src[0] ) |
((unsigned int)src[src_pitch] << 24) ;
dst[x] = pix;
}
}
}
}
}
/* Fills in val->image with an image surface created from @bitmap
*/
@ -772,7 +1059,7 @@ _get_bitmap_surface (FT_Bitmap *bitmap,
int width, height, stride;
unsigned char *data;
int format = CAIRO_FORMAT_A8;
cairo_bool_t subpixel = FALSE;
cairo_image_surface_t *image;
width = bitmap->width;
height = bitmap->rows;
@ -814,7 +1101,7 @@ _get_bitmap_surface (FT_Bitmap *bitmap,
#ifndef WORDS_BIGENDIAN
{
unsigned char *d = data;
uint8_t *d = data;
int count = stride * height;
while (count--) {
@ -829,11 +1116,7 @@ _get_bitmap_surface (FT_Bitmap *bitmap,
case FT_PIXEL_MODE_LCD:
case FT_PIXEL_MODE_LCD_V:
case FT_PIXEL_MODE_GRAY:
switch (font_options->antialias) {
case CAIRO_ANTIALIAS_DEFAULT:
case CAIRO_ANTIALIAS_GRAY:
case CAIRO_ANTIALIAS_NONE:
default:
if (font_options->antialias != CAIRO_ANTIALIAS_SUBPIXEL) {
stride = bitmap->pitch;
if (own_buffer) {
data = bitmap->buffer;
@ -845,104 +1128,16 @@ _get_bitmap_surface (FT_Bitmap *bitmap,
memcpy (data, bitmap->buffer, stride * height);
}
format = CAIRO_FORMAT_A8;
break;
case CAIRO_ANTIALIAS_SUBPIXEL: {
int x, y;
unsigned char *in_line, *out_line, *in;
unsigned int *out;
unsigned int red, green, blue;
int rf, gf, bf;
int s;
int o, os;
unsigned char *data_rgba;
unsigned int width_rgba, stride_rgba;
int vmul = 1;
int hmul = 1;
} else {
/* if we get there, the data from the source bitmap
* really comes from _fill_xrender_bitmap, and is
* made of 32-bit ARGB or ABGR values */
assert (own_buffer != 0);
assert (bitmap->pixel_mode != FT_PIXEL_MODE_GRAY);
switch (font_options->subpixel_order) {
case CAIRO_SUBPIXEL_ORDER_DEFAULT:
case CAIRO_SUBPIXEL_ORDER_RGB:
case CAIRO_SUBPIXEL_ORDER_BGR:
default:
width /= 3;
hmul = 3;
break;
case CAIRO_SUBPIXEL_ORDER_VRGB:
case CAIRO_SUBPIXEL_ORDER_VBGR:
vmul = 3;
height /= 3;
break;
}
/*
* Filter the glyph to soften the color fringes
*/
width_rgba = width;
data = bitmap->buffer;
stride = bitmap->pitch;
stride_rgba = (width_rgba * 4 + 3) & ~3;
data_rgba = calloc (stride_rgba, height);
if (data_rgba == NULL) {
if (own_buffer)
free (bitmap->buffer);
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
}
os = 1;
switch (font_options->subpixel_order) {
case CAIRO_SUBPIXEL_ORDER_VRGB:
os = stride;
case CAIRO_SUBPIXEL_ORDER_DEFAULT:
case CAIRO_SUBPIXEL_ORDER_RGB:
default:
rf = 0;
gf = 1;
bf = 2;
break;
case CAIRO_SUBPIXEL_ORDER_VBGR:
os = stride;
case CAIRO_SUBPIXEL_ORDER_BGR:
bf = 0;
gf = 1;
rf = 2;
break;
}
in_line = bitmap->buffer;
out_line = data_rgba;
for (y = 0; y < height; y++)
{
in = in_line;
out = (unsigned int *) out_line;
in_line += stride * vmul;
out_line += stride_rgba;
for (x = 0; x < width * hmul; x += hmul)
{
red = green = blue = 0;
o = 0;
for (s = 0; s < 3; s++)
{
red += filters[rf][s]*in[x+o];
green += filters[gf][s]*in[x+o];
blue += filters[bf][s]*in[x+o];
o += os;
}
red = red / 65536;
green = green / 65536;
blue = blue / 65536;
*out++ = (green << 24) | (red << 16) | (green << 8) | blue;
}
}
/* Images here are stored in native format. The
* backend must convert to its own format as needed
*/
if (own_buffer)
free (bitmap->buffer);
data = data_rgba;
stride = stride_rgba;
format = CAIRO_FORMAT_ARGB32;
subpixel = TRUE;
break;
}
}
break;
case FT_PIXEL_MODE_GRAY2:
@ -954,19 +1149,20 @@ _get_bitmap_surface (FT_Bitmap *bitmap,
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
}
*surface = (cairo_image_surface_t *)
/* XXX */
*surface = image = (cairo_image_surface_t *)
cairo_image_surface_create_for_data (data,
format,
width, height, stride);
if ((*surface)->base.status) {
if (image->base.status) {
free (data);
return (*surface)->base.status;
}
if (subpixel)
pixman_image_set_component_alpha ((*surface)->pixman_image, TRUE);
if (font_options->antialias == CAIRO_ANTIALIAS_SUBPIXEL)
pixman_image_set_component_alpha (image->pixman_image, TRUE);
_cairo_image_surface_assume_ownership_of_data ((*surface));
_cairo_image_surface_assume_ownership_of_data (image);
return CAIRO_STATUS_SUCCESS;
}
@ -991,16 +1187,59 @@ _render_glyph_outline (FT_Face face,
cairo_font_options_t *font_options,
cairo_image_surface_t **surface)
{
int rgba = FC_RGBA_UNKNOWN;
int lcd_filter = FT_LCD_FILTER_LEGACY;
FT_GlyphSlot glyphslot = face->glyph;
FT_Outline *outline = &glyphslot->outline;
FT_Bitmap bitmap;
FT_BBox cbox;
FT_Matrix matrix;
int hmul = 1;
int vmul = 1;
unsigned int width, height, stride;
cairo_bool_t subpixel = FALSE;
unsigned int width, height;
cairo_status_t status;
FT_Error fterror;
FT_Library library = glyphslot->library;
FT_Render_Mode render_mode = FT_RENDER_MODE_NORMAL;
switch (font_options->antialias) {
case CAIRO_ANTIALIAS_NONE:
render_mode = FT_RENDER_MODE_MONO;
break;
case CAIRO_ANTIALIAS_SUBPIXEL:
switch (font_options->subpixel_order) {
case CAIRO_SUBPIXEL_ORDER_DEFAULT:
case CAIRO_SUBPIXEL_ORDER_RGB:
case CAIRO_SUBPIXEL_ORDER_BGR:
render_mode = FT_RENDER_MODE_LCD;
break;
case CAIRO_SUBPIXEL_ORDER_VRGB:
case CAIRO_SUBPIXEL_ORDER_VBGR:
render_mode = FT_RENDER_MODE_LCD_V;
break;
}
switch (font_options->lcd_filter) {
case CAIRO_LCD_FILTER_NONE:
lcd_filter = FT_LCD_FILTER_NONE;
break;
case CAIRO_LCD_FILTER_DEFAULT:
case CAIRO_LCD_FILTER_INTRA_PIXEL:
lcd_filter = FT_LCD_FILTER_LEGACY;
break;
case CAIRO_LCD_FILTER_FIR3:
lcd_filter = FT_LCD_FILTER_LIGHT;
break;
case CAIRO_LCD_FILTER_FIR5:
lcd_filter = FT_LCD_FILTER_DEFAULT;
break;
}
break;
case CAIRO_ANTIALIAS_DEFAULT:
case CAIRO_ANTIALIAS_GRAY:
render_mode = FT_RENDER_MODE_NORMAL;
}
FT_Outline_Get_CBox (outline, &cbox);
@ -1011,20 +1250,21 @@ _render_glyph_outline (FT_Face face,
width = (unsigned int) ((cbox.xMax - cbox.xMin) >> 6);
height = (unsigned int) ((cbox.yMax - cbox.yMin) >> 6);
stride = (width * hmul + 3) & ~3;
if (width * height == 0) {
cairo_format_t format;
/* Looks like fb handles zero-sized images just fine */
switch (font_options->antialias) {
case CAIRO_ANTIALIAS_NONE:
switch (render_mode) {
case FT_RENDER_MODE_MONO:
format = CAIRO_FORMAT_A1;
break;
case CAIRO_ANTIALIAS_SUBPIXEL:
case FT_RENDER_MODE_LCD:
case FT_RENDER_MODE_LCD_V:
format= CAIRO_FORMAT_ARGB32;
break;
case CAIRO_ANTIALIAS_DEFAULT:
case CAIRO_ANTIALIAS_GRAY:
case FT_RENDER_MODE_LIGHT:
case FT_RENDER_MODE_NORMAL:
case FT_RENDER_MODE_MAX:
default:
format = CAIRO_FORMAT_A8;
break;
@ -1036,73 +1276,73 @@ _render_glyph_outline (FT_Face face,
return (*surface)->base.status;
} else {
matrix.xx = matrix.yy = 0x10000L;
matrix.xy = matrix.yx = 0;
int bitmap_size;
switch (font_options->antialias) {
case CAIRO_ANTIALIAS_NONE:
bitmap.pixel_mode = FT_PIXEL_MODE_MONO;
bitmap.num_grays = 1;
stride = ((width + 31) & -32) >> 3;
break;
case CAIRO_ANTIALIAS_DEFAULT:
case CAIRO_ANTIALIAS_GRAY:
bitmap.pixel_mode = FT_PIXEL_MODE_GRAY;
bitmap.num_grays = 256;
stride = (width + 3) & -4;
break;
case CAIRO_ANTIALIAS_SUBPIXEL:
switch (font_options->subpixel_order) {
case CAIRO_SUBPIXEL_ORDER_RGB:
case CAIRO_SUBPIXEL_ORDER_BGR:
case CAIRO_SUBPIXEL_ORDER_DEFAULT:
default:
matrix.xx *= 3;
hmul = 3;
subpixel = TRUE;
break;
case CAIRO_SUBPIXEL_ORDER_VRGB:
case CAIRO_SUBPIXEL_ORDER_VBGR:
matrix.yy *= 3;
vmul = 3;
subpixel = TRUE;
break;
switch (render_mode) {
case FT_RENDER_MODE_LCD:
if (font_options->subpixel_order == CAIRO_SUBPIXEL_ORDER_BGR) {
rgba = FC_RGBA_BGR;
} else {
rgba = FC_RGBA_RGB;
}
FT_Outline_Transform (outline, &matrix);
bitmap.pixel_mode = FT_PIXEL_MODE_GRAY;
bitmap.num_grays = 256;
stride = (width * hmul + 3) & -4;
break;
case FT_RENDER_MODE_LCD_V:
if (font_options->subpixel_order == CAIRO_SUBPIXEL_ORDER_VBGR) {
rgba = FC_RGBA_VBGR;
} else {
rgba = FC_RGBA_VRGB;
}
break;
case FT_RENDER_MODE_MONO:
case FT_RENDER_MODE_LIGHT:
case FT_RENDER_MODE_NORMAL:
case FT_RENDER_MODE_MAX:
default:
break;
}
bitmap.pitch = stride;
bitmap.width = width * hmul;
bitmap.rows = height * vmul;
bitmap.buffer = calloc (stride, bitmap.rows);
#if HAVE_FT_LIBRARY_SETLCDFILTER
FT_Library_SetLcdFilter (library, lcd_filter);
#endif
fterror = FT_Render_Glyph (face->glyph, render_mode);
#if HAVE_FT_LIBRARY_SETLCDFILTER
FT_Library_SetLcdFilter (library, FT_LCD_FILTER_NONE);
#endif
if (fterror != 0)
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
bitmap_size = _compute_xrender_bitmap_size (&bitmap,
face->glyph,
render_mode);
if (bitmap_size < 0)
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
bitmap.buffer = calloc (1, bitmap_size);
if (bitmap.buffer == NULL)
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
FT_Outline_Translate (outline, -cbox.xMin*hmul, -cbox.yMin*vmul);
if (FT_Outline_Get_Bitmap (glyphslot->library, outline, &bitmap) != 0) {
free (bitmap.buffer);
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
}
_fill_xrender_bitmap (&bitmap, face->glyph, render_mode,
(rgba == FC_RGBA_BGR || rgba == FC_RGBA_VBGR));
/* Note:
* _get_bitmap_surface will free bitmap.buffer if there is an error
*/
status = _get_bitmap_surface (&bitmap, TRUE, font_options, surface);
if (status)
return status;
}
/*
* Note: the font's coordinate system is upside down from ours, so the
* Y coordinate of the control box needs to be negated. Moreover, device
* offsets are position of glyph origin relative to top left while xMin
* and yMax are offsets of top left relative to origin. Another negation.
*/
cairo_surface_set_device_offset (&(*surface)->base,
floor (-(double) cbox.xMin / 64.0),
floor (+(double) cbox.yMax / 64.0));
/* Note: the font's coordinate system is upside down from ours, so the
* Y coordinate of the control box needs to be negated. Moreover, device
* offsets are position of glyph origin relative to top left while xMin
* and yMax are offsets of top left relative to origin. Another negation.
*/
cairo_surface_set_device_offset (&(*surface)->base,
(double)-glyphslot->bitmap_left,
(double)+glyphslot->bitmap_top);
}
return CAIRO_STATUS_SUCCESS;
}
@ -1322,6 +1562,7 @@ _get_pattern_ft_options (FcPattern *pattern, cairo_ft_options_t *ret)
if (antialias) {
cairo_subpixel_order_t subpixel_order;
int lcd_filter;
/* disable hinting if requested */
if (FcPatternGetBool (pattern,
@ -1357,6 +1598,25 @@ _get_pattern_ft_options (FcPattern *pattern, cairo_ft_options_t *ret)
ft_options.base.antialias = CAIRO_ANTIALIAS_SUBPIXEL;
}
if (FcPatternGetInteger (pattern,
FC_LCD_FILTER, 0, &lcd_filter) == FcResultMatch)
{
switch (lcd_filter) {
case FC_LCD_NONE:
ft_options.base.lcd_filter = CAIRO_LCD_FILTER_NONE;
break;
case FC_LCD_DEFAULT:
ft_options.base.lcd_filter = CAIRO_LCD_FILTER_FIR5;
break;
case FC_LCD_LIGHT:
ft_options.base.lcd_filter = CAIRO_LCD_FILTER_FIR3;
break;
case FC_LCD_LEGACY:
ft_options.base.lcd_filter = CAIRO_LCD_FILTER_INTRA_PIXEL;
break;
}
}
#ifdef FC_HINT_STYLE
if (FcPatternGetInteger (pattern,
FC_HINT_STYLE, 0, &hintstyle) != FcResultMatch)
@ -1457,6 +1717,12 @@ _cairo_ft_options_merge (cairo_ft_options_t *options,
if (other->base.hint_style == CAIRO_HINT_STYLE_NONE)
options->base.hint_style = CAIRO_HINT_STYLE_NONE;
if (options->base.lcd_filter == CAIRO_LCD_FILTER_DEFAULT)
options->base.lcd_filter = other->base.lcd_filter;
if (other->base.lcd_filter == CAIRO_LCD_FILTER_NONE)
options->base.lcd_filter = CAIRO_LCD_FILTER_NONE;
if (options->base.antialias == CAIRO_ANTIALIAS_NONE) {
if (options->base.hint_style == CAIRO_HINT_STYLE_NONE)
load_flags |= FT_LOAD_NO_HINTING;
@ -1480,11 +1746,11 @@ _cairo_ft_options_merge (cairo_ft_options_t *options,
case CAIRO_SUBPIXEL_ORDER_DEFAULT:
case CAIRO_SUBPIXEL_ORDER_RGB:
case CAIRO_SUBPIXEL_ORDER_BGR:
load_target |= FT_LOAD_TARGET_LCD;
load_target = FT_LOAD_TARGET_LCD;
break;
case CAIRO_SUBPIXEL_ORDER_VRGB:
case CAIRO_SUBPIXEL_ORDER_VBGR:
load_target |= FT_LOAD_TARGET_LCD_V;
load_target = FT_LOAD_TARGET_LCD_V;
break;
}
}
@ -2146,7 +2412,11 @@ _cairo_ft_ucs4_to_index (void *abstract_font,
face = _cairo_ft_unscaled_font_lock_face (unscaled);
if (!face)
return 0;
index = FT_Get_Char_Index (face, ucs4);
/* If making this compile without fontconfig, use:
* index = FT_Get_Char_Index (face, ucs4); */
index = FcFreeTypeCharIndex (face, ucs4);
_cairo_ft_unscaled_font_unlock_face (unscaled);
return index;
}
@ -2423,6 +2693,34 @@ _cairo_ft_font_options_substitute (const cairo_font_options_t *options,
}
}
if (options->lcd_filter != CAIRO_LCD_FILTER_DEFAULT)
{
if (FcPatternGet (pattern, FC_LCD_FILTER, 0, &v) == FcResultNoMatch)
{
int lcd_filter;
switch (options->lcd_filter) {
case CAIRO_LCD_FILTER_NONE:
lcd_filter = FT_LCD_FILTER_NONE;
break;
case CAIRO_LCD_FILTER_DEFAULT:
case CAIRO_LCD_FILTER_INTRA_PIXEL:
lcd_filter = FT_LCD_FILTER_LEGACY;
break;
case CAIRO_LCD_FILTER_FIR3:
lcd_filter = FT_LCD_FILTER_LIGHT;
break;
default:
case CAIRO_LCD_FILTER_FIR5:
lcd_filter = FT_LCD_FILTER_DEFAULT;
break;
}
if (! FcPatternAddInteger (pattern, FC_LCD_FILTER, lcd_filter))
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
}
}
if (options->hint_style != CAIRO_HINT_STYLE_DEFAULT)
{
if (FcPatternGet (pattern, FC_HINTING, 0, &v) == FcResultNoMatch)

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

@ -99,8 +99,9 @@ _cairo_gstate_init (cairo_gstate_t *gstate,
gstate->parent_target = NULL;
gstate->original_target = cairo_surface_reference (target);
_cairo_gstate_identity_matrix (gstate);
gstate->source_ctm_inverse = gstate->ctm_inverse;
cairo_matrix_init_identity (&gstate->ctm);
gstate->ctm_inverse = gstate->ctm;
gstate->source_ctm_inverse = gstate->ctm;
gstate->source = _cairo_pattern_create_solid (CAIRO_COLOR_BLACK,
CAIRO_CONTENT_COLOR);
@ -653,6 +654,9 @@ _cairo_gstate_transform (cairo_gstate_t *gstate,
cairo_matrix_t tmp;
cairo_status_t status;
if (_cairo_matrix_is_identity (matrix))
return CAIRO_STATUS_SUCCESS;
tmp = *matrix;
status = cairo_matrix_invert (&tmp);
if (status)
@ -676,6 +680,9 @@ _cairo_gstate_set_matrix (cairo_gstate_t *gstate,
{
cairo_status_t status;
if (memcmp (matrix, &gstate->ctm, sizeof (cairo_matrix_t)) == 0)
return CAIRO_STATUS_SUCCESS;
if (! _cairo_matrix_is_invertible (matrix))
return _cairo_error (CAIRO_STATUS_INVALID_MATRIX);
@ -692,6 +699,9 @@ _cairo_gstate_set_matrix (cairo_gstate_t *gstate,
void
_cairo_gstate_identity_matrix (cairo_gstate_t *gstate)
{
if (_cairo_matrix_is_identity (&gstate->ctm))
return;
_cairo_gstate_unset_scaled_font (gstate);
cairo_matrix_init_identity (&gstate->ctm);
@ -1215,7 +1225,7 @@ _cairo_gstate_select_font_face (cairo_gstate_t *gstate,
cairo_font_face_t *font_face;
cairo_status_t status;
font_face = _cairo_toy_font_face_create (family, slant, weight);
font_face = cairo_toy_font_face_create (family, slant, weight);
if (font_face->status)
return font_face->status;
@ -1240,6 +1250,9 @@ cairo_status_t
_cairo_gstate_set_font_matrix (cairo_gstate_t *gstate,
const cairo_matrix_t *matrix)
{
if (memcmp (matrix, &gstate->font_matrix, sizeof (cairo_matrix_t)) == 0)
return CAIRO_STATUS_SUCCESS;
if (! _cairo_matrix_is_invertible (matrix))
return _cairo_error (CAIRO_STATUS_INVALID_MATRIX);
@ -1261,6 +1274,9 @@ void
_cairo_gstate_set_font_options (cairo_gstate_t *gstate,
const cairo_font_options_t *options)
{
if (memcmp (options, &gstate->font_options, sizeof (cairo_font_options_t)) == 0)
return;
_cairo_gstate_unset_scaled_font (gstate);
_cairo_font_options_init_copy (&gstate->font_options, options);
@ -1389,9 +1405,9 @@ _cairo_gstate_ensure_font_face (cairo_gstate_t *gstate)
return gstate->font_face->status;
font_face = _cairo_toy_font_face_create (CAIRO_FONT_FAMILY_DEFAULT,
CAIRO_FONT_SLANT_DEFAULT,
CAIRO_FONT_WEIGHT_DEFAULT);
font_face = cairo_toy_font_face_create (CAIRO_FONT_FAMILY_DEFAULT,
CAIRO_FONT_SLANT_DEFAULT,
CAIRO_FONT_WEIGHT_DEFAULT);
if (font_face->status)
return font_face->status;
@ -1445,12 +1461,16 @@ _cairo_gstate_get_font_extents (cairo_gstate_t *gstate,
}
cairo_status_t
_cairo_gstate_text_to_glyphs (cairo_gstate_t *gstate,
const char *utf8,
double x,
double y,
cairo_glyph_t **glyphs,
int *num_glyphs)
_cairo_gstate_text_to_glyphs (cairo_gstate_t *gstate,
double x,
double y,
const char *utf8,
int utf8_len,
cairo_glyph_t **glyphs,
int *num_glyphs,
cairo_text_cluster_t **clusters,
int *num_clusters,
cairo_bool_t *backward)
{
cairo_status_t status;
@ -1458,8 +1478,11 @@ _cairo_gstate_text_to_glyphs (cairo_gstate_t *gstate,
if (status)
return status;
return _cairo_scaled_font_text_to_glyphs (gstate->scaled_font, x, y,
utf8, glyphs, num_glyphs);
return cairo_scaled_font_text_to_glyphs (gstate->scaled_font, x, y,
utf8, utf8_len,
glyphs, num_glyphs,
clusters, num_clusters,
backward);
}
cairo_status_t
@ -1469,10 +1492,11 @@ _cairo_gstate_set_font_face (cairo_gstate_t *gstate,
if (font_face && font_face->status)
return font_face->status;
if (font_face != gstate->font_face) {
cairo_font_face_destroy (gstate->font_face);
gstate->font_face = cairo_font_face_reference (font_face);
}
if (font_face == gstate->font_face)
return CAIRO_STATUS_SUCCESS;
cairo_font_face_destroy (gstate->font_face);
gstate->font_face = cairo_font_face_reference (font_face);
_cairo_gstate_unset_scaled_font (gstate);
@ -1501,7 +1525,7 @@ _cairo_gstate_glyph_extents (cairo_gstate_t *gstate,
cairo_bool_t
_cairo_gstate_has_show_text_glyphs (cairo_gstate_t *gstate)
{
return _cairo_surface_has_show_text_glyphs (gstate->target);
return cairo_surface_has_show_text_glyphs (gstate->target);
}
cairo_status_t
@ -1533,7 +1557,7 @@ _cairo_gstate_show_text_glyphs (cairo_gstate_t *gstate,
if (num_glyphs <= ARRAY_LENGTH (stack_transformed_glyphs)) {
transformed_glyphs = stack_transformed_glyphs;
} else {
transformed_glyphs = _cairo_malloc_ab (num_glyphs, sizeof(cairo_glyph_t));
transformed_glyphs = cairo_glyph_allocate (num_glyphs);
if (transformed_glyphs == NULL)
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
}
@ -1548,6 +1572,10 @@ _cairo_gstate_show_text_glyphs (cairo_gstate_t *gstate,
if (status)
goto CLEANUP_GLYPHS;
/* Just in case */
if (!clusters)
num_clusters = 0;
/* For really huge font sizes, we can just do path;fill instead of
* show_glyphs, as show_glyphs would put excess pressure on the cache,
* and moreover, not all components below us correctly handle huge font
@ -1595,7 +1623,7 @@ _cairo_gstate_show_text_glyphs (cairo_gstate_t *gstate,
CLEANUP_GLYPHS:
if (transformed_glyphs != stack_transformed_glyphs)
free (transformed_glyphs);
cairo_glyph_free (transformed_glyphs);
return status;
}
@ -1617,7 +1645,7 @@ _cairo_gstate_glyph_path (cairo_gstate_t *gstate,
if (num_glyphs < ARRAY_LENGTH (stack_transformed_glyphs))
transformed_glyphs = stack_transformed_glyphs;
else
transformed_glyphs = _cairo_malloc_ab (num_glyphs, sizeof(cairo_glyph_t));
transformed_glyphs = cairo_glyph_allocate (num_glyphs);
if (transformed_glyphs == NULL)
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
@ -1631,7 +1659,7 @@ _cairo_gstate_glyph_path (cairo_gstate_t *gstate,
CAIRO_MUTEX_UNLOCK (gstate->scaled_font->mutex);
if (transformed_glyphs != stack_transformed_glyphs)
free (transformed_glyphs);
cairo_glyph_free (transformed_glyphs);
return status;
}

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

@ -259,7 +259,7 @@ _cairo_image_surface_create_with_masks (unsigned char *data,
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"
"Error: Cairo %s does not yet support the requested image format:\n"
"\tDepth: %d\n"
"\tAlpha mask: 0x%08lx\n"
"\tRed mask: 0x%08lx\n"
@ -267,6 +267,7 @@ _cairo_image_surface_create_with_masks (unsigned char *data,
"\tBlue mask: 0x%08lx\n"
"Please file an enhancement request (quoting the above) at:\n"
PACKAGE_BUGREPORT "\n",
cairo_version_string (),
masks->bpp, masks->alpha_mask,
masks->red_mask, masks->green_mask, masks->blue_mask);
@ -792,8 +793,9 @@ _cairo_image_surface_set_matrix (cairo_image_surface_t *surface,
return CAIRO_STATUS_SUCCESS;
}
static void
_cairo_image_surface_set_filter (cairo_image_surface_t *surface, cairo_filter_t filter)
static cairo_status_t
_cairo_image_surface_set_filter (cairo_image_surface_t *surface,
cairo_filter_t filter)
{
pixman_filter_t pixman_filter;
@ -823,7 +825,14 @@ _cairo_image_surface_set_filter (cairo_image_surface_t *surface, cairo_filter_t
pixman_filter = PIXMAN_FILTER_BEST;
}
pixman_image_set_filter (surface->pixman_image, pixman_filter, NULL, 0);
if (! pixman_image_set_filter (surface->pixman_image,
pixman_filter,
NULL, 0))
{
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
}
return CAIRO_STATUS_SUCCESS;
}
static cairo_status_t
@ -851,7 +860,9 @@ _cairo_image_surface_set_attributes (cairo_image_surface_t *surface,
break;
}
_cairo_image_surface_set_filter (surface, attributes->filter);
status = _cairo_image_surface_set_filter (surface, attributes->filter);
if (status)
return status;
return CAIRO_STATUS_SUCCESS;
}
@ -1058,8 +1069,7 @@ _cairo_image_surface_composite_trapezoids (cairo_operator_t op,
pixman_trapezoid_t stack_traps[CAIRO_STACK_ARRAY_LENGTH (pixman_trapezoid_t)];
pixman_trapezoid_t *pixman_traps = stack_traps;
int mask_stride;
int mask_bpp;
int ret, i;
int i;
if (height == 0 || width == 0)
return CAIRO_STATUS_SUCCESS;
@ -1123,18 +1133,14 @@ _cairo_image_surface_composite_trapezoids (cairo_operator_t op,
switch (antialias) {
case CAIRO_ANTIALIAS_NONE:
format = PIXMAN_a1;
ret = 1;
mask_stride = ((width + 31) / 8) & ~0x03;
mask_bpp = 1;
break;
case CAIRO_ANTIALIAS_GRAY:
case CAIRO_ANTIALIAS_SUBPIXEL:
case CAIRO_ANTIALIAS_DEFAULT:
default:
format = PIXMAN_a8;
ret = 1;
mask_stride = (width + 3) & ~3;
mask_bpp = 8;
break;
}

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

@ -488,7 +488,7 @@ cairo_matrix_invert (cairo_matrix_t *matrix)
/* inv (A) = 1/det (A) * adj (A) */
double det;
_cairo_matrix_compute_determinant (matrix, &det);
det = _cairo_matrix_compute_determinant (matrix);
if (! ISFINITE (det))
return _cairo_error (CAIRO_STATUS_INVALID_MATRIX);
@ -508,42 +508,54 @@ _cairo_matrix_is_invertible (const cairo_matrix_t *matrix)
{
double det;
_cairo_matrix_compute_determinant (matrix, &det);
det = _cairo_matrix_compute_determinant (matrix);
return ISFINITE (det) && det != 0.;
}
void
_cairo_matrix_compute_determinant (const cairo_matrix_t *matrix,
double *det)
double
_cairo_matrix_compute_determinant (const cairo_matrix_t *matrix)
{
double a, b, c, d;
a = matrix->xx; b = matrix->yx;
c = matrix->xy; d = matrix->yy;
*det = a*d - b*c;
return a*d - b*c;
}
/* Compute the amount that each basis vector is scaled by. */
/**
* _cairo_matrix_compute_basis_scale_factors:
* @matrix: a matrix
* @basis_scale: the scale factor in the direction of basis
* @normal_scale: the scale factor in the direction normal to the basis
* @x_basis: basis to use. X basis if true, Y basis otherwise.
*
* Computes |Mv| and det(M)/|Mv| for v=[1,0] if x_basis is true, and v=[0,1]
* otherwise, and M is @matrix.
*
* Return value: the scale factor of @matrix on the height of the font,
* or 1.0 if @matrix is %NULL.
**/
cairo_status_t
_cairo_matrix_compute_scale_factors (const cairo_matrix_t *matrix,
double *sx, double *sy, int x_major)
_cairo_matrix_compute_basis_scale_factors (const cairo_matrix_t *matrix,
double *basis_scale, double *normal_scale,
cairo_bool_t x_basis)
{
double det;
_cairo_matrix_compute_determinant (matrix, &det);
det = _cairo_matrix_compute_determinant (matrix);
if (! ISFINITE (det))
return _cairo_error (CAIRO_STATUS_INVALID_MATRIX);
if (det == 0)
{
*sx = *sy = 0;
*basis_scale = *normal_scale = 0;
}
else
{
double x = x_major != 0;
double x = x_basis != 0;
double y = x == 0;
double major, minor;
@ -558,15 +570,15 @@ _cairo_matrix_compute_scale_factors (const cairo_matrix_t *matrix,
minor = det / major;
else
minor = 0.0;
if (x_major)
if (x_basis)
{
*sx = major;
*sy = minor;
*basis_scale = major;
*normal_scale = minor;
}
else
{
*sx = minor;
*sy = major;
*basis_scale = minor;
*normal_scale = major;
}
}

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

@ -844,14 +844,12 @@ _cairo_meta_surface_replay_internal (cairo_surface_t *surface,
{
cairo_matrix_t dev_ctm = command->stroke.ctm;
cairo_matrix_t dev_ctm_inverse = command->stroke.ctm_inverse;
cairo_matrix_t tmp;
if (has_device_transform) {
cairo_matrix_multiply (&dev_ctm, &dev_ctm, device_transform);
tmp = surface->device_transform;
status = cairo_matrix_invert (&tmp);
assert (status == CAIRO_STATUS_SUCCESS);
cairo_matrix_multiply (&dev_ctm_inverse, &tmp, &dev_ctm_inverse);
cairo_matrix_multiply (&dev_ctm_inverse,
&surface->device_transform_inverse,
&dev_ctm_inverse);
}
status = _cairo_surface_stroke (target,
@ -885,17 +883,15 @@ _cairo_meta_surface_replay_internal (cairo_surface_t *surface,
_cairo_path_fixed_is_equal (dev_path, _cairo_command_get_path (stroke_command))) {
cairo_matrix_t dev_ctm;
cairo_matrix_t dev_ctm_inverse;
cairo_matrix_t tmp;
dev_ctm = stroke_command->stroke.ctm;
dev_ctm_inverse = stroke_command->stroke.ctm_inverse;
if (has_device_transform) {
cairo_matrix_multiply (&dev_ctm, &dev_ctm, device_transform);
tmp = surface->device_transform;
status = cairo_matrix_invert (&tmp);
assert (status == CAIRO_STATUS_SUCCESS);
cairo_matrix_multiply (&dev_ctm_inverse, &tmp, &dev_ctm_inverse);
cairo_matrix_multiply (&dev_ctm_inverse,
&surface->device_transform_inverse,
&dev_ctm_inverse);
}
status = _cairo_surface_fill_stroke (target,
@ -973,7 +969,6 @@ _cairo_meta_surface_replay_internal (cairo_surface_t *surface,
command->intersect_clip_path.tolerance,
command->intersect_clip_path.antialias,
target);
assert (status == 0);
break;
default:
ASSERT_NOT_REACHED;

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

@ -3,6 +3,7 @@
*
* Copyright © 2002 University of Southern California
* Copyright © 2005 Red Hat, Inc.
* Copyright © 2007 Adrian Johnson
*
* This library is free software; you can redistribute it and/or
* modify it either under the terms of the GNU Lesser General Public
@ -34,6 +35,7 @@
*
* Contributor(s):
* Carl D. Worth <cworth@cworth.org>
* Adrian Johnson <ajohnson@redneon.com>
*/
#include "cairoint.h"
@ -41,6 +43,8 @@
COMPILE_TIME_ASSERT (CAIRO_STATUS_LAST_STATUS < CAIRO_INT_STATUS_UNSUPPORTED);
COMPILE_TIME_ASSERT (CAIRO_INT_STATUS_LAST_STATUS <= 127);
/* Public stuff */
/**
* cairo_status_to_string:
* @status: a cairo status
@ -113,11 +117,191 @@ cairo_status_to_string (cairo_status_t status)
return "negative number used where it is not allowed";
case CAIRO_STATUS_INVALID_CLUSTERS:
return "input clusters do not represent the accompanying text and glyph arrays";
case CAIRO_STATUS_INVALID_SLANT:
return "invalid value for an input #cairo_font_slant_t";
case CAIRO_STATUS_INVALID_WEIGHT:
return "input value for an input #cairo_font_weight_t";
}
return "<unknown error status>";
}
/**
* cairo_glyph_allocate:
* @num_glyphs: number of glyphs to allocate
*
* Allocates an array of #cairo_glyph_t's.
* This function is only useful in implementations of
* #cairo_user_scaled_font_text_to_glyphs_func_t where the user
* needs to allocate an array of glyphs that cairo will free.
* For all other uses, user can use their own allocation method
* for glyphs.
*
* This function returns %NULL if @num_glyphs is not positive,
* or if out of memory. That means, the %NULL return value
* signals out-of-memory only if @num_glyphs was positive.
*
* Returns: the newly allocated array of glyphs that should be
* freed using cairo_glyph_free()
*
* Since: 1.8
*/
cairo_glyph_t *
cairo_glyph_allocate (int num_glyphs)
{
if (num_glyphs <= 0)
return NULL;
return _cairo_malloc_ab (num_glyphs, sizeof (cairo_glyph_t));
}
slim_hidden_def (cairo_glyph_allocate);
/**
* cairo_glyph_free:
* @glyphs: array of glyphs to free, or %NULL
*
* Frees an array of #cairo_glyph_t's allocated using cairo_glyph_allocate().
* This function is only useful to free glyph array returned
* by cairo_scaled_font_text_to_glyphs() where cairo returns
* an array of glyphs that the user will free.
* For all other uses, user can use their own allocation method
* for glyphs.
*
* Since: 1.8
*/
void
cairo_glyph_free (cairo_glyph_t *glyphs)
{
if (glyphs)
free (glyphs);
}
slim_hidden_def (cairo_glyph_free);
/**
* cairo_text_cluster_allocate:
* @num_clusters: number of text_clusters to allocate
*
* Allocates an array of #cairo_text_cluster_t's.
* This function is only useful in implementations of
* #cairo_user_scaled_font_text_to_glyphs_func_t where the user
* needs to allocate an array of text clusters that cairo will free.
* For all other uses, user can use their own allocation method
* for text clusters.
*
* This function returns %NULL if @num_clusters is not positive,
* or if out of memory. That means, the %NULL return value
* signals out-of-memory only if @num_clusters was positive.
*
* Returns: the newly allocated array of text clusters that should be
* freed using cairo_text_cluster_free()
*
* Since: 1.8
*/
cairo_text_cluster_t *
cairo_text_cluster_allocate (int num_clusters)
{
if (num_clusters <= 0)
return NULL;
return _cairo_malloc_ab (num_clusters, sizeof (cairo_text_cluster_t));
}
slim_hidden_def (cairo_text_cluster_allocate);
/**
* cairo_text_cluster_free:
* @clusters: array of text clusters to free, or %NULL
*
* Frees an array of #cairo_text_cluster's allocated using cairo_text_cluster_allocate().
* This function is only useful to free text cluster array returned
* by cairo_scaled_font_text_to_glyphs() where cairo returns
* an array of text clusters that the user will free.
* For all other uses, user can use their own allocation method
* for text clusters.
*
* Since: 1.8
*/
void
cairo_text_cluster_free (cairo_text_cluster_t *clusters)
{
if (clusters)
free (clusters);
}
slim_hidden_def (cairo_text_cluster_free);
/* Private stuff */
/**
* _cairo_validate_text_clusters:
* @utf8: UTF-8 text
* @utf8_len: length of @utf8 in bytes
* @glyphs: array of glyphs
* @num_glyphs: number of glyphs
* @clusters: array of cluster mapping information
* @num_clusters: number of clusters in the mapping
* @backward: whether the text to glyphs mapping goes backward
*
* Check that clusters cover the entire glyphs and utf8 arrays,
* and that cluster boundaries are UTF-8 boundaries.
*
* Return value: %CAIRO_STATUS_SUCCESS upon success, or
* %CAIRO_STATUS_INVALID_CLUSTERS on error.
* The error is either invalid UTF-8 input,
* or bad cluster mapping.
*/
cairo_status_t
_cairo_validate_text_clusters (const char *utf8,
int utf8_len,
const cairo_glyph_t *glyphs,
int num_glyphs,
const cairo_text_cluster_t *clusters,
int num_clusters,
cairo_bool_t backward)
{
cairo_status_t status;
unsigned int n_bytes = 0;
unsigned int n_glyphs = 0;
int i;
for (i = 0; i < num_clusters; i++) {
int cluster_bytes = clusters[i].num_bytes;
int cluster_glyphs = clusters[i].num_glyphs;
if (cluster_bytes < 0 || cluster_glyphs < 0)
goto BAD;
/* A cluster should cover at least one character or glyph.
* I can't see any use for a 0,0 cluster.
* I can't see an immediate use for a zero-text cluster
* right now either, but they don't harm.
* Zero-glyph clusters on the other hand are useful for
* things like U+200C ZERO WIDTH NON-JOINER */
if (cluster_bytes == 0 && cluster_glyphs == 0)
goto BAD;
/* Since n_bytes and n_glyphs are unsigned, but the rest of
* values involved are signed, we can detect overflow easily */
if (n_bytes+cluster_bytes > (unsigned int)utf8_len || n_glyphs+cluster_glyphs > (unsigned int)num_glyphs)
goto BAD;
/* Make sure we've got valid UTF-8 for the cluster */
status = _cairo_utf8_to_ucs4 (utf8+n_bytes, cluster_bytes, NULL, NULL);
if (status)
return CAIRO_STATUS_INVALID_CLUSTERS;
n_bytes += cluster_bytes ;
n_glyphs += cluster_glyphs;
}
if (n_bytes != (unsigned int) utf8_len || n_glyphs != (unsigned int) num_glyphs) {
BAD:
return CAIRO_STATUS_INVALID_CLUSTERS;
}
return CAIRO_STATUS_SUCCESS;
}
/**
* _cairo_operator_bounded_by_mask:
* @op: a #cairo_operator_t
@ -417,3 +601,69 @@ _cairo_lround (double d)
#undef MSW
#undef LSW
}
#ifdef _WIN32
#define WIN32_LEAN_AND_MEAN
/* We require Windows 2000 features such as ETO_PDY */
#if !defined(WINVER) || (WINVER < 0x0500)
# define WINVER 0x0500
#endif
#if !defined(_WIN32_WINNT) || (_WIN32_WINNT < 0x0500)
# define _WIN32_WINNT 0x0500
#endif
#include <windows.h>
#include <io.h>
/* tmpfile() replacment for Windows.
*
* On Windows tmpfile() creates the file in the root directory. This
* may fail due to unsufficient privileges.
*/
FILE *
_cairo_win32_tmpfile (void)
{
DWORD path_len;
WCHAR path_name[MAX_PATH + 1];
WCHAR file_name[MAX_PATH + 1];
HANDLE handle;
int fd;
FILE *fp;
path_len = GetTempPathW (MAX_PATH, path_name);
if (path_len <= 0 || path_len >= MAX_PATH)
return NULL;
if (GetTempFileNameW (path_name, L"ps_", 0, file_name) == 0)
return NULL;
handle = CreateFileW (file_name,
GENERIC_READ | GENERIC_WRITE,
0,
NULL,
CREATE_ALWAYS,
FILE_ATTRIBUTE_NORMAL | FILE_FLAG_DELETE_ON_CLOSE,
NULL);
if (handle == INVALID_HANDLE_VALUE) {
DeleteFileW (file_name);
return NULL;
}
fd = _open_osfhandle((intptr_t) handle, 0);
if (fd < 0) {
CloseHandle (handle);
return NULL;
}
fp = fdopen(fd, "w+b");
if (fp == NULL) {
_close(fd);
return NULL;
}
return fp;
}
#endif /* _WIN32 */

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

@ -45,10 +45,6 @@
#include "config.h"
#endif
#include "cairo-features.h"
CAIRO_BEGIN_DECLS
/* A fully qualified no-operation statement */
#define CAIRO_MUTEX_IMPL_NOOP do {/*no-op*/} while (0)
@ -221,6 +217,4 @@ CAIRO_BEGIN_DECLS
#endif
CAIRO_END_DECLS
#endif

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

@ -41,6 +41,10 @@
#ifndef CAIRO_MUTEX_PRIVATE_H
#define CAIRO_MUTEX_PRIVATE_H
#if HAVE_CONFIG_H
#include "config.h"
#endif
#include "cairo-mutex-type-private.h"
CAIRO_BEGIN_DECLS

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

@ -41,12 +41,6 @@
#ifndef CAIRO_MUTEX_TYPE_PRIVATE_H
#define CAIRO_MUTEX_TYPE_PRIVATE_H
#if HAVE_CONFIG_H
#include "config.h"
#endif
#include "cairo-features.h"
#include "cairo-compiler-private.h"
#include "cairo-mutex-impl-private.h"

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

@ -0,0 +1,12 @@
/* Generated by configure. Do not edit */
#ifndef CAIRO_NO_FEATURES_H
#define CAIRO_NO_FEATURES_H
#include <cairo-features.h>
/* This is a dummy header, to trick gtk-doc only */
#define CAIRO_HAS_WIN32_FONT 1
#define CAIRO_HAS_WIN32_SURFACE 1
#endif

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

@ -39,6 +39,10 @@
#include "cairo-compiler-private.h"
#include "cairo-types-private.h"
#include <stdlib.h>
#include <stdio.h>
#include <stdarg.h>
typedef cairo_status_t (*cairo_output_stream_write_func_t) (cairo_output_stream_t *output_stream,
const unsigned char *data,
unsigned int length);
@ -107,7 +111,7 @@ _cairo_output_stream_write (cairo_output_stream_t *stream,
cairo_private void
_cairo_output_stream_write_hex_string (cairo_output_stream_t *stream,
const char *data,
const unsigned char *data,
size_t length);
cairo_private void

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

@ -237,7 +237,7 @@ _cairo_output_stream_write (cairo_output_stream_t *stream,
void
_cairo_output_stream_write_hex_string (cairo_output_stream_t *stream,
const char *data,
const unsigned char *data,
size_t length)
{
const char hex_chars[] = "0123456789abcdef";
@ -423,7 +423,6 @@ _cairo_output_stream_vprintf (cairo_output_stream_t *stream,
/* Flush contents of buffer before snprintf()'ing into it. */
_cairo_output_stream_write (stream, buffer, p - buffer);
p = buffer;
/* We group signed and unsigned together in this switch, the
* only thing that matters here is the size of the arguments,

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

@ -609,7 +609,7 @@ _cairo_paginated_surface_has_show_text_glyphs (void *abstract_surface)
{
cairo_paginated_surface_t *surface = abstract_surface;
return _cairo_surface_has_show_text_glyphs (surface->target);
return cairo_surface_has_show_text_glyphs (surface->target);
}
static cairo_int_status_t

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

@ -36,6 +36,8 @@
#ifndef CAIRO_PATH_FIXED_PRIVATE_H
#define CAIRO_PATH_FIXED_PRIVATE_H
#include "cairo-types-private.h"
enum cairo_path_op {
CAIRO_PATH_OP_MOVE_TO = 0,
CAIRO_PATH_OP_LINE_TO = 1,

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

@ -169,11 +169,8 @@ _cairo_stroker_init (cairo_stroker_t *stroker,
stroker->tolerance = tolerance;
stroker->traps = traps;
_cairo_matrix_compute_determinant (stroker->ctm, &stroker->ctm_determinant);
if (stroker->ctm_determinant >= 0.0)
stroker->ctm_det_positive = TRUE;
else
stroker->ctm_det_positive = FALSE;
stroker->ctm_determinant = _cairo_matrix_compute_determinant (stroker->ctm);
stroker->ctm_det_positive = stroker->ctm_determinant >= 0.0;
status = _cairo_pen_init (&stroker->pen,
stroke_style->line_width / 2.0,

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

@ -95,9 +95,12 @@ static void
_cairo_pattern_init (cairo_pattern_t *pattern, cairo_pattern_type_t type)
{
pattern->type = type;
CAIRO_REFERENCE_COUNT_INIT (&pattern->ref_count, 1);
pattern->status = CAIRO_STATUS_SUCCESS;
/* Set the reference count to zero for on-stack patterns.
* Callers needs to explicitly increment the count for heap allocations. */
CAIRO_REFERENCE_COUNT_INIT (&pattern->ref_count, 0);
_cairo_user_data_array_init (&pattern->user_data);
if (type == CAIRO_PATTERN_TYPE_SURFACE)
@ -183,7 +186,7 @@ _cairo_pattern_init_copy (cairo_pattern_t *pattern,
}
/* The reference count and user_data array are unique to the copy. */
CAIRO_REFERENCE_COUNT_INIT (&pattern->ref_count, 1);
CAIRO_REFERENCE_COUNT_INIT (&pattern->ref_count, 0);
_cairo_user_data_array_init (&pattern->user_data);
return CAIRO_STATUS_SUCCESS;
@ -246,6 +249,8 @@ _cairo_pattern_create_copy (cairo_pattern_t **pattern,
return status;
}
CAIRO_REFERENCE_COUNT_INIT (&(*pattern)->ref_count, 1);
return CAIRO_STATUS_SUCCESS;
}
@ -350,8 +355,10 @@ _cairo_pattern_create_solid (const cairo_color_t *color,
if (pattern == NULL) {
_cairo_error_throw (CAIRO_STATUS_NO_MEMORY);
pattern = (cairo_solid_pattern_t *) &_cairo_pattern_nil;
} else
} else {
_cairo_pattern_init_solid (pattern, color, content);
CAIRO_REFERENCE_COUNT_INIT (&pattern->base.ref_count, 1);
}
return &pattern->base;
}
@ -504,6 +511,7 @@ cairo_pattern_create_for_surface (cairo_surface_t *surface)
CAIRO_MUTEX_INITIALIZE ();
_cairo_pattern_init_for_surface (pattern, surface);
CAIRO_REFERENCE_COUNT_INIT (&pattern->base.ref_count, 1);
return &pattern->base;
}
@ -549,6 +557,7 @@ cairo_pattern_create_linear (double x0, double y0, double x1, double y1)
CAIRO_MUTEX_INITIALIZE ();
_cairo_pattern_init_linear (pattern, x0, y0, x1, y1);
CAIRO_REFERENCE_COUNT_INIT (&pattern->base.base.ref_count, 1);
return &pattern->base.base;
}
@ -596,6 +605,7 @@ cairo_pattern_create_radial (double cx0, double cy0, double radius0,
CAIRO_MUTEX_INITIALIZE ();
_cairo_pattern_init_radial (pattern, cx0, cy0, radius0, cx1, cy1, radius1);
CAIRO_REFERENCE_COUNT_INIT (&pattern->base.base.ref_count, 1);
return &pattern->base.base;
}
@ -1308,6 +1318,13 @@ _cairo_pattern_acquire_surface_for_gradient (cairo_gradient_pattern_t *pattern,
}
}
if (! pixman_image_set_filter (pixman_image, PIXMAN_FILTER_BILINEAR,
NULL, 0))
{
pixman_image_unref (pixman_image);
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
}
image = (cairo_image_surface_t *)
cairo_image_surface_create (CAIRO_FORMAT_ARGB32, width, height);
if (image->base.status) {
@ -1315,8 +1332,6 @@ _cairo_pattern_acquire_surface_for_gradient (cairo_gradient_pattern_t *pattern,
return image->base.status;
}
pixman_image_set_filter (pixman_image, PIXMAN_FILTER_BILINEAR, NULL, 0);
_cairo_matrix_to_pixman_matrix (&pattern->base.matrix, &pixman_transform);
if (!pixman_image_set_transform (pixman_image, &pixman_transform)) {
cairo_surface_destroy (&image->base);
@ -2078,10 +2093,11 @@ _cairo_pattern_get_extents (cairo_pattern_t *pattern,
* horizontal/vertical linear gradients).
*/
/* unbounded patterns -> 'infinite' extents */
extents->x = CAIRO_RECT_INT_MIN;
extents->y = CAIRO_RECT_INT_MIN;
extents->width = CAIRO_RECT_INT_MIN + CAIRO_RECT_INT_MAX;
extents->height = CAIRO_RECT_INT_MIN + CAIRO_RECT_INT_MAX;
extents->width = CAIRO_RECT_INT_MAX - CAIRO_RECT_INT_MIN;
extents->height = CAIRO_RECT_INT_MAX - CAIRO_RECT_INT_MIN;
return CAIRO_STATUS_SUCCESS;
}

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

@ -162,5 +162,4 @@ _cairo_pdf_operators_show_text_glyphs (cairo_pdf_operators_t *pdf_operators,
cairo_bool_t backward,
cairo_scaled_font_t *scaled_font);
#endif /* CAIRO_PDF_OPERATORS_H */

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

@ -40,6 +40,9 @@
*/
#include "cairoint.h"
#if CAIRO_HAS_PDF_OPERATORS
#include "cairo-pdf-operators-private.h"
#include "cairo-path-fixed-private.h"
#include "cairo-output-stream-private.h"
@ -683,15 +686,18 @@ _cairo_pdf_operators_emit_stroke (cairo_pdf_operators_t *pdf_operators,
cairo_stroke_style_t *style,
cairo_matrix_t *ctm,
cairo_matrix_t *ctm_inverse,
const char *pdf_operator)
const char *pdf_operator)
{
cairo_status_t status;
cairo_matrix_t m, path_transform;
cairo_bool_t has_ctm = TRUE;
double scale = 1.0;
if (pdf_operators->in_text_object)
if (pdf_operators->in_text_object) {
status = _cairo_pdf_operators_end_text (pdf_operators);
if (status)
return status;
}
/* Optimize away the stroke ctm when it does not affect the
* stroke. There are other ctm cases that could be optimized
@ -788,8 +794,11 @@ _cairo_pdf_operators_fill (cairo_pdf_operators_t *pdf_operators,
const char *pdf_operator;
cairo_status_t status;
if (pdf_operators->in_text_object)
if (pdf_operators->in_text_object) {
status = _cairo_pdf_operators_end_text (pdf_operators);
if (status)
return status;
}
status = _cairo_pdf_operators_emit_path (pdf_operators,
path,
@ -927,12 +936,12 @@ static cairo_status_t
_cairo_pdf_operators_flush_glyphs (cairo_pdf_operators_t *pdf_operators)
{
cairo_output_stream_t *word_wrap_stream;
cairo_status_t status;
cairo_status_t status, status2;
int i;
double x;
if (pdf_operators->num_glyphs == 0)
return 0;
return CAIRO_STATUS_SUCCESS;
word_wrap_stream = _word_wrap_stream_create (pdf_operators->stream, 72);
status = _cairo_output_stream_get_status (word_wrap_stream);
@ -955,9 +964,9 @@ _cairo_pdf_operators_flush_glyphs (cairo_pdf_operators_t *pdf_operators)
}
pdf_operators->num_glyphs = 0;
status = _cairo_output_stream_destroy (word_wrap_stream);
if (status)
return status;
status2 = _cairo_output_stream_destroy (word_wrap_stream);
if (status == CAIRO_STATUS_SUCCESS)
status = status2;
return status;
}
@ -1266,7 +1275,7 @@ _cairo_pdf_operators_emit_cluster (cairo_pdf_operators_t *pdf_operators,
scaled_font,
glyphs->index,
utf8,
utf8_len < 0 ? 0 : utf8_len,
utf8_len,
&subset_glyph);
if (status)
return status;
@ -1275,7 +1284,10 @@ _cairo_pdf_operators_emit_cluster (cairo_pdf_operators_t *pdf_operators,
status = _cairo_pdf_operators_emit_glyph (pdf_operators,
glyphs,
&subset_glyph);
return 0;
if (status)
return status;
return CAIRO_STATUS_SUCCESS;
}
}
@ -1283,12 +1295,17 @@ _cairo_pdf_operators_emit_cluster (cairo_pdf_operators_t *pdf_operators,
* unicode string. */
_cairo_pdf_operators_flush_glyphs (pdf_operators);
status = _cairo_pdf_operators_begin_actualtext (pdf_operators, utf8, utf8_len);
if (status)
return status;
cur_glyph = glyphs;
/* XXX
* If no glyphs, we should put *something* here for the text to be selectable. */
for (i = 0; i < num_glyphs; i++) {
status = _cairo_scaled_font_subsets_map_glyph (pdf_operators->font_subsets,
scaled_font,
cur_glyph->index,
NULL, 0,
NULL, -1,
&subset_glyph);
if (status)
return status;
@ -1411,3 +1428,5 @@ _cairo_pdf_operators_show_text_glyphs (cairo_pdf_operators_t *pdf_operators,
return _cairo_output_stream_get_status (pdf_operators->stream);
}
#endif /* CAIRO_HAS_PDF_OPERATORS */

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

@ -2868,7 +2868,7 @@ _cairo_pdf_surface_emit_unicode_for_glyph (cairo_pdf_surface_t *surface,
if (utf8 && *utf8) {
status = _cairo_utf8_to_utf16 (utf8, -1, &utf16, &utf16_len);
if (status && status != CAIRO_STATUS_INVALID_STRING)
if (status)
return status;
}
@ -3444,7 +3444,7 @@ static cairo_status_t
_cairo_pdf_emit_imagemask (cairo_image_surface_t *image,
cairo_output_stream_t *stream)
{
unsigned char *byte, output_byte;
uint8_t *byte, output_byte;
int row, col, num_cols;
/* The only image type supported by Type 3 fonts are 1-bit image
@ -3487,7 +3487,6 @@ _cairo_pdf_surface_emit_type3_font_subset (cairo_pdf_surface_t *surface,
cairo_status_t status = CAIRO_STATUS_SUCCESS;
cairo_pdf_resource_t *glyphs, encoding, char_procs, subset_resource, to_unicode_stream;
cairo_pdf_font_t font;
cairo_matrix_t matrix;
double *widths;
unsigned int i;
cairo_box_t font_bbox = {{0,0},{0,0}};
@ -3522,6 +3521,9 @@ _cairo_pdf_surface_emit_type3_font_subset (cairo_pdf_surface_t *surface,
NULL,
surface->compress_content,
NULL);
if (status)
break;
glyphs[i] = surface->pdf_stream.self;
if (i == 0) {
status = _cairo_type3_glyph_surface_emit_notdef_glyph (type3_surface,
@ -3535,6 +3537,9 @@ _cairo_pdf_surface_emit_type3_font_subset (cairo_pdf_surface_t *surface,
&bbox,
&widths[i]);
}
if (status)
break;
status = _cairo_pdf_surface_close_stream (surface);
if (status)
break;
@ -3610,7 +3615,6 @@ _cairo_pdf_surface_emit_type3_font_subset (cairo_pdf_surface_t *surface,
}
_cairo_pdf_surface_update_object (surface, subset_resource);
matrix = font_subset->scaled_font->scale_inverse;
_cairo_output_stream_printf (surface->output,
"%d 0 obj\n"
"<< /Type /Font\n"
@ -4783,8 +4787,8 @@ _cairo_pdf_surface_show_text_glyphs (void *abstract_surface,
group->source_res = pattern_res;
if (utf8_len) {
group->utf8 = malloc(utf8_len);
if (group->utf8) {
group->utf8 = malloc (utf8_len);
if (group->utf8 == NULL) {
_cairo_pdf_smask_group_destroy (group);
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
}
@ -4804,7 +4808,7 @@ _cairo_pdf_surface_show_text_glyphs (void *abstract_surface,
if (num_clusters) {
group->clusters = _cairo_malloc_ab (num_clusters, sizeof (cairo_text_cluster_t));
if (group->clusters) {
if (group->clusters == NULL) {
_cairo_pdf_smask_group_destroy (group);
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
}

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

@ -53,17 +53,11 @@ _cairo_pen_init (cairo_pen_t *pen,
{
int i;
int reflect;
double det;
pen->radius = radius;
pen->tolerance = tolerance;
_cairo_matrix_compute_determinant (ctm, &det);
if (det >= 0) {
reflect = 0;
} else {
reflect = 1;
}
reflect = _cairo_matrix_compute_determinant (ctm) < 0.;
pen->num_vertices = _cairo_pen_vertices_needed (tolerance,
radius,

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

@ -119,6 +119,13 @@ png_simple_warning_callback (png_structp png,
}
/* Starting with libpng-1.2.30, we must explicitly specify an output_flush_fn.
* Otherwise, we will segfault if we are writing to a stream. */
static void
png_simple_output_flush_fn (png_structp png_ptr)
{
}
static cairo_status_t
write_png (cairo_surface_t *surface,
png_rw_ptr write_func,
@ -130,7 +137,6 @@ write_png (cairo_surface_t *surface,
void *image_extra;
png_struct *png;
png_info *info;
png_time pt;
png_byte **volatile rows = NULL;
png_color_16 white;
int png_color_type;
@ -179,7 +185,7 @@ write_png (cairo_surface_t *surface,
goto BAIL3;
#endif
png_set_write_fn (png, closure, write_func, NULL);
png_set_write_fn (png, closure, write_func, png_simple_output_flush_fn);
switch (image->format) {
case CAIRO_FORMAT_ARGB32:
@ -218,8 +224,12 @@ write_png (cairo_surface_t *surface,
white.red = white.blue = white.green = white.gray;
png_set_bKGD (png, info, &white);
png_convert_from_time_t (&pt, time (NULL));
png_set_tIME (png, info, &pt);
if (0) { /* XXX extract meta-data from surface (i.e. creation date) */
png_time pt;
png_convert_from_time_t (&pt, time (NULL));
png_set_tIME (png, info, &pt);
}
/* We have to call png_write_info() before setting up the write
* transformation, since it stores data internally in 'png'

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

@ -46,6 +46,8 @@
#include "cairo-surface-private.h"
#include "cairo-pdf-operators-private.h"
#include <time.h>
typedef struct cairo_ps_surface {
cairo_surface_t base;
@ -80,6 +82,8 @@ typedef struct cairo_ps_surface {
cairo_paginated_mode_t paginated_mode;
cairo_bool_t force_fallbacks;
cairo_bool_t has_creation_date;
time_t creation_date;
cairo_scaled_font_subsets_t *font_subsets;

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

@ -90,7 +90,10 @@ _cairo_ps_surface_emit_header (cairo_ps_surface_t *surface)
int level;
const char *eps_header = "";
now = time (NULL);
if (surface->has_creation_date)
now = surface->creation_date;
else
now = time (NULL);
if (surface->ps_level_used == CAIRO_PS_LEVEL_2)
level = 2;
@ -364,7 +367,7 @@ _cairo_ps_surface_emit_truetype_font_subset (cairo_ps_surface_t *surface,
subset.data + begin, end - begin);
_cairo_output_stream_printf (surface->final_stream,"00>\n");
begin = end;
}
}
if (subset.data_length > end) {
_cairo_output_stream_printf (surface->final_stream,"<");
_cairo_output_stream_write_hex_string (surface->final_stream,
@ -385,7 +388,7 @@ static cairo_status_t
_cairo_ps_emit_imagemask (cairo_image_surface_t *image,
cairo_output_stream_t *stream)
{
unsigned char *row, *byte;
uint8_t *row, *byte;
int rows, cols;
/* The only image type supported by Type 3 fonts are 1-bit image
@ -407,18 +410,15 @@ _cairo_ps_emit_imagemask (cairo_image_surface_t *image,
image->height);
_cairo_output_stream_printf (stream,
" /DataSource {<");
" /DataSource {<\n ");
for (row = image->data, rows = image->height; rows; row += image->stride, rows--) {
for (byte = row, cols = (image->width + 7) / 8; cols; byte++, cols--) {
unsigned char output_byte = CAIRO_BITSWAP8_IF_LITTLE_ENDIAN (*byte);
uint8_t output_byte = CAIRO_BITSWAP8_IF_LITTLE_ENDIAN (*byte);
_cairo_output_stream_printf (stream, "%02x ", output_byte);
}
_cairo_output_stream_printf (stream, "\n ");
}
_cairo_output_stream_printf (stream,
" >}\n");
_cairo_output_stream_printf (stream,
">>\n");
_cairo_output_stream_printf (stream, ">}\n>>\n");
_cairo_output_stream_printf (stream,
"imagemask\n");
@ -433,7 +433,6 @@ _cairo_ps_surface_emit_type3_font_subset (cairo_ps_surface_t *surface,
{
cairo_status_t status;
cairo_matrix_t matrix;
unsigned int i;
cairo_box_t font_bbox = {{0,0},{0,0}};
cairo_box_t bbox = {{0,0},{0,0}};
@ -445,7 +444,6 @@ _cairo_ps_surface_emit_type3_font_subset (cairo_ps_surface_t *surface,
"%% _cairo_ps_surface_emit_type3_font_subset\n");
#endif
matrix = font_subset->scaled_font->scale_inverse;
_cairo_output_stream_printf (surface->final_stream,
"8 dict begin\n"
"/FontType 3 def\n"
@ -618,6 +616,9 @@ _cairo_ps_surface_emit_body (cairo_ps_surface_t *surface)
while ((n = fread (buf, 1, sizeof (buf), surface->tmpfile)) > 0)
_cairo_output_stream_write (surface->final_stream, buf, n);
if (ferror (surface->tmpfile) != 0)
return _cairo_error (CAIRO_STATUS_TEMP_FILE_ERROR);
return CAIRO_STATUS_SUCCESS;
}
@ -681,6 +682,7 @@ _cairo_ps_surface_create_for_stream_internal (cairo_output_stream_t *stream,
goto CLEANUP_OUTPUT_STREAM;
}
surface->has_creation_date = FALSE;
surface->eps = FALSE;
surface->ps_level = CAIRO_PS_LEVEL_3;
surface->ps_level_used = CAIRO_PS_LEVEL_2;
@ -1585,7 +1587,10 @@ _string_array_stream_write (cairo_output_stream_t *base,
_cairo_output_stream_write (stream->output, &c, 1);
stream->column++;
stream->string_size++;
length--;
if (length-- == 0)
break;
c = *data++;
}
_cairo_output_stream_write (stream->output, &c, 1);
@ -2231,11 +2236,13 @@ _cairo_ps_surface_paint_surface (cairo_ps_surface_t *surface,
cairo_matrix_translate (&ps_p2d, 0.0, height);
cairo_matrix_scale (&ps_p2d, 1.0, -1.0);
_cairo_output_stream_printf (surface->stream,
"[ %f %f %f %f %f %f ] concat\n",
ps_p2d.xx, ps_p2d.yx,
ps_p2d.xy, ps_p2d.yy,
ps_p2d.x0, ps_p2d.y0);
if (! _cairo_matrix_is_identity (&ps_p2d)) {
_cairo_output_stream_printf (surface->stream,
"[ %f %f %f %f %f %f ] concat\n",
ps_p2d.xx, ps_p2d.yx,
ps_p2d.xy, ps_p2d.yy,
ps_p2d.x0, ps_p2d.y0);
}
status = _cairo_ps_surface_emit_surface (surface, pattern, op);
_cairo_ps_surface_release_surface (surface, pattern);
@ -2705,17 +2712,17 @@ _cairo_ps_surface_emit_linear_pattern (cairo_ps_surface_t *surface,
" << /ShadingType 2\n"
" /ColorSpace /DeviceRGB\n"
" /Coords [ %f %f %f %f ]\n"
" /Domain [ %f %f ]\r\n"
" /Domain [ %f %f ]\n"
" /Function CairoFunction\n",
x1, y1, x2, y2,
first_stop, last_stop);
if (extend == CAIRO_EXTEND_PAD) {
_cairo_output_stream_printf (surface->stream,
" /Extend [ true true ]\r\n");
" /Extend [ true true ]\n");
} else {
_cairo_output_stream_printf (surface->stream,
" /Extend [ false false ]\r\n");
" /Extend [ false false ]\n");
}
_cairo_output_stream_printf (surface->stream,
@ -2787,10 +2794,10 @@ _cairo_ps_surface_emit_radial_pattern (cairo_ps_surface_t *surface,
if (extend == CAIRO_EXTEND_PAD) {
_cairo_output_stream_printf (surface->stream,
" /Extend [ true true ]\r\n");
" /Extend [ true true ]\n");
} else {
_cairo_output_stream_printf (surface->stream,
" /Extend [ false false ]\r\n");
" /Extend [ false false ]\n");
}
_cairo_output_stream_printf (surface->stream,

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

@ -390,7 +390,7 @@ _cairo_matrix_to_unit_quartz_matrix (const cairo_matrix_t *m, CGAffineTransform
double xscale, yscale;
cairo_status_t status;
status = _cairo_matrix_compute_scale_factors (m, &xscale, &yscale, 1);
status = _cairo_matrix_compute_basis_scale_factors (m, &xscale, &yscale, 1);
if (status)
return status;
@ -435,7 +435,7 @@ _cairo_quartz_init_glyph_metrics (cairo_quartz_scaled_font_t *font,
!CGFontGetGlyphBBoxesPtr (font_face->cgFont, &glyph, 1, &bbox))
goto FAIL;
status = _cairo_matrix_compute_scale_factors (&font->base.scale,
status = _cairo_matrix_compute_basis_scale_factors (&font->base.scale,
&xscale, &yscale, 1);
if (status)
goto FAIL;
@ -632,7 +632,7 @@ _cairo_quartz_init_glyph_surface (cairo_quartz_scaled_font_t *font,
return CAIRO_INT_STATUS_UNSUPPORTED;
}
status = _cairo_matrix_compute_scale_factors (&font->base.scale,
status = _cairo_matrix_compute_basis_scale_factors (&font->base.scale,
&xscale, &yscale, 1);
if (status)
return status;

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

@ -37,6 +37,10 @@
#ifndef CAIRO_REFRENCE_COUNT_PRIVATE_H
#define CAIRO_REFRENCE_COUNT_PRIVATE_H
#if HAVE_CONFIG_H
#include "config.h"
#endif
#include "cairo-atomic-private.h"
CAIRO_BEGIN_DECLS

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

@ -40,6 +40,7 @@
#include <pixman.h>
#include "cairo-compiler-private.h"
#include "cairo-types-private.h"
/* #cairo_region_t is defined in cairoint.h */

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

@ -14,11 +14,6 @@
#define cairo_copy_path_flat _moz_cairo_copy_path_flat
#define cairo_create _moz_cairo_create
#define cairo_curve_to _moz_cairo_curve_to
#define cairo_debug_dump_clip _moz_cairo_debug_dump_clip
#define cairo_debug_dump_path _moz_cairo_debug_dump_path
#define cairo_debug_dump_trapezoid_array _moz_cairo_debug_dump_trapezoid_array
#define cairo_debug_dump_traps _moz_cairo_debug_dump_traps
#define cairo_debug_reset_static_data _moz_cairo_debug_reset_static_data
#define cairo_debug_reset_static_data _moz_cairo_debug_reset_static_data
#define cairo_destroy _moz_cairo_destroy
#define cairo_device_to_user _moz_cairo_device_to_user
@ -42,12 +37,14 @@
#define cairo_font_options_get_antialias _moz_cairo_font_options_get_antialias
#define cairo_font_options_get_hint_metrics _moz_cairo_font_options_get_hint_metrics
#define cairo_font_options_get_hint_style _moz_cairo_font_options_get_hint_style
#define cairo_font_options_get_lcd_filter _moz_cairo_font_options_get_lcd_filter
#define cairo_font_options_get_subpixel_order _moz_cairo_font_options_get_subpixel_order
#define cairo_font_options_hash _moz_cairo_font_options_hash
#define cairo_font_options_merge _moz_cairo_font_options_merge
#define cairo_font_options_set_antialias _moz_cairo_font_options_set_antialias
#define cairo_font_options_set_hint_metrics _moz_cairo_font_options_set_hint_metrics
#define cairo_font_options_set_hint_style _moz_cairo_font_options_set_hint_style
#define cairo_font_options_set_lcd_filter _moz_cairo_font_options_set_lcd_filter
#define cairo_font_options_set_subpixel_order _moz_cairo_font_options_set_subpixel_order
#define cairo_font_options_status _moz_cairo_font_options_status
#define cairo_format_stride_for_width _moz_cairo_format_stride_for_width
@ -78,7 +75,9 @@
#define cairo_get_tolerance _moz_cairo_get_tolerance
#define cairo_get_user_data _moz_cairo_get_user_data
#define cairo_glitz_surface_create _moz_cairo_glitz_surface_create
#define cairo_glyph_allocate _moz_cairo_glyph_allocate
#define cairo_glyph_extents _moz_cairo_glyph_extents
#define cairo_glyph_free _moz_cairo_glyph_free
#define cairo_glyph_path _moz_cairo_glyph_path
#define cairo_has_current_point _moz_cairo_has_current_point
#define cairo_has_show_text_glyphs _moz_cairo_has_show_text_glyphs
@ -168,6 +167,12 @@
#define cairo_ps_surface_set_size _moz_cairo_ps_surface_set_size
#define cairo_push_group _moz_cairo_push_group
#define cairo_push_group_with_content _moz_cairo_push_group_with_content
#define cairo_qpainter_surface_create _moz_cairo_qpainter_surface_create
#define cairo_qpainter_surface_create_with_qimage _moz_cairo_qpainter_surface_create_with_qimage
#define cairo_qpainter_surface_create_with_qpixmap _moz_cairo_qpainter_surface_create_with_qpixmap
#define cairo_qpainter_surface_get_image _moz_cairo_qpainter_surface_get_image
#define cairo_qpainter_surface_get_qimage _moz_cairo_qpainter_surface_get_qimage
#define cairo_qpainter_surface_get_qpainter _moz_cairo_qpainter_surface_get_qpainter
#define cairo_quartz_font_face_create_for_atsu_font_id _moz_cairo_quartz_font_face_create_for_atsu_font_id
#define cairo_quartz_font_face_create_for_cgfont _moz_cairo_quartz_font_face_create_for_cgfont
#define cairo_quartz_image_surface_create _moz_cairo_quartz_image_surface_create
@ -202,6 +207,7 @@
#define cairo_scaled_font_set_user_data _moz_cairo_scaled_font_set_user_data
#define cairo_scaled_font_status _moz_cairo_scaled_font_status
#define cairo_scaled_font_text_extents _moz_cairo_scaled_font_text_extents
#define cairo_scaled_font_text_to_glyphs _moz_cairo_scaled_font_text_to_glyphs
#define cairo_select_font_face _moz_cairo_select_font_face
#define cairo_set_antialias _moz_cairo_set_antialias
#define cairo_set_dash _moz_cairo_set_dash
@ -245,6 +251,7 @@
#define cairo_surface_get_reference_count _moz_cairo_surface_get_reference_count
#define cairo_surface_get_type _moz_cairo_surface_get_type
#define cairo_surface_get_user_data _moz_cairo_surface_get_user_data
#define cairo_surface_has_show_text_glyphs _moz_cairo_surface_has_show_text_glyphs
#define cairo_surface_mark_dirty _moz_cairo_surface_mark_dirty
#define cairo_surface_mark_dirty_rectangle _moz_cairo_surface_mark_dirty_rectangle
#define cairo_surface_reference _moz_cairo_surface_reference
@ -260,8 +267,14 @@
#define cairo_svg_surface_create_for_stream _moz_cairo_svg_surface_create_for_stream
#define cairo_svg_surface_restrict_to_version _moz_cairo_svg_surface_restrict_to_version
#define cairo_svg_version_to_string _moz_cairo_svg_version_to_string
#define cairo_text_cluster_allocate _moz_cairo_text_cluster_allocate
#define cairo_text_cluster_free _moz_cairo_text_cluster_free
#define cairo_text_extents _moz_cairo_text_extents
#define cairo_text_path _moz_cairo_text_path
#define cairo_toy_font_face_create _moz_cairo_toy_font_face_create
#define cairo_toy_font_face_get_family _moz_cairo_toy_font_face_get_family
#define cairo_toy_font_face_get_slant _moz_cairo_toy_font_face_get_slant
#define cairo_toy_font_face_get_weight _moz_cairo_toy_font_face_get_weight
#define cairo_transform _moz_cairo_transform
#define cairo_translate _moz_cairo_translate
#define cairo_user_font_face_create _moz_cairo_user_font_face_create
@ -374,14 +387,14 @@
#define pixman_image_set_source_clipping _moz_pixman_image_set_source_clipping
#define pixman_image_set_alpha_map _moz_pixman_image_set_alpha_map
#define pixman_image_set_component_alpha _moz_pixman_image_set_component_alpha
#define pixman_image_set_accessors _moz_pixman_image_set_accessors
#define pixman_image_set_indexed _moz_pixman_image_set_indexed
#define pixman_image_set_accessors _moz_pixman_image_set_accessors
#define pixman_image_set_indexed _moz_pixman_image_set_indexed
#define pixman_image_get_data _moz_pixman_image_get_data
#define pixman_image_get_width _moz_pixman_image_get_width
#define pixman_image_get_height _moz_pixman_image_get_height
#define pixman_image_get_stride _moz_pixman_image_get_stride
#define pixman_image_get_depth _moz_pixman_image_get_depth
#define pixman_image_fill_rectangles _moz_pixman_image_fill_rectangles
#define pixman_image_fill_rectangles _moz_pixman_image_fill_rectangles
#define pixman_compute_composite_region _moz_pixman_compute_composite_region
#define pixman_image_composite _moz_pixman_image_composite
#define pixman_sample_ceil_y _moz_pixman_sample_ceil_y

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

@ -39,6 +39,8 @@
#include "cairoint.h"
#if CAIRO_HAS_FONT_SUBSET
typedef struct _cairo_scaled_font_subsets_glyph {
unsigned int font_id;
unsigned int subset_id;
@ -127,12 +129,10 @@ _cairo_scaled_font_subsets_destroy (cairo_scaled_font_subsets_t *font_subsets);
* @font_subsets: a #cairo_scaled_font_subsets_t
* @scaled_font: the font of the glyph to be mapped
* @scaled_font_glyph_index: the index of the glyph to be mapped
* @utf8: a string of text encoded in UTF-8
* @utf8_len: length of @utf8 in bytes
* @subset_glyph_ret: return structure containing subset font and glyph id
*
* @font_id_ret: return value giving the font ID of the mapped glyph
* @subset_id_ret: return value giving the subset ID of the mapped glyph within the @font_id_ret
* @subset_glyph_index_ret: return value giving the index of the mapped glyph within the @subset_id_ret subset
*
* Map a glyph from a #cairo_scaled_font to a new index within a
* subset of that font. The mapping performed is from the tuple:
*
@ -170,6 +170,14 @@ _cairo_scaled_font_subsets_destroy (cairo_scaled_font_subsets_t *font_subsets);
* used by #cairo_scaled_font_subset_t as provided by
* _cairo_scaled_font_subsets_foreach.
*
* @utf8 and @utf8_len specify a string of unicode characters that the
* glyph @scaled_font_glyph_index maps to. If @utf8_is_mapped in
* @subset_glyph_ret is %TRUE, the font subsetting will (where index to
* unicode mapping is supported) ensure that @scaled_font_glyph_index
* maps to @utf8. If @utf8_is_mapped is %FALSE,
* @scaled_font_glyph_index has already been mapped to a different
* unicode string.
*
* The returned values in the #cairo_scaled_font_subsets_glyph_t struct are:
*
* @font_id: The font ID of the mapped glyph
@ -365,7 +373,7 @@ typedef struct _cairo_truetype_subset {
double *widths;
double x_min, y_min, x_max, y_max;
double ascent, descent;
char *data;
unsigned char *data;
unsigned long data_length;
unsigned long *string_offsets;
unsigned long num_string_offsets;
@ -415,6 +423,9 @@ typedef struct _cairo_type1_subset {
unsigned long trailer_length;
} cairo_type1_subset_t;
#if CAIRO_HAS_FT_FONT
/**
* _cairo_type1_subset_init:
* @type1_subset: a #cairo_type1_subset_t to initialize
@ -448,6 +459,9 @@ _cairo_type1_subset_init (cairo_type1_subset_t *type_subset,
cairo_private void
_cairo_type1_subset_fini (cairo_type1_subset_t *subset);
#endif /* CAIRO_HAS_FT_FONT */
/**
* _cairo_type1_scaled_font_is_type1:
* @scaled_font: a #cairo_scaled_font_t
@ -586,4 +600,6 @@ _cairo_truetype_index_to_ucs4 (cairo_scaled_font_t *scaled_font,
unsigned long index,
uint32_t *ucs4);
#endif /* CAIRO_HAS_FONT_SUBSET */
#endif /* CAIRO_SCALED_FONT_SUBSETS_PRIVATE_H */

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

@ -42,6 +42,9 @@
#define _BSD_SOURCE /* for snprintf(), strdup() */
#include "cairoint.h"
#if CAIRO_HAS_FONT_SUBSET
#include "cairo-scaled-font-subsets-private.h"
#include "cairo-user-font-private.h"
@ -280,7 +283,7 @@ _cairo_sub_font_create (cairo_scaled_font_subsets_t *parent,
sub_font->next = NULL;
/* Reserve first glyph in subset for the .notdef glyph */
status = _cairo_sub_font_map_glyph (sub_font, 0, NULL, 0, &subset_glyph);
status = _cairo_sub_font_map_glyph (sub_font, 0, NULL, -1, &subset_glyph);
if (status) {
_cairo_hash_table_destroy (sub_font->sub_font_glyphs);
free (sub_font);
@ -324,23 +327,31 @@ _cairo_sub_font_glyph_lookup_unicode (cairo_sub_font_glyph_t *sub_font_glyph,
/* Do a reverse lookup on the glyph index. unicode is -1 if the
* index could not be mapped to a unicode character. */
status = _cairo_truetype_index_to_ucs4 (scaled_font, scaled_font_glyph_index, &unicode);
unicode = -1;
status = _cairo_truetype_index_to_ucs4 (scaled_font,
scaled_font_glyph_index,
&unicode);
if (status && status != CAIRO_INT_STATUS_UNSUPPORTED)
return status;
if (status == CAIRO_INT_STATUS_UNSUPPORTED)
unicode = -1;
if (unicode == (uint32_t)-1 && scaled_font->backend->index_to_ucs4)
status = scaled_font->backend->index_to_ucs4 (scaled_font, scaled_font_glyph_index, &unicode);
if (unicode == (uint32_t)-1 && scaled_font->backend->index_to_ucs4) {
status = scaled_font->backend->index_to_ucs4 (scaled_font,
scaled_font_glyph_index,
&unicode);
if (status)
return status;
}
sub_font_glyph->unicode = unicode;
sub_font_glyph->utf8 = NULL;
sub_font_glyph->utf8_len = 0;
if (unicode != (uint32_t)-1) {
if (unicode != (uint32_t) -1) {
len = _cairo_ucs4_to_utf8 (unicode, buf);
if (len > 0) {
sub_font_glyph->utf8 = malloc(len + 1);
sub_font_glyph->utf8 = malloc (len + 1);
if (sub_font_glyph->utf8 == NULL)
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
memcpy (sub_font_glyph->utf8, buf, len);
sub_font_glyph->utf8[len] = 0;
sub_font_glyph->utf8_len = len;
@ -352,10 +363,14 @@ _cairo_sub_font_glyph_lookup_unicode (cairo_sub_font_glyph_t *sub_font_glyph,
static cairo_bool_t
_cairo_sub_font_glyph_map_to_unicode (cairo_sub_font_glyph_t *sub_font_glyph,
const char *utf8,
int utf8_len)
const char *utf8,
int utf8_len)
{
int add_zero_byte = 0;
if (utf8_len < 0)
return FALSE;
if (utf8 != NULL && utf8_len != 0 && utf8[utf8_len - 1] == '\0')
utf8_len--;
if (utf8 != NULL && utf8_len != 0) {
if (sub_font_glyph->utf8 != NULL) {
@ -372,12 +387,9 @@ _cairo_sub_font_glyph_map_to_unicode (cairo_sub_font_glyph_t *sub_font_glyph,
}
} else {
/* No existing mapping. Use the requested mapping */
if (sub_font_glyph->utf8[utf8_len - 1] != 0)
add_zero_byte = 1;
sub_font_glyph->utf8 = malloc (utf8_len + add_zero_byte);
sub_font_glyph->utf8 = malloc (utf8_len + 1);
memcpy (sub_font_glyph->utf8, utf8, utf8_len);
if (add_zero_byte)
sub_font_glyph->utf8[utf8_len] = 0;
sub_font_glyph->utf8[utf8_len] = 0;
sub_font_glyph->utf8_len = utf8_len;
return TRUE;
}
@ -390,7 +402,7 @@ _cairo_sub_font_glyph_map_to_unicode (cairo_sub_font_glyph_t *sub_font_glyph,
static cairo_bool_t
_cairo_sub_font_lookup_glyph (cairo_sub_font_t *sub_font,
unsigned long scaled_font_glyph_index,
const char * utf8,
const char *utf8,
int utf8_len,
cairo_scaled_font_subsets_glyph_t *subset_glyph)
{
@ -419,14 +431,13 @@ _cairo_sub_font_lookup_glyph (cairo_sub_font_t *sub_font,
static cairo_status_t
_cairo_sub_font_map_glyph (cairo_sub_font_t *sub_font,
unsigned long scaled_font_glyph_index,
const char * utf8,
const char *utf8,
int utf8_len,
cairo_scaled_font_subsets_glyph_t *subset_glyph)
{
cairo_sub_font_glyph_t key, *sub_font_glyph;
cairo_status_t status;
cairo_scaled_glyph_t *scaled_glyph;
cairo_scaled_font_subsets_glyph_t tmp_subset_glyph;
_cairo_sub_font_glyph_init_key (&key, scaled_font_glyph_index);
if (! _cairo_hash_table_lookup (sub_font->sub_font_glyphs, &key.base,
@ -434,11 +445,13 @@ _cairo_sub_font_map_glyph (cairo_sub_font_t *sub_font,
{
if (sub_font->num_glyphs_in_current_subset == sub_font->max_glyphs_per_subset)
{
cairo_scaled_font_subsets_glyph_t tmp_subset_glyph;
sub_font->current_subset++;
sub_font->num_glyphs_in_current_subset = 0;
/* Reserve first glyph in subset for the .notdef glyph */
status = _cairo_sub_font_map_glyph (sub_font, 0, NULL, 0, &tmp_subset_glyph);
status = _cairo_sub_font_map_glyph (sub_font, 0, NULL, -1, &tmp_subset_glyph);
if (status)
return status;
}
@ -459,9 +472,13 @@ _cairo_sub_font_map_glyph (cairo_sub_font_t *sub_font,
if (sub_font_glyph == NULL)
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
_cairo_sub_font_glyph_lookup_unicode (sub_font_glyph,
sub_font->scaled_font,
scaled_font_glyph_index);
status = _cairo_sub_font_glyph_lookup_unicode (sub_font_glyph,
sub_font->scaled_font,
scaled_font_glyph_index);
if (status) {
_cairo_sub_font_glyph_destroy (sub_font_glyph);
return status;
}
status = _cairo_hash_table_insert (sub_font->sub_font_glyphs, &sub_font_glyph->base);
if (status) {
@ -471,13 +488,10 @@ _cairo_sub_font_map_glyph (cairo_sub_font_t *sub_font,
sub_font->num_glyphs_in_current_subset++;
if (sub_font->is_scaled)
{
if (sub_font->is_scaled) {
if (sub_font->num_glyphs_in_current_subset > sub_font->parent->max_glyphs_per_scaled_subset_used)
sub_font->parent->max_glyphs_per_scaled_subset_used = sub_font->num_glyphs_in_current_subset;
}
else
{
} else {
if (sub_font->num_glyphs_in_current_subset > sub_font->parent->max_glyphs_per_unscaled_subset_used)
sub_font->parent->max_glyphs_per_unscaled_subset_used = sub_font->num_glyphs_in_current_subset;
}
@ -490,7 +504,8 @@ _cairo_sub_font_map_glyph (cairo_sub_font_t *sub_font,
subset_glyph->is_composite = sub_font->is_composite;
subset_glyph->x_advance = sub_font_glyph->x_advance;
subset_glyph->y_advance = sub_font_glyph->y_advance;
subset_glyph->utf8_is_mapped = FALSE;
subset_glyph->utf8_is_mapped = _cairo_sub_font_glyph_map_to_unicode (sub_font_glyph, utf8, utf8_len);
subset_glyph->unicode = sub_font_glyph->unicode;
return CAIRO_STATUS_SUCCESS;
}
@ -944,8 +959,8 @@ _cairo_scaled_font_subset_create_glyph_names (cairo_scaled_font_subset_t *subset
utf16_len = 0;
if (utf8 && *utf8) {
status = _cairo_utf8_to_utf16 (utf8, -1, &utf16, &utf16_len);
if (status && status != CAIRO_STATUS_INVALID_STRING)
return status; // FIXME
if (status)
return status; /* FIXME */
}
if (utf16_len == 1) {
@ -1004,3 +1019,5 @@ CLEANUP_HASH:
return status;
}
#endif /* CAIRO_HAS_FONT_SUBSET */

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

@ -299,6 +299,7 @@ slim_hidden_def (cairo_scaled_font_status);
#define CAIRO_SCALED_FONT_MAX_HOLDOVERS 256
typedef struct _cairo_scaled_font_map {
cairo_scaled_font_t *mru_scaled_font;
cairo_hash_table_t *hash_table;
cairo_scaled_font_t *holdovers[CAIRO_SCALED_FONT_MAX_HOLDOVERS];
int num_holdovers;
@ -319,6 +320,7 @@ _cairo_scaled_font_map_lock (void)
if (cairo_scaled_font_map == NULL)
goto CLEANUP_MUTEX_LOCK;
cairo_scaled_font_map->mru_scaled_font = NULL;
cairo_scaled_font_map->hash_table =
_cairo_hash_table_create (_cairo_scaled_font_keys_equal);
@ -358,11 +360,17 @@ _cairo_scaled_font_map_destroy (void)
goto CLEANUP_MUTEX_LOCK;
}
scaled_font = font_map->mru_scaled_font;
if (scaled_font != NULL) {
CAIRO_MUTEX_UNLOCK (_cairo_scaled_font_map_mutex);
cairo_scaled_font_destroy (scaled_font);
CAIRO_MUTEX_LOCK (_cairo_scaled_font_map_mutex);
}
/* remove scaled_fonts starting from the end so that font_map->holdovers
* is always in a consistent state when we release the mutex. */
while (font_map->num_holdovers) {
scaled_font = font_map->holdovers[font_map->num_holdovers-1];
assert (! CAIRO_REFERENCE_COUNT_HAS_REFERENCE (&scaled_font->ref_count));
_cairo_hash_table_remove (font_map->hash_table,
&scaled_font->hash_entry);
@ -673,7 +681,7 @@ _cairo_scaled_font_set_metrics (cairo_scaled_font_t *scaled_font,
cairo_status_t status;
double font_scale_x, font_scale_y;
status = _cairo_matrix_compute_scale_factors (&scaled_font->font_matrix,
status = _cairo_matrix_compute_basis_scale_factors (&scaled_font->font_matrix,
&font_scale_x, &font_scale_y,
1);
if (status)
@ -745,7 +753,7 @@ cairo_scaled_font_create (cairo_font_face_t *font_face,
{
cairo_status_t status;
cairo_scaled_font_map_t *font_map;
cairo_scaled_font_t key, *scaled_font = NULL;
cairo_scaled_font_t key, *old = NULL, *scaled_font = NULL;
if (font_face->status)
return _cairo_scaled_font_create_in_error (font_face->status);
@ -763,42 +771,12 @@ cairo_scaled_font_create (cairo_font_face_t *font_face,
_cairo_scaled_font_init_key (&key, font_face,
font_matrix, ctm, options);
while (_cairo_hash_table_lookup (font_map->hash_table, &key.hash_entry,
(cairo_hash_entry_t**) &scaled_font))
scaled_font = font_map->mru_scaled_font;
if (scaled_font != NULL &&
scaled_font->hash_entry.hash == key.hash_entry.hash &&
_cairo_scaled_font_keys_equal (scaled_font, &key))
{
if (!scaled_font->placeholder)
break;
/* If the scaled font is being created (happens for user-font),
* just wait until it's done, then retry */
_cairo_scaled_font_placeholder_wait_for_creation_to_finish (scaled_font);
}
/* Return existing scaled_font if it exists in the hash table. */
if (scaled_font)
{
/* If the original reference count is 0, then this font must have
* been found in font_map->holdovers, (which means this caching is
* actually working). So now we remove it from the holdovers
* array. */
if (! CAIRO_REFERENCE_COUNT_HAS_REFERENCE (&scaled_font->ref_count)) {
int i;
for (i = 0; i < font_map->num_holdovers; i++)
if (font_map->holdovers[i] == scaled_font)
break;
assert (i < font_map->num_holdovers);
font_map->num_holdovers--;
memmove (&font_map->holdovers[i],
&font_map->holdovers[i+1],
(font_map->num_holdovers - i) * sizeof (cairo_scaled_font_t*));
/* reset any error status */
scaled_font->status = CAIRO_STATUS_SUCCESS;
}
assert (! scaled_font->placeholder);
if (scaled_font->status == CAIRO_STATUS_SUCCESS) {
/* We increment the reference count manually here, (rather
@ -814,6 +792,66 @@ cairo_scaled_font_create (cairo_font_face_t *font_face,
_cairo_hash_table_remove (font_map->hash_table, &key.hash_entry);
scaled_font->hash_entry.hash = ZOMBIE;
}
else
{
while (_cairo_hash_table_lookup (font_map->hash_table, &key.hash_entry,
(cairo_hash_entry_t**) &scaled_font))
{
if (! scaled_font->placeholder)
break;
/* If the scaled font is being created (happens for user-font),
* just wait until it's done, then retry */
_cairo_scaled_font_placeholder_wait_for_creation_to_finish (scaled_font);
}
/* Return existing scaled_font if it exists in the hash table. */
if (scaled_font != NULL) {
/* If the original reference count is 0, then this font must have
* been found in font_map->holdovers, (which means this caching is
* actually working). So now we remove it from the holdovers
* array. */
if (! CAIRO_REFERENCE_COUNT_HAS_REFERENCE (&scaled_font->ref_count)) {
int i;
for (i = 0; i < font_map->num_holdovers; i++)
if (font_map->holdovers[i] == scaled_font)
break;
assert (i < font_map->num_holdovers);
font_map->num_holdovers--;
memmove (&font_map->holdovers[i],
&font_map->holdovers[i+1],
(font_map->num_holdovers - i) * sizeof (cairo_scaled_font_t*));
/* reset any error status */
scaled_font->status = CAIRO_STATUS_SUCCESS;
}
if (scaled_font->status == CAIRO_STATUS_SUCCESS) {
/* We increment the reference count manually here, (rather
* than calling into cairo_scaled_font_reference), since we
* must modify the reference count while our lock is still
* held. */
old = font_map->mru_scaled_font;
font_map->mru_scaled_font = scaled_font;
/* increment reference count for the mru cache */
_cairo_reference_count_inc (&scaled_font->ref_count);
/* and increment for the returned reference */
_cairo_reference_count_inc (&scaled_font->ref_count);
_cairo_scaled_font_map_unlock ();
cairo_scaled_font_destroy (old);
return scaled_font;
}
/* the font has been put into an error status - abandon the cache */
_cairo_hash_table_remove (font_map->hash_table, &key.hash_entry);
scaled_font->hash_entry.hash = ZOMBIE;
}
}
/* Otherwise create it and insert it into the hash table. */
status = font_face->backend->scaled_font_create (font_face, font_matrix,
@ -826,6 +864,12 @@ cairo_scaled_font_create (cairo_font_face_t *font_face,
status = _cairo_hash_table_insert (font_map->hash_table,
&scaled_font->hash_entry);
if (status == CAIRO_STATUS_SUCCESS) {
old = font_map->mru_scaled_font;
font_map->mru_scaled_font = scaled_font;
_cairo_reference_count_inc (&scaled_font->ref_count);
}
_cairo_scaled_font_map_unlock ();
if (status) {
@ -837,6 +881,8 @@ cairo_scaled_font_create (cairo_font_face_t *font_face,
return _cairo_scaled_font_create_in_error (status);
}
cairo_scaled_font_destroy (old);
return scaled_font;
}
slim_hidden_def (cairo_scaled_font_create);
@ -1083,7 +1129,7 @@ slim_hidden_def (cairo_scaled_font_extents);
/**
* cairo_scaled_font_text_extents:
* @scaled_font: a #cairo_scaled_font_t
* @utf8: a string of text, encoded in UTF-8
* @utf8: a NUL-terminated string of text, encoded in UTF-8
* @extents: a #cairo_text_extents_t which to store the retrieved extents.
*
* Gets the extents for a string of text. The extents describe a
@ -1109,7 +1155,7 @@ cairo_scaled_font_text_extents (cairo_scaled_font_t *scaled_font,
cairo_text_extents_t *extents)
{
cairo_status_t status;
cairo_glyph_t *glyphs;
cairo_glyph_t *glyphs = NULL;
int num_glyphs;
if (scaled_font->status)
@ -1118,7 +1164,11 @@ cairo_scaled_font_text_extents (cairo_scaled_font_t *scaled_font,
if (utf8 == NULL)
goto ZERO_EXTENTS;
status = _cairo_scaled_font_text_to_glyphs (scaled_font, 0., 0., utf8, &glyphs, &num_glyphs);
status = cairo_scaled_font_text_to_glyphs (scaled_font, 0., 0.,
utf8, -1,
&glyphs, &num_glyphs,
NULL, NULL,
NULL);
if (status)
goto ZERO_EXTENTS;
@ -1166,15 +1216,15 @@ cairo_scaled_font_glyph_extents (cairo_scaled_font_t *scaled_font,
cairo_bool_t visible = FALSE;
cairo_scaled_glyph_t *scaled_glyph = NULL;
if (scaled_font->status) {
extents->x_bearing = 0.0;
extents->y_bearing = 0.0;
extents->width = 0.0;
extents->height = 0.0;
extents->x_advance = 0.0;
extents->y_advance = 0.0;
extents->x_bearing = 0.0;
extents->y_bearing = 0.0;
extents->width = 0.0;
extents->height = 0.0;
extents->x_advance = 0.0;
extents->y_advance = 0.0;
if (scaled_font->status)
return;
}
if (num_glyphs == 0)
return;
@ -1264,71 +1314,326 @@ cairo_scaled_font_glyph_extents (cairo_scaled_font_t *scaled_font,
}
slim_hidden_def (cairo_scaled_font_glyph_extents);
/**
* cairo_scaled_font_text_to_glyphs:
* @x: X position to place first glyph
* @y: Y position to place first glyph
* @scaled_font: a #cairo_scaled_font_t
* @utf8: a string of text encoded in UTF-8
* @utf8_len: length of @utf8 in bytes, or -1 if it is NUL-terminated
* @glyphs: pointer to array of glyphs to fill
* @num_glyphs: pointer to number of glyphs
* @clusters: pointer to array of cluster mapping information to fill, or %NULL
* @num_clusters: pointer to number of clusters, or %NULL
* @backward: pointer to whether the text to glyphs mapping goes backward, or
* %NULL
*
* Converts UTF-8 text to an array of glyphs, optionally with cluster
* mapping, that can be used to render later using @scaled_font.
*
* If @glyphs initially points to a non-%NULL value, that array is used
* as a glyph buffer, and @num_glyphs should point to the number of glyph
* entries available there. If the provided glyph array is too short for
* the conversion, a new glyph array is allocated using cairo_glyph_allocate()
* and placed in @glyphs. Upon return, @num_glyphs always contains the
* number of generated glyphs. If the value @glyphs points at has changed
* after the call, the user is responsible for freeing the allocated glyph
* array using cairo_glyph_free().
*
* If @clusters is not %NULL, @num_clusters and @backward should not be %NULL,
* and cluster mapping will be computed.
* The semantics of how cluster array allocation works is similar to the glyph
* array. That is,
* if @clusters initially points to a non-%NULL value, that array is used
* as a cluster buffer, and @num_clusters should point to the number of cluster
* entries available there. If the provided cluster array is too short for
* the conversion, a new cluster array is allocated using cairo_text_cluster_allocate()
* and placed in @clusters. Upon return, @num_clusters always contains the
* number of generated clusters. If the value @clusters points at has changed
* after the call, the user is responsible for freeing the allocated cluster
* array using cairo_text_cluster_free().
*
* In the simplest case, @glyphs and @clusters can point to %NULL initially
* and a suitable array will be allocated. In code:
* <informalexample><programlisting>
* cairo_status_t status;
*
* cairo_glyph_t *glyphs = NULL;
* int num_glyphs;
* cairo_text_cluster_t *clusters = NULL;
* int num_clusters;
* cairo_bool_t backward;
*
* status = cairo_scaled_font_text_to_glyphs (scaled_font,
* x, y,
* utf8, utf8_len,
* &amp;glyphs, &amp;num_glyphs,
* &amp;clusters, &amp;num_clusters,
* &amp;backward);
*
* if (status == CAIRO_STATUS_SUCCESS) {
* cairo_show_text_glyphs (cr,
* utf8, utf8_len,
* *glyphs, *num_glyphs,
* *clusters, *num_clusters,
* *backward);
*
* cairo_glyph_free (*glyphs);
* cairo_text_cluster_free (*clusters);
* }
* </programlisting></informalexample>
*
* If no cluster mapping is needed:
* <informalexample><programlisting>
* cairo_status_t status;
*
* cairo_glyph_t *glyphs = NULL;
* int num_glyphs;
*
* status = cairo_scaled_font_text_to_glyphs (scaled_font,
* x, y,
* utf8, utf8_len,
* &amp;glyphs, &amp;num_glyphs,
* NULL, NULL,
* NULL);
*
* if (status == CAIRO_STATUS_SUCCESS) {
* cairo_show_glyphs (cr, *glyphs, *num_glyphs);
* cairo_glyph_free (*glyphs);
* }
* </programlisting></informalexample>
*
* If stack-based glyph and cluster arrays are to be used for small
* arrays:
* <informalexample><programlisting>
* cairo_status_t status;
*
* cairo_glyph_t stack_glyphs[40];
* cairo_glyph_t *glyphs = stack_glyphs;
* int num_glyphs = sizeof (stack_glyphs) / sizeof (stack_glyphs[0]);
* cairo_text_cluster_t stack_clusters[40];
* cairo_text_cluster_t *clusters = stack_clusters;
* int num_clusters = sizeof (stack_clusters) / sizeof (stack_clusters[0]);
* cairo_bool_t backward;
*
* status = cairo_scaled_font_text_to_glyphs (scaled_font,
* x, y,
* utf8, utf8_len,
* &amp;glyphs, &amp;num_glyphs,
* &amp;clusters, &amp;num_clusters,
* &amp;backward);
*
* if (status == CAIRO_STATUS_SUCCESS) {
* cairo_show_text_glyphs (cr,
* utf8, utf8_len,
* *glyphs, *num_glyphs,
* *clusters, *num_clusters,
* *backward);
*
* if (glyphs != stack_glyphs)
* cairo_glyph_free (*glyphs);
* if (clusters != stack_clusters)
* cairo_text_cluster_free (*clusters);
* }
* </programlisting></informalexample>
*
* For details of how @clusters, @num_clusters, and @backward map input
* UTF-8 text to the output glyphs see cairo_show_text_glyphs().
*
* The output values can be readily passed to cairo_show_text_glyphs()
* cairo_show_glyphs(), or related functions, assuming that the exact
* same @scaled_font is used for the operation.
*
* Return value: %CAIRO_STATUS_SUCCESS upon success, or an error status
* if the input values are wrong or if conversion failed. If the input
* values are correct but the conversion failed, the error status is also
* set on @scaled_font.
*
* Since: 1.8
**/
cairo_status_t
_cairo_scaled_font_text_to_glyphs (cairo_scaled_font_t *scaled_font,
double x,
double y,
const char *utf8,
cairo_glyph_t **glyphs,
int *num_glyphs)
cairo_scaled_font_text_to_glyphs (cairo_scaled_font_t *scaled_font,
double x,
double y,
const char *utf8,
int utf8_len,
cairo_glyph_t **glyphs,
int *num_glyphs,
cairo_text_cluster_t **clusters,
int *num_clusters,
cairo_bool_t *backward)
{
int i;
uint32_t *ucs4 = NULL;
int num_chars = 0;
const char *p;
cairo_status_t status;
cairo_scaled_glyph_t *scaled_glyph;
*num_glyphs = 0;
*glyphs = NULL;
cairo_glyph_t *orig_glyphs;
cairo_text_cluster_t *orig_clusters;
status = scaled_font->status;
if (status)
return status;
if (utf8[0] == '\0')
return CAIRO_STATUS_SUCCESS;
/* A slew of sanity checks */
/* glyphs and num_glyphs can't be NULL */
if (glyphs == NULL ||
num_glyphs == NULL) {
status = CAIRO_STATUS_NULL_POINTER;
goto BAIL;
}
/* Special case for NULL and -1 */
if (utf8 == NULL && utf8_len == -1)
utf8_len = 0;
/* No NULLs for non-NULLs! */
if ((utf8_len && utf8 == NULL) ||
(clusters && num_clusters == NULL) ||
(clusters && backward == NULL)) {
status = CAIRO_STATUS_NULL_POINTER;
goto BAIL;
}
/* A -1 for utf8_len means NUL-terminated */
if (utf8_len == -1)
utf8_len = strlen (utf8);
/* A NULL *glyphs means no prealloced glyphs array */
if (glyphs && *glyphs == NULL)
*num_glyphs = 0;
/* A NULL *clusters means no prealloced clusters array */
if (clusters && *clusters == NULL)
*num_clusters = 0;
if (!clusters && num_clusters) {
num_clusters = NULL;
}
if (backward) {
*backward = FALSE;
}
if (!clusters && backward) {
backward = NULL;
}
/* Apart from that, no negatives */
if (utf8_len < 0 ||
*num_glyphs < 0 ||
(num_clusters && *num_clusters < 0)) {
status = CAIRO_STATUS_NEGATIVE_COUNT;
goto BAIL;
}
if (utf8_len == 0) {
status = CAIRO_STATUS_SUCCESS;
goto BAIL;
}
/* validate input so backend does not have to */
status = _cairo_utf8_to_ucs4 (utf8, utf8_len, NULL, &num_chars);
if (status)
goto BAIL;
CAIRO_MUTEX_LOCK (scaled_font->mutex);
_cairo_scaled_font_freeze_cache (scaled_font);
orig_glyphs = *glyphs;
orig_clusters = clusters ? *clusters : NULL;
if (scaled_font->backend->text_to_glyphs) {
/* validate input so backend does not have to */
status = _cairo_utf8_to_ucs4 (utf8, -1, NULL, NULL);
if (status)
goto DONE;
status = scaled_font->backend->text_to_glyphs (scaled_font, x, y,
utf8, utf8_len,
glyphs, num_glyphs,
clusters, num_clusters,
backward);
status = scaled_font->backend->text_to_glyphs (scaled_font,
x, y, utf8,
glyphs, num_glyphs);
if (status != CAIRO_INT_STATUS_UNSUPPORTED) {
if (status == CAIRO_STATUS_SUCCESS) {
/* The checks here are crude; we only should do them in
* user-font backend, but they don't hurt here. This stuff
* can be hard to get right. */
if (*num_glyphs < 0) {
status = CAIRO_STATUS_NEGATIVE_COUNT;
goto DONE;
}
if (num_glyphs && *glyphs == NULL) {
status = CAIRO_STATUS_NULL_POINTER;
goto DONE;
}
if (clusters) {
if (*num_clusters < 0) {
status = CAIRO_STATUS_NEGATIVE_COUNT;
goto DONE;
}
if (num_clusters && *clusters == NULL) {
status = CAIRO_STATUS_NULL_POINTER;
goto DONE;
}
/* Dont trust the backend, validate clusters! */
status = _cairo_validate_text_clusters (utf8, utf8_len,
*glyphs, *num_glyphs,
*clusters, *num_clusters,
*backward);
}
}
if (status != CAIRO_INT_STATUS_UNSUPPORTED)
goto DONE;
}
}
status = _cairo_utf8_to_ucs4 (utf8, -1, &ucs4, num_glyphs);
if (status)
goto DONE;
if (*num_glyphs < num_chars) {
*glyphs = cairo_glyph_allocate (num_chars);
if (*glyphs == NULL) {
status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
goto DONE;
}
}
*num_glyphs = num_chars;
*glyphs = (cairo_glyph_t *) _cairo_malloc_ab ((*num_glyphs), sizeof (cairo_glyph_t));
if (*glyphs == NULL) {
status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
goto DONE;
if (clusters) {
if (*num_clusters < num_chars) {
*clusters = cairo_text_cluster_allocate (num_chars);
if (*clusters == NULL) {
status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
goto DONE;
}
}
*num_clusters = num_chars;
}
for (i = 0; i < *num_glyphs; i++) {
(*glyphs)[i].index = (*scaled_font->backend->
ucs4_to_index) (scaled_font, ucs4[i]);
p = utf8;
for (i = 0; i < num_chars; i++) {
int num_bytes;
uint32_t unicode;
cairo_scaled_glyph_t *scaled_glyph;
num_bytes = _cairo_utf8_get_char_validated (p, &unicode);
p += num_bytes;
(*glyphs)[i].index = (*scaled_font->backend->ucs4_to_index) (scaled_font, unicode);
(*glyphs)[i].x = x;
(*glyphs)[i].y = y;
if (clusters) {
(*clusters)[i].num_bytes = num_bytes;
(*clusters)[i].num_glyphs = 1;
}
status = _cairo_scaled_glyph_lookup (scaled_font,
(*glyphs)[i].index,
CAIRO_SCALED_GLYPH_INFO_METRICS,
&scaled_glyph);
if (status) {
free (*glyphs);
*glyphs = NULL;
goto DONE;
}
@ -1336,15 +1641,39 @@ _cairo_scaled_font_text_to_glyphs (cairo_scaled_font_t *scaled_font,
y += scaled_glyph->metrics.y_advance;
}
DONE:
DONE: /* error that should be logged on scaled_font happened */
_cairo_scaled_font_thaw_cache (scaled_font);
CAIRO_MUTEX_UNLOCK (scaled_font->mutex);
if (ucs4)
free (ucs4);
if (status) {
*num_glyphs = 0;
if (*glyphs != orig_glyphs) {
cairo_glyph_free (*glyphs);
*glyphs = orig_glyphs;
}
if (clusters) {
*num_clusters = 0;
if (*clusters != orig_clusters) {
cairo_text_cluster_free (*clusters);
*clusters = orig_clusters;
}
}
}
return _cairo_scaled_font_set_error (scaled_font, status);
BAIL: /* error with input arguments */
if (num_glyphs)
*num_glyphs = 0;
if (num_clusters)
*num_clusters = 0;
return status;
}
slim_hidden_def (cairo_scaled_font_text_to_glyphs);
/*
* Compute a device-space bounding box for the glyphs.
@ -1453,8 +1782,6 @@ _cairo_scaled_font_show_glyphs (cairo_scaled_font_t *scaled_font,
/* Font display routine either does not exist or failed. */
status = CAIRO_STATUS_SUCCESS;
_cairo_pattern_init_solid (&white_pattern, CAIRO_COLOR_WHITE, CAIRO_CONTENT_COLOR);
_cairo_cache_freeze (scaled_font->glyphs);
@ -1696,7 +2023,7 @@ _trace_mask_to_path (cairo_image_surface_t *mask,
{
cairo_status_t status;
cairo_image_surface_t *a1_mask;
unsigned char *row, *byte_ptr, byte;
uint8_t *row, *byte_ptr, byte;
int rows, cols, bytes_per_row;
int x, y, bit;
double xoff, yoff;
@ -1716,7 +2043,7 @@ _trace_mask_to_path (cairo_image_surface_t *mask,
bytes_per_row = (a1_mask->width + 7) / 8;
for (y = 0, row = a1_mask->data, rows = a1_mask->height; rows; row += a1_mask->stride, rows--, y++) {
for (x = 0, byte_ptr = row, cols = (a1_mask->width + 7) / 8; cols; byte_ptr++, cols--) {
for (x = 0, byte_ptr = row, cols = bytes_per_row; cols; byte_ptr++, cols--) {
byte = CAIRO_BITSWAP8_IF_LITTLE_ENDIAN (*byte_ptr);
for (bit = 7; bit >= 0 && x < a1_mask->width; bit--, x++) {
if (byte & (1 << bit)) {

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

@ -71,10 +71,11 @@ const cairo_surface_t name = { \
0, /* current_clip_serial */ \
FALSE, /* is_snapshot */ \
FALSE, /* has_font_options */ \
{ CAIRO_ANTIALIAS_DEFAULT, \
CAIRO_SUBPIXEL_ORDER_DEFAULT, \
CAIRO_HINT_STYLE_DEFAULT, \
CAIRO_HINT_METRICS_DEFAULT \
{ CAIRO_ANTIALIAS_DEFAULT, /* antialias */ \
CAIRO_SUBPIXEL_ORDER_DEFAULT, /* subpixel_order */ \
CAIRO_LCD_FILTER_DEFAULT, /* lcd_filter */ \
CAIRO_HINT_STYLE_DEFAULT, /* hint_style */ \
CAIRO_HINT_METRICS_DEFAULT /* hint_metrics */ \
} /* font_options */ \
}
@ -648,7 +649,12 @@ cairo_surface_get_font_options (cairo_surface_t *surface,
if (cairo_font_options_status (options))
return;
if (!surface->has_font_options) {
if (surface->status) {
_cairo_font_options_init_default (options);
return;
}
if (! surface->has_font_options) {
surface->has_font_options = TRUE;
_cairo_font_options_init_default (&surface->font_options);
@ -1732,6 +1738,9 @@ _cairo_surface_composite_trapezoids (cairo_operator_t op,
* be retained for the next page. Use cairo_surface_show_page() if you
* want to get an empty page after the emission.
*
* There is a convenience function for this that takes a #cairo_t,
* namely cairo_copy_page().
*
* Since: 1.6
*/
void
@ -1766,6 +1775,9 @@ slim_hidden_def (cairo_surface_copy_page);
* Emits and clears the current page for backends that support multiple
* pages. Use cairo_surface_copy_page() if you don't want to clear the page.
*
* There is a convenience function for this that takes a #cairo_t,
* namely cairo_show_page().
*
* Since: 1.6
**/
void
@ -2135,14 +2147,50 @@ _cairo_surface_get_extents (cairo_surface_t *surface,
return status;
}
/**
* cairo_surface_has_show_text_glyphs:
* @surface: a #cairo_surface_t
*
* Returns whether the surface supports
* sophisticated cairo_show_text_glyphs() operations. That is,
* whether it actually uses the provided text and cluster data
* to a cairo_show_text_glyphs() call.
*
* Note: Even if this function returns %FALSE, a
* cairo_show_text_glyphs() operation targeted at @surface will
* still succeed. It just will
* act like a cairo_show_glyphs() operation. Users can use this
* function to avoid computing UTF-8 text and cluster mapping if the
* target surface does not use it.
*
* There is a convenience function for this that takes a #cairo_t,
* namely cairo_has_show_text_glyphs().
*
* Return value: %TRUE if @surface supports
* cairo_show_text_glyphs(), %FALSE otherwise
*
* Since: 1.8
**/
cairo_bool_t
_cairo_surface_has_show_text_glyphs (cairo_surface_t *surface)
cairo_surface_has_show_text_glyphs (cairo_surface_t *surface)
{
cairo_status_t status_ignored;
if (surface->status)
return FALSE;
if (surface->finished) {
status_ignored = _cairo_surface_set_error (surface,
CAIRO_STATUS_SURFACE_FINISHED);
return FALSE;
}
if (surface->backend->has_show_text_glyphs)
return surface->backend->has_show_text_glyphs (surface);
else
return surface->backend->show_text_glyphs != NULL;
}
slim_hidden_def (cairo_surface_has_show_text_glyphs);
/* Note: the backends may modify the contents of the glyph array as long as
* they do not return %CAIRO_INT_STATUS_UNSUPPORTED. This makes it possible to
@ -2558,15 +2606,8 @@ _cairo_surface_copy_pattern_for_destination (const cairo_pattern_t *pattern,
return status;
if (_cairo_surface_has_device_transform (destination)) {
cairo_matrix_t device_to_surface = destination->device_transform;
status = cairo_matrix_invert (&device_to_surface);
/* We only ever allow for scaling (under the implementation's
* control) or translation (under the user's control). So the
* matrix should always be invertible. */
assert (status == CAIRO_STATUS_SUCCESS);
_cairo_pattern_transform (*pattern_out, &device_to_surface);
_cairo_pattern_transform (*pattern_out,
&destination->device_transform_inverse);
}
return CAIRO_STATUS_SUCCESS;
@ -2639,6 +2680,8 @@ _cairo_surface_create_in_error (cairo_status_t status)
case CAIRO_STATUS_USER_FONT_ERROR:
case CAIRO_STATUS_NEGATIVE_COUNT:
case CAIRO_STATUS_INVALID_CLUSTERS:
case CAIRO_STATUS_INVALID_SLANT:
case CAIRO_STATUS_INVALID_WEIGHT:
default:
_cairo_error_throw (CAIRO_STATUS_NO_MEMORY);
return (cairo_surface_t *) &_cairo_surface_nil;

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

@ -651,7 +651,7 @@ _cairo_svg_document_emit_bitmap_glyph_data (cairo_svg_document_t *document,
cairo_image_surface_t *image;
cairo_scaled_glyph_t *scaled_glyph;
cairo_status_t status;
unsigned char *row, *byte;
uint8_t *row, *byte;
int rows, cols;
int x, y, bit;
@ -677,7 +677,7 @@ _cairo_svg_document_emit_bitmap_glyph_data (cairo_svg_document_t *document,
for (y = 0, row = image->data, rows = image->height; rows; row += image->stride, rows--, y++) {
for (x = 0, byte = row, cols = (image->width + 7) / 8; cols; byte++, cols--) {
unsigned char output_byte = CAIRO_BITSWAP8_IF_LITTLE_ENDIAN (*byte);
uint8_t output_byte = CAIRO_BITSWAP8_IF_LITTLE_ENDIAN (*byte);
for (bit = 7; bit >= 0 && x < image->width; bit--, x++) {
if (output_byte & (1 << bit)) {
_cairo_output_stream_printf (document->xml_node_glyphs,
@ -870,12 +870,11 @@ _cairo_svg_surface_emit_alpha_filter (cairo_svg_document_t *document)
typedef struct {
cairo_output_stream_t *output;
unsigned int in_mem;
unsigned char src[3];
unsigned char dst[5];
unsigned int trailing;
unsigned char src[3];
} base64_write_closure_t;
static char const *base64_table =
static char const base64_table[64] =
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
static cairo_status_t
@ -885,26 +884,27 @@ base64_write_func (void *closure,
{
base64_write_closure_t *info = (base64_write_closure_t *) closure;
unsigned int i;
unsigned char *src, *dst;
unsigned char *src;
dst = info->dst;
src = info->src;
if (info->in_mem + length < 3) {
for (i = 0; i < length; i++) {
src[i + info->in_mem] = *data;
data++;
src[i + info->in_mem] = *data++;
}
info->in_mem += length;
return CAIRO_STATUS_SUCCESS;
}
while (info->in_mem + length >= 3) {
for (i = 0; i < 3 - info->in_mem; i++) {
src[i + info->in_mem] = *data;
data++;
do {
unsigned char dst[4];
for (i = info->in_mem; i < 3; i++) {
src[i] = *data++;
length--;
}
info->in_mem = 0;
dst[0] = base64_table[src[0] >> 2];
dst[1] = base64_table[(src[0] & 0x03) << 4 | src[1] >> 4];
dst[2] = base64_table[(src[1] & 0x0f) << 2 | src[2] >> 6];
@ -919,16 +919,14 @@ base64_write_func (void *closure,
break;
}
_cairo_output_stream_write (info->output, dst, 4);
info->in_mem = 0;
}
} while (length >= 3);
for (i = 0; i < length; i++) {
src[i] = *data;
data++;
src[i] = *data++;
}
info->in_mem = length;
return CAIRO_STATUS_SUCCESS;
return _cairo_output_stream_get_status (info->output);
}
static cairo_int_status_t
@ -942,7 +940,6 @@ _cairo_surface_base64_encode (cairo_surface_t *surface,
info.output = output;
info.in_mem = 0;
info.trailing = 0;
memset (info.dst, '\x0', 5);
_cairo_output_stream_printf (info.output, "data:image/png;base64,");

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

@ -39,6 +39,8 @@
#include "cairoint.h"
#if CAIRO_HAS_FONT_SUBSET
/* The structs defined here should strictly follow the TrueType
* specification and not be padded. We use only 16-bit integer
* in their definition to guarantee that. The fields of type
@ -192,4 +194,6 @@ typedef struct _tt_glyph_data {
tt_composite_glyph_t glyph;
} tt_glyph_data_t;
#endif /* CAIRO_HAS_FONT_SUBSET */
#endif /* CAIRO_TRUETYPE_SUBSET_PRIVATE_H */

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

@ -43,6 +43,8 @@
#define _BSD_SOURCE /* for snprintf(), strdup() */
#include "cairoint.h"
#if CAIRO_HAS_FONT_SUBSET
#include "cairo-scaled-font-subsets-private.h"
#include "cairo-truetype-subset-private.h"
@ -1224,8 +1226,7 @@ _cairo_truetype_reverse_cmap (cairo_scaled_font_t *scaled_font,
range_offset = &(delta[num_segments]);
glyph_array = &(range_offset[num_segments]);
/* search for glyph in segments
* with rangeOffset=0 */
/* search for glyph in segments with rangeOffset=0 */
for (i = 0; i < num_segments; i++) {
c = index - be16_to_cpu (delta[i]);
if (range_offset[i] == 0 &&
@ -1245,12 +1246,13 @@ _cairo_truetype_reverse_cmap (cairo_scaled_font_t *scaled_font,
uint16_t g_id_be = cpu_to_be16 (index);
int j;
for (j = 0; j < range_size; j++) {
if (glyph_ids[j] == g_id_be) {
*ucs4 = be16_to_cpu (start_code[i]) + j;
goto found;
if (range_size > 0)
for (j = 0; j < range_size; j++) {
if (glyph_ids[j] == g_id_be) {
*ucs4 = be16_to_cpu (start_code[i]) + j;
goto found;
}
}
}
}
}
@ -1293,7 +1295,7 @@ _cairo_truetype_index_to_ucs4 (cairo_scaled_font_t *scaled_font,
cmap = (tt_cmap_t *) buf;
num_tables = be16_to_cpu (cmap->num_tables);
size = 4 + num_tables*sizeof(tt_cmap_index_t);
cmap = malloc (size);
cmap = _cairo_malloc_ab_plus_c (num_tables, sizeof (tt_cmap_index_t), 4);
if (cmap == NULL)
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
@ -1322,3 +1324,5 @@ cleanup:
return status;
}
#endif /* CAIRO_HAS_FONT_SUBSET */

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

@ -35,6 +35,9 @@
#define _BSD_SOURCE /* for snprintf(), strdup() */
#include "cairoint.h"
#if CAIRO_HAS_FONT_SUBSET
#include "cairo-type1-private.h"
#include "cairo-scaled-font-subsets-private.h"
#include "cairo-path-fixed-private.h"
@ -873,3 +876,5 @@ _cairo_type2_charstrings_fini (cairo_type2_charstrings_t *type2_subset)
free (type2_subset->widths);
}
#endif /* CAIRO_HAS_FONT_SUBSET */

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

@ -36,10 +36,16 @@
#ifndef CAIRO_TYPE1_PRIVATE_H
#define CAIRO_TYPE1_PRIVATE_H
#include "cairoint.h"
#if CAIRO_HAS_FONT_SUBSET
/* Magic constants for the type1 eexec encryption */
#define CAIRO_TYPE1_ENCRYPT_C1 ((unsigned short) 52845)
#define CAIRO_TYPE1_ENCRYPT_C2 ((unsigned short) 22719)
#define CAIRO_TYPE1_PRIVATE_DICT_KEY ((unsigned short) 55665)
#define CAIRO_TYPE1_CHARSTRING_KEY ((unsigned short) 4330)
#endif /* CAIRO_HAS_FONT_SUBSET */
#endif /* CAIRO_TYPE1_PRIVATE_H */

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

@ -38,13 +38,19 @@
* http://partners.adobe.com/public/developer/en/font/T1_SPEC.PDF
*/
#define _BSD_SOURCE /* for snprintf(), strdup() */
#include "cairoint.h"
#if CAIRO_HAS_FONT_SUBSET
#include "cairo-type1-private.h"
#include "cairo-scaled-font-subsets-private.h"
#include "cairo-output-stream-private.h"
/* XXX: Eventually, we need to handle other font backends */
#if CAIRO_HAS_FT_FONT
#include "cairo-ft-private.h"
#include <ft2build.h>
@ -1405,3 +1411,7 @@ _cairo_type1_scaled_font_is_type1 (cairo_scaled_font_t *scaled_font)
return is_type1;
}
#endif /* CAIRO_HAS_FT_FONT */
#endif /* CAIRO_HAS_FONT_SUBSET */

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

@ -37,6 +37,10 @@
#ifndef CAIRO_TYPE3_GLYPH_SURFACE_PRIVATE_H
#define CAIRO_TYPE3_GLYPH_SURFACE_PRIVATE_H
#include "cairoint.h"
#if CAIRO_HAS_FONT_SUBSET
#include "cairo-surface-private.h"
#include "cairo-pdf-operators-private.h"
@ -71,4 +75,6 @@ _cairo_type3_glyph_surface_emit_glyph (void *abstract_surface,
cairo_box_t *bbox,
double *width);
#endif /* CAIRO_HAS_FONT_SUBSET */
#endif /* CAIRO_TYPE3_GLYPH_SURFACE_PRIVATE_H */

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

@ -35,6 +35,9 @@
*/
#include "cairoint.h"
#if CAIRO_HAS_FONT_SUBSET
#include "cairo-type3-glyph-surface-private.h"
#include "cairo-output-stream-private.h"
#include "cairo-meta-surface-private.h"
@ -112,7 +115,7 @@ _cairo_type3_glyph_surface_emit_image (cairo_type3_glyph_surface_t *surface,
if (image_mask != image)
cairo_surface_destroy (&image_mask->base);
return CAIRO_STATUS_SUCCESS;
return status;
}
static cairo_status_t
@ -443,3 +446,5 @@ _cairo_type3_glyph_surface_emit_glyph (void *abstract_surface,
return status;
}
#endif /* CAIRO_HAS_FONT_SUBSET */

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

@ -45,17 +45,27 @@
#include "cairo-fixed-type-private.h"
typedef struct _cairo_array cairo_array_t;
typedef struct _cairo_hash_table cairo_hash_table_t;
typedef struct _cairo_cache cairo_cache_t;
typedef struct _cairo_hash_entry cairo_hash_entry_t;
typedef struct _cairo_surface_backend cairo_surface_backend_t;
typedef struct _cairo_clip cairo_clip_t;
typedef struct _cairo_output_stream cairo_output_stream_t;
typedef struct _cairo_scaled_font_subsets cairo_scaled_font_subsets_t;
typedef struct _cairo_paginated_surface_backend cairo_paginated_surface_backend_t;
typedef struct _cairo_scaled_font_backend cairo_scaled_font_backend_t;
typedef struct _cairo_clip_path cairo_clip_path_t;
typedef struct _cairo_color cairo_color_t;
typedef struct _cairo_font_face_backend cairo_font_face_backend_t;
typedef struct _cairo_gstate cairo_gstate_t;
typedef struct _cairo_hash_entry cairo_hash_entry_t;
typedef struct _cairo_hash_table cairo_hash_table_t;
typedef struct _cairo_image_surface cairo_image_surface_t;
typedef struct _cairo_output_stream cairo_output_stream_t;
typedef struct _cairo_paginated_surface_backend cairo_paginated_surface_backend_t;
typedef struct _cairo_path_fixed cairo_path_fixed_t;
typedef struct _cairo_rectangle_int16 cairo_glyph_size_t;
typedef struct _cairo_region cairo_region_t;
typedef struct _cairo_scaled_font_backend cairo_scaled_font_backend_t;
typedef struct _cairo_scaled_font_subsets cairo_scaled_font_subsets_t;
typedef struct _cairo_solid_pattern cairo_solid_pattern_t;
typedef struct _cairo_surface_backend cairo_surface_backend_t;
typedef struct _cairo_unscaled_font_backend cairo_unscaled_font_backend_t;
typedef struct _cairo_xlib_screen_info cairo_xlib_screen_info_t;
typedef cairo_array_t cairo_user_data_array_t;
/**
@ -108,6 +118,7 @@ struct _cairo_array {
struct _cairo_font_options {
cairo_antialias_t antialias;
cairo_subpixel_order_t subpixel_order;
cairo_lcd_filter_t lcd_filter;
cairo_hint_style_t hint_style;
cairo_hint_metrics_t hint_metrics;
};
@ -137,7 +148,6 @@ typedef enum _cairo_int_status {
CAIRO_INT_STATUS_UNSUPPORTED = 100,
CAIRO_INT_STATUS_DEGENERATE,
CAIRO_INT_STATUS_NOTHING_TO_DO,
CAIRO_INT_STATUS_CACHE_EMPTY,
CAIRO_INT_STATUS_FLATTEN_TRANSPARENCY,
CAIRO_INT_STATUS_IMAGE_FALLBACK,
CAIRO_INT_STATUS_ANALYZE_META_SURFACE_PATTERN,
@ -156,8 +166,6 @@ typedef enum _cairo_internal_surface_type {
CAIRO_INTERNAL_SURFACE_TYPE_TYPE3_GLYPH
} cairo_internal_surface_type_t;
typedef struct _cairo_region cairo_region_t;
typedef struct _cairo_point {
cairo_fixed_t x;
cairo_fixed_t y;
@ -199,8 +207,6 @@ struct _cairo_rectangle_int32 {
uint32_t width, height;
};
typedef struct _cairo_rectangle_int16 cairo_glyph_size_t;
struct _cairo_point_int16 {
int16_t x, y;
};
@ -233,13 +239,11 @@ typedef enum _cairo_direction {
CAIRO_DIRECTION_REVERSE
} cairo_direction_t;
typedef struct _cairo_path_fixed cairo_path_fixed_t;
typedef enum _cairo_clip_mode {
CAIRO_CLIP_MODE_PATH,
CAIRO_CLIP_MODE_REGION,
CAIRO_CLIP_MODE_MASK
} cairo_clip_mode_t;
typedef struct _cairo_clip_path cairo_clip_path_t;
typedef struct _cairo_edge {
cairo_line_t edge;
@ -292,9 +296,6 @@ typedef struct _cairo_pen {
cairo_pen_vertex_t vertices_embedded[32];
} cairo_pen_t;
typedef struct _cairo_color cairo_color_t;
typedef struct _cairo_image_surface cairo_image_surface_t;
typedef struct _cairo_stroke_style {
double line_width;
cairo_line_cap_t line_cap;

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

@ -195,6 +195,40 @@ _utf8_get_char_extended (const unsigned char *p,
return wc;
}
/**
* _cairo_utf8_get_char_validated:
* @p: a UTF-8 string
* @unicode: location to store one Unicode character
*
* Decodes the first character of a valid UTF-8 string, and returns
* the number of bytes consumed.
*
* Note that the string should be valid. Do not use this without
* validating the string first.
*
* Returns: the number of bytes forming the character returned.
**/
int
_cairo_utf8_get_char_validated (const char *p,
uint32_t *unicode)
{
int i, mask = 0, len;
uint32_t result;
unsigned char c = (unsigned char) *p;
UTF8_COMPUTE (c, mask, len);
if (len == -1) {
if (unicode)
*unicode = (uint32_t)-1;
return 1;
}
UTF8_GET (result, p, i, mask, len);
if (unicode)
*unicode = result;
return len;
}
/**
* _cairo_utf8_to_utf32:
* @str: an UTF-8 string
@ -266,7 +300,7 @@ _cairo_utf8_to_ucs4 (const char *str,
* _cairo_ucs4_to_utf8:
* @unicode: a UCS-4 character
* @utf8: buffer to write utf8 string into. Must have at least 4 bytes
* space available.
* space available. Or %NULL.
*
* Return value: Number of bytes in the utf8 string or 0 if an invalid
* unicode character
@ -279,7 +313,8 @@ _cairo_ucs4_to_utf8 (uint32_t unicode,
char *p;
if (unicode < 0x80) {
*utf8 = unicode;
if (utf8)
*utf8 = unicode;
return 1;
} else if (unicode < 0x800) {
bytes = 2;
@ -291,6 +326,9 @@ _cairo_ucs4_to_utf8 (uint32_t unicode,
return 0;
}
if (!utf8)
return bytes;
p = utf8 + bytes;
while (p > utf8) {
*--p = 0x80 | (unicode & 0x3f);

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

@ -38,6 +38,7 @@
#define CAIRO_USER_FONT_PRIVATE_H
#include "cairo.h"
#include "cairo-compiler-private.h"
cairo_private cairo_bool_t
_cairo_font_face_is_user (cairo_font_face_t *font_face);

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

@ -74,6 +74,28 @@ typedef struct _cairo_user_scaled_font {
/* #cairo_user_scaled_font_t */
static cairo_t *
_cairo_user_scaled_font_create_meta_context (cairo_user_scaled_font_t *scaled_font)
{
cairo_content_t content;
cairo_surface_t *meta_surface;
cairo_t *cr;
content = scaled_font->base.options.antialias == CAIRO_ANTIALIAS_SUBPIXEL ?
CAIRO_CONTENT_COLOR_ALPHA :
CAIRO_CONTENT_ALPHA;
meta_surface = _cairo_meta_surface_create (content, -1, -1);
cr = cairo_create (meta_surface);
cairo_surface_destroy (meta_surface);
cairo_set_matrix (cr, &scaled_font->base.scale);
cairo_set_font_size (cr, 1.0);
cairo_set_font_options (cr, &scaled_font->base.options);
return cr;
}
static const cairo_scaled_font_backend_t cairo_user_scaled_font_backend;
static cairo_int_status_t
@ -89,17 +111,9 @@ _cairo_user_scaled_glyph_init (void *abstract_font,
cairo_user_font_face_t *face =
(cairo_user_font_face_t *) scaled_font->base.font_face;
cairo_text_extents_t extents = scaled_font->default_glyph_extents;
cairo_content_t content = scaled_font->base.options.antialias == CAIRO_ANTIALIAS_SUBPIXEL ?
CAIRO_CONTENT_COLOR_ALPHA :
CAIRO_CONTENT_ALPHA;
cairo_t *cr;
meta_surface = _cairo_meta_surface_create (content, -1, -1);
cr = cairo_create (meta_surface);
cairo_set_matrix (cr, &scaled_font->base.scale);
cairo_set_font_size (cr, 1.0);
cairo_set_font_options (cr, &scaled_font->base.options);
cr = _cairo_user_scaled_font_create_meta_context (scaled_font);
if (face->scaled_font_methods.render_glyph)
status = face->scaled_font_methods.render_glyph ((cairo_scaled_font_t *)scaled_font,
@ -111,6 +125,8 @@ _cairo_user_scaled_glyph_init (void *abstract_font,
if (status == CAIRO_STATUS_SUCCESS)
status = cairo_status (cr);
meta_surface = cairo_surface_reference (cairo_get_target (cr));
cairo_destroy (cr);
if (status) {
@ -131,8 +147,11 @@ _cairo_user_scaled_glyph_init (void *abstract_font,
cairo_box_t bbox;
double x1, y1, x2, y2;
double x_scale, y_scale;
cairo_surface_t *null_surface = _cairo_null_surface_create (cairo_surface_get_content (meta_surface));
cairo_surface_t *analysis_surface = _cairo_analysis_surface_create (null_surface, -1, -1);
cairo_surface_t *null_surface;
cairo_surface_t *analysis_surface;
null_surface = _cairo_null_surface_create (cairo_surface_get_content (meta_surface));
analysis_surface = _cairo_analysis_surface_create (null_surface, -1, -1);
cairo_surface_destroy (null_surface);
_cairo_analysis_surface_set_ctm (analysis_surface, &scaled_font->extent_scale);
@ -140,6 +159,9 @@ _cairo_user_scaled_glyph_init (void *abstract_font,
_cairo_analysis_surface_get_bounding_box (analysis_surface, &bbox);
cairo_surface_destroy (analysis_surface);
if (status)
return status;
_cairo_box_to_doubles (&bbox, &x1, &y1, &x2, &y2);
x_scale = scaled_font->extent_x_scale;
@ -249,12 +271,16 @@ _cairo_user_ucs4_to_index (void *abstract_font,
}
static cairo_int_status_t
_cairo_user_text_to_glyphs (void *abstract_font,
double x,
double y,
const char *utf8,
cairo_glyph_t **glyphs,
int *num_glyphs)
_cairo_user_text_to_glyphs (void *abstract_font,
double x,
double y,
const char *utf8,
int utf8_len,
cairo_glyph_t **glyphs,
int *num_glyphs,
cairo_text_cluster_t **clusters,
int *num_clusters,
cairo_bool_t *backward)
{
cairo_int_status_t status = CAIRO_INT_STATUS_UNSUPPORTED;
@ -264,25 +290,21 @@ _cairo_user_text_to_glyphs (void *abstract_font,
if (face->scaled_font_methods.text_to_glyphs) {
int i;
int orig_num_glyphs = *num_glyphs;
*glyphs = NULL;
*num_glyphs = -1;
/* XXX currently user allocs glyphs array but cairo frees it */
status = face->scaled_font_methods.text_to_glyphs (&scaled_font->base,
utf8, glyphs, num_glyphs);
utf8, utf8_len,
glyphs, num_glyphs,
clusters, num_clusters,
backward);
if (status != CAIRO_STATUS_SUCCESS) {
status = _cairo_scaled_font_set_error (&scaled_font->base, status);
if (*glyphs) {
free (*glyphs);
*glyphs = NULL;
}
if (status != CAIRO_STATUS_SUCCESS)
return status;
}
if (*num_glyphs < 0)
if (*num_glyphs < 0) {
*num_glyphs = orig_num_glyphs;
return CAIRO_INT_STATUS_UNSUPPORTED;
}
/* Convert from font space to user space and add x,y */
for (i = 0; i < *num_glyphs; i++) {
@ -351,7 +373,7 @@ _cairo_user_font_face_scaled_font_create (void *abstract_
double fixed_scale, x_scale, y_scale;
user_scaled_font->extent_scale = user_scaled_font->base.scale_inverse;
status = _cairo_matrix_compute_scale_factors (&user_scaled_font->extent_scale,
status = _cairo_matrix_compute_basis_scale_factors (&user_scaled_font->extent_scale,
&x_scale, &y_scale,
1);
if (status == CAIRO_STATUS_SUCCESS) {
@ -377,6 +399,8 @@ _cairo_user_font_face_scaled_font_create (void *abstract_
if (status == CAIRO_STATUS_SUCCESS && font_face->scaled_font_methods.init != NULL) {
cairo_t *cr;
/* Lock the scaled_font mutex such that user doesn't accidentally try
* to use it just yet. */
CAIRO_MUTEX_LOCK (user_scaled_font->base.mutex);
@ -384,9 +408,17 @@ _cairo_user_font_face_scaled_font_create (void *abstract_
/* Give away fontmap lock such that user-font can use other fonts */
_cairo_scaled_font_register_placeholder_and_unlock_font_map (&user_scaled_font->base);
cr = _cairo_user_scaled_font_create_meta_context (user_scaled_font);
status = font_face->scaled_font_methods.init (&user_scaled_font->base,
cr,
&font_extents);
if (status == CAIRO_STATUS_SUCCESS)
status = cairo_status (cr);
cairo_destroy (cr);
_cairo_scaled_font_unregister_placeholder_and_lock_font_map (&user_scaled_font->base);
CAIRO_MUTEX_UNLOCK (user_scaled_font->base.mutex);

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

@ -0,0 +1,88 @@
/* -*- Mode: c; c-basic-offset: 4; indent-tabs-mode: t; tab-width: 8; -*- */
/* cairo - a vector graphics library with display and print output
*
* Copyright © 2002 University of Southern California
* Copyright © 2005 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 University of Southern
* California.
*
* Contributor(s):
* Carl D. Worth <cworth@cworth.org>
*/
#define CAIRO_VERSION_H 1
#include "cairoint.h"
/* get the "real" version info instead of dummy cairo-version.h */
#undef CAIRO_VERSION_H
#include "cairo-features.h"
/**
* cairo_version:
*
* Returns the version of the cairo library encoded in a single
* integer as per %CAIRO_VERSION_ENCODE. The encoding ensures that
* later versions compare greater than earlier versions.
*
* A run-time comparison to check that cairo's version is greater than
* or equal to version X.Y.Z could be performed as follows:
*
* <informalexample><programlisting>
* if (cairo_version() >= CAIRO_VERSION_ENCODE(X,Y,Z)) {...}
* </programlisting></informalexample>
*
* See also cairo_version_string() as well as the compile-time
* equivalents %CAIRO_VERSION and %CAIRO_VERSION_STRING.
*
* Return value: the encoded version.
**/
int
cairo_version (void)
{
return CAIRO_VERSION;
}
/**
* cairo_version_string:
*
* Returns the version of the cairo library as a human-readable string
* of the form "X.Y.Z".
*
* See also cairo_version() as well as the compile-time equivalents
* %CAIRO_VERSION_STRING and %CAIRO_VERSION.
*
* Return value: a string containing the version.
**/
const char*
cairo_version_string (void)
{
return CAIRO_VERSION_STRING;
}
slim_hidden_def (cairo_version_string);

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

@ -0,0 +1,16 @@
/* This is a dummy file.
* The actual version info is in toplevel cairo-version.h.
* The purpose of this file is to make most of the source files NOT depend
* on the real cairo-version.h, and as a result, changing library version
* would not cause a complete rebuild of all object files (just a relink).
* This is useful when bisecting. */
#ifndef CAIRO_VERSION_H
#define CAIRO_VERSION_H
#if 0
#define CAIRO_VERSION_MAJOR USE_cairo_version_OR_cairo_version_string_INSTEAD
#define CAIRO_VERSION_MINOR USE_cairo_version_OR_cairo_version_string_INSTEAD
#define CAIRO_VERSION_MICRO USE_cairo_version_OR_cairo_version_string_INSTEAD
#endif
#endif

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

@ -59,25 +59,26 @@
# ifndef HAVE_UINT64_T
# define HAVE_UINT64_T 1
# endif
# ifndef INT16_MIN
# define INT16_MIN (-32767-1)
# endif
# ifndef INT16_MAX
# define INT16_MAX (32767)
# endif
# ifndef UINT16_MAX
# define UINT16_MAX (65535)
# endif
# ifndef INT32_MIN
# define INT32_MIN (-2147483647-1)
# endif
# ifndef INT32_MAX
# define INT32_MAX (2147483647)
# endif
#else
#error Cannot find definitions for fixed-width integral types (uint8_t, uint32_t, etc.)
#endif
#ifndef INT16_MIN
# define INT16_MIN (-32767-1)
#endif
#ifndef INT16_MAX
# define INT16_MAX (32767)
#endif
#ifndef UINT16_MAX
# define UINT16_MAX (65535)
#endif
#ifndef INT32_MIN
# define INT32_MIN (-2147483647-1)
#endif
#ifndef INT32_MAX
# define INT32_MAX (2147483647)
#endif
#if HAVE_BYTESWAP_H
# include <byteswap.h>
#endif

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

@ -130,6 +130,28 @@ _cairo_win32_scaled_font_init_glyph_path (cairo_win32_scaled_font_t *scaled_font
#define NEARLY_ZERO(d) (fabs(d) < (1. / 65536.))
static HDC
_get_global_font_dc (void)
{
static HDC hdc;
if (!hdc) {
hdc = CreateCompatibleDC (NULL);
if (!hdc) {
_cairo_win32_print_gdi_error ("_get_global_font_dc");
return NULL;
}
if (!SetGraphicsMode (hdc, GM_ADVANCED)) {
_cairo_win32_print_gdi_error ("_get_global_font_dc");
DeleteDC (hdc);
return NULL;
}
}
return hdc;
}
static cairo_status_t
_compute_transform (cairo_win32_scaled_font_t *scaled_font,
cairo_matrix_t *sc)
@ -175,7 +197,7 @@ _compute_transform (cairo_win32_scaled_font_t *scaled_font,
sc->xx, sc->yx, sc->xy, sc->yy, 0, 0);
if (!scaled_font->preserve_axes) {
status = _cairo_matrix_compute_scale_factors (&scaled_font->logical_to_device,
status = _cairo_matrix_compute_basis_scale_factors (&scaled_font->logical_to_device,
&scaled_font->x_scale, &scaled_font->y_scale,
TRUE); /* XXX: Handle vertical text */
if (status)
@ -259,10 +281,15 @@ _win32_scaled_font_create (LOGFONTW *logfont,
const cairo_font_options_t *options,
cairo_scaled_font_t **font_out)
{
HDC hdc;
cairo_win32_scaled_font_t *f;
cairo_matrix_t scale;
cairo_status_t status;
hdc = _get_global_font_dc ();
if (hdc == NULL)
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
f = malloc (sizeof(cairo_win32_scaled_font_t));
if (f == NULL)
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
@ -363,30 +390,9 @@ _win32_scaled_font_set_identity_transform (HDC hdc)
return CAIRO_STATUS_SUCCESS;
}
static HDC
_get_global_font_dc (void)
{
static HDC hdc;
if (!hdc) {
hdc = CreateCompatibleDC (NULL);
if (!hdc) {
_cairo_win32_print_gdi_error ("_get_global_font_dc");
return NULL;
}
if (!SetGraphicsMode (hdc, GM_ADVANCED)) {
_cairo_win32_print_gdi_error ("_get_global_font_dc");
DeleteDC (hdc);
return NULL;
}
}
return hdc;
}
static HFONT
_win32_scaled_font_get_scaled_hfont (cairo_win32_scaled_font_t *scaled_font)
static cairo_status_t
_win32_scaled_font_get_scaled_hfont (cairo_win32_scaled_font_t *scaled_font,
HFONT *hfont_out)
{
if (!scaled_font->scaled_hfont) {
LOGFONTW logfont = scaled_font->logfont;
@ -397,50 +403,46 @@ _win32_scaled_font_get_scaled_hfont (cairo_win32_scaled_font_t *scaled_font)
logfont.lfQuality = scaled_font->quality;
scaled_font->scaled_hfont = CreateFontIndirectW (&logfont);
if (!scaled_font->scaled_hfont) {
_cairo_win32_print_gdi_error ("_win32_scaled_font_get_scaled_hfont");
return NULL;
}
if (!scaled_font->scaled_hfont)
return _cairo_win32_print_gdi_error ("_win32_scaled_font_get_scaled_hfont");
}
return scaled_font->scaled_hfont;
*hfont_out = scaled_font->scaled_hfont;
return CAIRO_STATUS_SUCCESS;
}
static HFONT
static cairo_status_t
_win32_scaled_font_get_unscaled_hfont (cairo_win32_scaled_font_t *scaled_font,
HDC hdc)
HDC hdc,
HFONT *hfont_out)
{
if (!scaled_font->unscaled_hfont) {
if (scaled_font->unscaled_hfont == NULL) {
OUTLINETEXTMETRIC *otm;
unsigned int otm_size;
HFONT scaled_hfont;
LOGFONTW logfont;
cairo_status_t status;
scaled_hfont = _win32_scaled_font_get_scaled_hfont (scaled_font);
if (!scaled_hfont)
return NULL;
status = _win32_scaled_font_get_scaled_hfont (scaled_font,
&scaled_hfont);
if (status)
return status;
if (!SelectObject (hdc, scaled_hfont)) {
_cairo_win32_print_gdi_error ("_win32_scaled_font_get_unscaled_hfont:SelectObject");
return NULL;
}
if (! SelectObject (hdc, scaled_hfont))
return _cairo_win32_print_gdi_error ("_win32_scaled_font_get_unscaled_hfont:SelectObject");
otm_size = GetOutlineTextMetrics (hdc, 0, NULL);
if (!otm_size) {
_cairo_win32_print_gdi_error ("_win32_scaled_font_get_unscaled_hfont:GetOutlineTextMetrics");
return NULL;
}
if (! otm_size)
return _cairo_win32_print_gdi_error ("_win32_scaled_font_get_unscaled_hfont:GetOutlineTextMetrics");
otm = malloc (otm_size);
if (!otm) {
_cairo_error_throw (CAIRO_STATUS_NO_MEMORY);
return NULL;
}
if (otm == NULL)
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
if (!GetOutlineTextMetrics (hdc, otm_size, otm)) {
_cairo_win32_print_gdi_error ("_win32_scaled_font_get_unscaled_hfont:GetOutlineTextMetrics");
if (! GetOutlineTextMetrics (hdc, otm_size, otm)) {
status = _cairo_win32_print_gdi_error ("_win32_scaled_font_get_unscaled_hfont:GetOutlineTextMetrics");
free (otm);
return NULL;
return status;
}
scaled_font->em_square = otm->otmEMSquare;
@ -454,13 +456,12 @@ _win32_scaled_font_get_unscaled_hfont (cairo_win32_scaled_font_t *scaled_font,
logfont.lfQuality = scaled_font->quality;
scaled_font->unscaled_hfont = CreateFontIndirectW (&logfont);
if (!scaled_font->unscaled_hfont) {
_cairo_win32_print_gdi_error ("_win32_scaled_font_get_unscaled_hfont:CreateIndirect");
return NULL;
}
if (! scaled_font->unscaled_hfont)
return _cairo_win32_print_gdi_error ("_win32_scaled_font_get_unscaled_hfont:CreateIndirect");
}
return scaled_font->unscaled_hfont;
*hfont_out = scaled_font->unscaled_hfont;
return CAIRO_STATUS_SUCCESS;
}
static cairo_status_t
@ -471,9 +472,9 @@ _cairo_win32_scaled_font_select_unscaled_font (cairo_scaled_font_t *scaled_font,
HFONT hfont;
HFONT old_hfont = NULL;
hfont = _win32_scaled_font_get_unscaled_hfont ((cairo_win32_scaled_font_t *)scaled_font, hdc);
if (!hfont)
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
status = _win32_scaled_font_get_unscaled_hfont ((cairo_win32_scaled_font_t *)scaled_font, hdc, &hfont);
if (status)
return status;
old_hfont = SelectObject (hdc, hfont);
if (!old_hfont)
@ -615,7 +616,7 @@ _cairo_win32_scaled_font_type1_text_to_glyphs (cairo_win32_scaled_font_t *scaled
int n16;
int i;
WORD *glyph_indices = NULL;
cairo_status_t status = CAIRO_STATUS_SUCCESS;
cairo_status_t status;
double x_pos, y_pos;
HDC hdc = NULL;
cairo_matrix_t mat;
@ -631,10 +632,7 @@ _cairo_win32_scaled_font_type1_text_to_glyphs (cairo_win32_scaled_font_t *scaled
}
hdc = _get_global_font_dc ();
if (!hdc) {
status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
goto FAIL2;
}
assert (hdc != NULL);
status = cairo_win32_scaled_font_select_font (&scaled_font->base, hdc);
if (status)
@ -655,7 +653,8 @@ _cairo_win32_scaled_font_type1_text_to_glyphs (cairo_win32_scaled_font_t *scaled
x_pos = x;
y_pos = y;
mat = scaled_font->base.ctm;
cairo_matrix_invert (&mat);
status = cairo_matrix_invert (&mat);
assert (status == CAIRO_STATUS_SUCCESS);
for (i = 0; i < n16; i++) {
cairo_scaled_glyph_t *scaled_glyph;
@ -704,7 +703,7 @@ _cairo_win32_scaled_font_text_to_glyphs (void *abstract_font,
unsigned int buffer_size, i;
WCHAR *glyph_indices = NULL;
int *dx = NULL;
cairo_status_t status = CAIRO_STATUS_SUCCESS;
cairo_status_t status;
double x_pos, y_pos;
double x_incr, y_incr;
HDC hdc = NULL;
@ -743,10 +742,7 @@ _cairo_win32_scaled_font_text_to_glyphs (void *abstract_font,
}
hdc = _get_global_font_dc ();
if (!hdc) {
status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
goto FAIL1;
}
assert (hdc != NULL);
status = cairo_win32_scaled_font_select_font (&scaled_font->base, hdc);
if (status)
@ -786,7 +782,7 @@ _cairo_win32_scaled_font_text_to_glyphs (void *abstract_font,
/* Too small a buffer, try again */
buffer_size *= 1.5;
buffer_size += buffer_size / 2;
if (buffer_size > INT_MAX) {
status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
goto FAIL2;
@ -826,6 +822,35 @@ _cairo_win32_scaled_font_text_to_glyphs (void *abstract_font,
return status;
}
static unsigned long
_cairo_win32_scaled_font_ucs4_to_index (void *abstract_font,
uint32_t ucs4)
{
cairo_win32_scaled_font_t *scaled_font = abstract_font;
wchar_t unicode[2];
WORD glyph_index;
HDC hdc = NULL;
cairo_status_t status;
hdc = _get_global_font_dc ();
assert (hdc != NULL);
status = cairo_win32_scaled_font_select_font (&scaled_font->base, hdc);
if (status)
return 0;
unicode[0] = ucs4;
unicode[1] = 0;
if (GetGlyphIndicesW (hdc, unicode, 1, &glyph_index, 0) == GDI_ERROR) {
_cairo_win32_print_gdi_error ("_cairo_win32_scaled_font_ucs4_to_index:GetGlyphIndicesW");
glyph_index = 0;
}
cairo_win32_scaled_font_done_font (&scaled_font->base);
return glyph_index;
}
static cairo_status_t
_cairo_win32_scaled_font_set_metrics (cairo_win32_scaled_font_t *scaled_font)
{
@ -836,8 +861,7 @@ _cairo_win32_scaled_font_set_metrics (cairo_win32_scaled_font_t *scaled_font)
HDC hdc;
hdc = _get_global_font_dc ();
if (!hdc)
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
assert (hdc != NULL);
if (scaled_font->preserve_axes || scaled_font->base.options.hint_metrics == CAIRO_HINT_METRICS_OFF) {
/* For 90-degree rotations (including 0), we get the metrics
@ -912,8 +936,7 @@ _cairo_win32_scaled_font_init_glyph_metrics (cairo_win32_scaled_font_t *scaled_f
HDC hdc;
hdc = _get_global_font_dc ();
if (!hdc)
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
assert (hdc != NULL);
if (scaled_font->is_bitmap) {
/* GetGlyphOutline will not work. Assume that the glyph does not extend outside the font box. */
@ -924,13 +947,16 @@ _cairo_win32_scaled_font_init_glyph_metrics (cairo_win32_scaled_font_t *scaled_f
cairo_scaled_font_extents (&scaled_font->base, &font_extents);
status = cairo_win32_scaled_font_select_font (&scaled_font->base, hdc);
if (!status) {
if (!GetCharWidth32(hdc, charIndex, charIndex, &width)) {
status = _cairo_win32_print_gdi_error ("_cairo_win32_scaled_font_init_glyph_metrics:GetCharWidth32");
width = 0;
}
if (status)
return status;
if (!GetCharWidth32(hdc, charIndex, charIndex, &width)) {
status = _cairo_win32_print_gdi_error ("_cairo_win32_scaled_font_init_glyph_metrics:GetCharWidth32");
width = 0;
}
cairo_win32_scaled_font_done_font (&scaled_font->base);
if (status)
return status;
extents.x_bearing = 0;
extents.y_bearing = scaled_font->base.ctm.yy * (-font_extents.ascent / scaled_font->y_scale);
@ -945,6 +971,7 @@ _cairo_win32_scaled_font_init_glyph_metrics (cairo_win32_scaled_font_t *scaled_f
status = cairo_win32_scaled_font_select_font (&scaled_font->base, hdc);
if (status)
return status;
if (GetGlyphOutlineW (hdc, _cairo_scaled_glyph_index (scaled_glyph),
GGO_METRICS | GGO_GLYPH_INDEX,
&metrics, 0, NULL, &matrix) == GDI_ERROR) {
@ -952,6 +979,8 @@ _cairo_win32_scaled_font_init_glyph_metrics (cairo_win32_scaled_font_t *scaled_f
memset (&metrics, 0, sizeof (GLYPHMETRICS));
}
cairo_win32_scaled_font_done_font (&scaled_font->base);
if (status)
return status;
if (scaled_font->swap_axes) {
extents.x_bearing = - metrics.gmptGlyphOrigin.y / scaled_font->y_scale;
@ -984,6 +1013,9 @@ _cairo_win32_scaled_font_init_glyph_metrics (cairo_win32_scaled_font_t *scaled_f
* of the font.
*/
status = _cairo_win32_scaled_font_select_unscaled_font (&scaled_font->base, hdc);
if (status)
return status;
if (GetGlyphOutlineW (hdc, _cairo_scaled_glyph_index (scaled_glyph),
GGO_METRICS | GGO_GLYPH_INDEX,
&metrics, 0, NULL, &matrix) == GDI_ERROR) {
@ -991,6 +1023,8 @@ _cairo_win32_scaled_font_init_glyph_metrics (cairo_win32_scaled_font_t *scaled_f
memset (&metrics, 0, sizeof (GLYPHMETRICS));
}
_cairo_win32_scaled_font_done_unscaled_font (&scaled_font->base);
if (status)
return status;
extents.x_bearing = (double)metrics.gmptGlyphOrigin.x / scaled_font->em_square;
extents.y_bearing = - (double)metrics.gmptGlyphOrigin.y / scaled_font->em_square;
@ -1024,13 +1058,13 @@ _cairo_win32_scaled_font_glyph_bbox (void *abstract_font,
int x1 = 0, x2 = 0, y1 = 0, y2 = 0;
if (num_glyphs > 0) {
HDC hdc = _get_global_font_dc ();
HDC hdc;
GLYPHMETRICS metrics;
cairo_status_t status;
int i;
if (!hdc)
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
hdc = _get_global_font_dc ();
assert (hdc != NULL);
status = cairo_win32_scaled_font_select_font (&scaled_font->base, hdc);
if (status)
@ -1164,14 +1198,17 @@ _add_glyph (cairo_glyph_state_t *state,
return CAIRO_STATUS_SUCCESS;
}
static void
static cairo_status_t
_finish_glyphs (cairo_glyph_state_t *state)
{
/* ignore errors as we only call _finish_glyphs on the error path */
_flush_glyphs (state);
cairo_status_t status;
status = _flush_glyphs (state);
_cairo_array_fini (&state->glyphs);
_cairo_array_fini (&state->dx);
return status;
}
static cairo_status_t
@ -1181,10 +1218,10 @@ _draw_glyphs_on_surface (cairo_win32_surface_t *surface,
int x_offset,
int y_offset,
const cairo_glyph_t *glyphs,
int num_glyphs)
int num_glyphs)
{
cairo_glyph_state_t state;
cairo_status_t status = CAIRO_STATUS_SUCCESS;
cairo_status_t status, status2;
int i;
if (!SaveDC (surface->dc))
@ -1208,7 +1245,10 @@ _draw_glyphs_on_surface (cairo_win32_surface_t *surface,
}
FAIL2:
_finish_glyphs (&state);
status2 = _finish_glyphs (&state);
if (status == CAIRO_STATUS_SUCCESS)
status = status2;
cairo_win32_scaled_font_done_font (&scaled_font->base);
FAIL1:
RestoreDC (surface->dc, -1);
@ -1260,10 +1300,13 @@ _compute_a8_mask (cairo_win32_surface_t *mask_surface)
cairo_image_surface_t *image8;
int i, j;
if (image24->base.status)
return cairo_surface_reference (&image24->base);
image8 = (cairo_image_surface_t *)cairo_image_surface_create (CAIRO_FORMAT_A8,
image24->width, image24->height);
if (image8->base.status)
return NULL;
return &image8->base;
for (i = 0; i < image24->height; i++) {
uint32_t *p = (uint32_t *) (image24->data + i * image24->stride);
@ -1402,8 +1445,9 @@ _cairo_win32_scaled_font_show_glyphs (void *abstract_font,
} else {
mask_surface = _compute_a8_mask (tmp_surface);
cairo_surface_destroy (&tmp_surface->base);
if (!mask_surface)
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
status = mask_surface->status;
if (status)
return status;
}
/* For op == OVER, no-cleartype, a possible optimization here is to
@ -1435,13 +1479,12 @@ _cairo_win32_scaled_font_load_truetype_table (void *abstract_font,
unsigned char *buffer,
unsigned long *length)
{
cairo_win32_scaled_font_t *scaled_font = abstract_font;
HDC hdc;
cairo_status_t status;
cairo_win32_scaled_font_t *scaled_font = abstract_font;
hdc = _get_global_font_dc ();
if (!hdc)
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
assert (hdc != NULL);
tag = (tag&0x000000ff)<<24 | (tag&0x0000ff00)<<8 | (tag&0x00ff0000)>>8 | (tag&0xff000000)>>24;
status = cairo_win32_scaled_font_select_font (&scaled_font->base, hdc);
@ -1457,8 +1500,8 @@ _cairo_win32_scaled_font_load_truetype_table (void *abstract_font,
return status;
}
static cairo_status_t
_cairo_win32_scaled_font_index_to_ucs4 (void *abstract_font,
static cairo_int_status_t
_cairo_win32_scaled_font_index_to_ucs4 (void *abstract_font,
unsigned long index,
uint32_t *ucs4)
{
@ -1469,11 +1512,10 @@ _cairo_win32_scaled_font_index_to_ucs4 (void *abstract_font,
HDC hdc = NULL;
int res;
unsigned int i, j, num_glyphs;
cairo_status_t status = CAIRO_STATUS_SUCCESS;
cairo_status_t status;
hdc = _get_global_font_dc ();
if (!hdc)
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
assert (hdc != NULL);
status = cairo_win32_scaled_font_select_font (&scaled_font->base, hdc);
if (status)
@ -1553,7 +1595,7 @@ static cairo_status_t
_cairo_win32_scaled_font_init_glyph_surface (cairo_win32_scaled_font_t *scaled_font,
cairo_scaled_glyph_t *scaled_glyph)
{
cairo_status_t status = CAIRO_STATUS_SUCCESS;
cairo_status_t status;
cairo_glyph_t glyph;
cairo_win32_surface_t *surface;
cairo_t *cr;
@ -1571,23 +1613,35 @@ _cairo_win32_scaled_font_init_glyph_surface (cairo_win32_scaled_font_t *scaled_f
surface = (cairo_win32_surface_t *)
cairo_win32_surface_create_with_dib (CAIRO_FORMAT_RGB24, width, height);
cr = cairo_create((cairo_surface_t *)surface);
cr = cairo_create (&surface->base);
cairo_set_source_rgb (cr, 1, 1, 1);
cairo_paint (cr);
status = cairo_status (cr);
cairo_destroy(cr);
if (status)
goto FAIL;
glyph.index = _cairo_scaled_glyph_index (scaled_glyph);
glyph.x = -x1;
glyph.y = -y1;
status = _draw_glyphs_on_surface (surface, scaled_font, RGB(0,0,0),
0, 0, &glyph, 1);
if (status)
goto FAIL;
GdiFlush();
image = _compute_a8_mask (surface);
cairo_surface_set_device_offset ((cairo_surface_t *)image, -x1, -y1);
status = image->status;
if (status)
goto FAIL;
cairo_surface_set_device_offset (image, -x1, -y1);
_cairo_scaled_glyph_set_surface (scaled_glyph,
&scaled_font->base,
(cairo_image_surface_t*)image);
(cairo_image_surface_t *) image);
FAIL:
cairo_surface_destroy (&surface->base);
return status;
@ -1623,8 +1677,7 @@ _cairo_win32_scaled_font_init_glyph_path (cairo_win32_scaled_font_t *scaled_font
return CAIRO_INT_STATUS_UNSUPPORTED;
hdc = _get_global_font_dc ();
if (!hdc)
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
assert (hdc != NULL);
path = _cairo_path_fixed_create ();
if (!path)
@ -1651,7 +1704,6 @@ _cairo_win32_scaled_font_init_glyph_path (cairo_win32_scaled_font_t *scaled_font
}
ptr = buffer = malloc (bytesGlyph);
if (!buffer) {
status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
goto CLEANUP_FONT;
@ -1780,8 +1832,8 @@ const cairo_scaled_font_backend_t _cairo_win32_scaled_font_backend = {
_cairo_win32_scaled_font_create_toy,
_cairo_win32_scaled_font_fini,
_cairo_win32_scaled_font_glyph_init,
_cairo_win32_scaled_font_text_to_glyphs,
NULL, /* ucs4_to_index */
NULL, /* _cairo_win32_scaled_font_text_to_glyphs, FIXME */
_cairo_win32_scaled_font_ucs4_to_index,
_cairo_win32_scaled_font_show_glyphs,
_cairo_win32_scaled_font_load_truetype_table,
_cairo_win32_scaled_font_index_to_ucs4,
@ -1985,9 +2037,9 @@ cairo_win32_scaled_font_select_font (cairo_scaled_font_t *scaled_font,
if (scaled_font->status)
return scaled_font->status;
hfont = _win32_scaled_font_get_scaled_hfont ((cairo_win32_scaled_font_t *)scaled_font);
if (!hfont)
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
status = _win32_scaled_font_get_scaled_hfont ((cairo_win32_scaled_font_t *)scaled_font, &hfont);
if (status)
return status;
old_hfont = SelectObject (hdc, hfont);
if (!old_hfont)

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

@ -51,6 +51,7 @@
#include "cairo-clip-private.h"
#include "cairo-win32-private.h"
#include "cairo-meta-surface-private.h"
#include "cairo-scaled-font-subsets-private.h"
#include <windows.h>
@ -1313,16 +1314,14 @@ _cairo_win32_printing_surface_show_glyphs (void *abstract_surfac
}
if (surface->paginated_mode == CAIRO_PAGINATED_MODE_ANALYZE) {
/* Calling ExtTextOutW() with ETO_GLYPH_INDEX and a Type 1 or
* bitmap font on a printer DC prints garbled text. The text
* displays correctly on a display DC. It appears that when
* using a printer DC. ExtTextOutW() only works with
* characters and not glyph indices.
/* When printing bitmap fonts to a printer DC, Windows may
* substitute an outline font for bitmap font. As the win32
* font backend always uses a screen DC when obtaining the
* font metrics the metrics of the substituted font will not
* match the metrics that the win32 font backend returns.
*
* For now we don't use ExtTextOutW for Type 1 or bitmap
* fonts. These fonts will go through the fallback path for
* non Windows fonts. ie filled outlines for Type 1 fonts and
* fallback images for bitmap fonts.
* If we are printing a bitmap font, use fallback images to
* ensure the font is not substituted.
*/
if (cairo_scaled_font_get_type (scaled_font) == CAIRO_FONT_TYPE_WIN32) {
if (_cairo_win32_scaled_font_is_bitmap (scaled_font))
@ -1364,10 +1363,46 @@ _cairo_win32_printing_surface_show_glyphs (void *abstract_surfac
}
if (cairo_scaled_font_get_type (scaled_font) == CAIRO_FONT_TYPE_WIN32 &&
! _cairo_win32_scaled_font_is_type1 (scaled_font) &&
source->type == CAIRO_PATTERN_TYPE_SOLID)
{
cairo_matrix_t ctm;
cairo_glyph_t *type1_glyphs = NULL;
cairo_scaled_font_subsets_glyph_t subset_glyph;
/* Calling ExtTextOutW() with ETO_GLYPH_INDEX and a Type 1
* font on a printer DC prints garbled text. The text displays
* correctly on a display DC. When using a printer
* DC, ExtTextOutW() only works with characters and not glyph
* indices.
*
* For Type 1 fonts the glyph indices are converted back to
* unicode characters before calling _cairo_win32_surface_show_glyphs().
*
* As _cairo_win32_scaled_font_index_to_ucs4() is a slow
* operation, the font subsetting function
* _cairo_scaled_font_subsets_map_glyph() is used to obtain
* the unicode value because it caches the reverse mapping in
* the subsets.
*/
if (_cairo_win32_scaled_font_is_type1 (scaled_font)) {
type1_glyphs = _cairo_malloc_ab (num_glyphs, sizeof (cairo_glyph_t));
if (type1_glyphs == NULL)
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
memcpy (type1_glyphs, glyphs, num_glyphs * sizeof (cairo_glyph_t));
for (i = 0; i < num_glyphs; i++) {
status = _cairo_scaled_font_subsets_map_glyph (surface->font_subsets,
scaled_font,
type1_glyphs[i].index,
NULL, 0,
&subset_glyph);
if (status)
return status;
type1_glyphs[i].index = subset_glyph.unicode;
}
glyphs = type1_glyphs;
}
if (surface->has_ctm) {
for (i = 0; i < num_glyphs; i++)
@ -1385,6 +1420,9 @@ _cairo_win32_printing_surface_show_glyphs (void *abstract_surfac
if (surface->has_ctm)
cairo_scaled_font_destroy (scaled_font);
if (type1_glyphs != NULL)
free (type1_glyphs);
return status;
}
@ -1531,6 +1569,11 @@ cairo_win32_printing_surface_create (HDC hdc)
surface->saved_dc_bitmap = NULL;
surface->brush = NULL;
surface->old_brush = NULL;
surface->font_subsets = _cairo_scaled_font_subsets_create_scaled ();
if (surface->font_subsets == NULL) {
free (surface);
return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY));
}
GetClipBox(hdc, &rect);
surface->extents.x = rect.left;

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

@ -92,6 +92,7 @@ typedef struct _cairo_win32_surface {
cairo_bool_t has_ctm;
cairo_matrix_t ctm;
HBRUSH brush, old_brush;
cairo_scaled_font_subsets_t *font_subsets;
} cairo_win32_surface_t;
/* Surface DC flag values */

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

@ -50,6 +50,7 @@
#include "cairo-clip-private.h"
#include "cairo-paginated-private.h"
#include "cairo-win32-private.h"
#include "cairo-scaled-font-subsets-private.h"
#include <windows.h>
@ -359,6 +360,7 @@ _cairo_win32_surface_create_for_dc (HDC original_dc,
surface->had_simple_clip = FALSE;
surface->extents = surface->clip_rect;
surface->font_subsets = NULL;
_cairo_surface_init (&surface->base, &cairo_win32_surface_backend,
_cairo_content_from_format (format));
@ -497,6 +499,9 @@ _cairo_win32_surface_finish (void *abstract_surface)
if (surface->initial_clip_rgn)
DeleteObject (surface->initial_clip_rgn);
if (surface->font_subsets != NULL)
_cairo_scaled_font_subsets_destroy (surface->font_subsets);
return CAIRO_STATUS_SUCCESS;
}
@ -1578,6 +1583,7 @@ _cairo_win32_surface_show_glyphs (void *surface,
int start_x, start_y;
double user_x, user_y;
int logical_x, logical_y;
unsigned int glyph_index_option;
/* We can only handle win32 fonts */
if (cairo_scaled_font_get_type (scaled_font) != CAIRO_FONT_TYPE_WIN32)
@ -1663,10 +1669,24 @@ _cairo_win32_surface_show_glyphs (void *surface,
}
}
/* Using glyph indices for a Type 1 font does not work on a
* printer DC. The win32 printing surface will convert the the
* glyph indices of Type 1 fonts to the unicode values.
*/
if ((dst->flags & CAIRO_WIN32_SURFACE_FOR_PRINTING) &&
_cairo_win32_scaled_font_is_type1 (scaled_font))
{
glyph_index_option = 0;
}
else
{
glyph_index_option = ETO_GLYPH_INDEX;
}
win_result = ExtTextOutW(dst->dc,
start_x,
start_y,
ETO_GLYPH_INDEX | ETO_PDY,
glyph_index_option | ETO_PDY,
NULL,
glyph_buf,
num_glyphs,
@ -1731,6 +1751,7 @@ cairo_win32_surface_create (HDC hdc)
surface->saved_dc_bitmap = NULL;
surface->brush = NULL;
surface->old_brush = NULL;
surface->font_subsets = NULL;
GetClipBox(hdc, &rect);
surface->extents.x = rect.left;

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

@ -29,6 +29,8 @@
*
* The Initial Developer of the Original Code is Chris Wilson.
*
* Contributor(s):
* Karl Tomlinson <karlt+@karlt.net>, Mozilla Corporation
*/
#include "cairoint.h"
@ -66,11 +68,15 @@ static cairo_xlib_display_t *_cairo_xlib_display_list;
static int buggy_repeat_force = -1;
static void
_cairo_xlib_remove_close_display_hook_internal (cairo_xlib_display_t *display,
cairo_xlib_hook_t *hook);
static void
_cairo_xlib_call_close_display_hooks (cairo_xlib_display_t *display)
{
cairo_xlib_screen_info_t *screen;
cairo_xlib_hook_t *hooks, *list;
cairo_xlib_hook_t *hook;
/* call all registered shutdown routines */
CAIRO_MUTEX_LOCK (display->mutex);
@ -78,28 +84,16 @@ _cairo_xlib_call_close_display_hooks (cairo_xlib_display_t *display)
for (screen = display->screens; screen != NULL; screen = screen->next)
_cairo_xlib_screen_info_close_display (screen);
hooks = display->close_display_hooks;
while (hooks != NULL) {
display->close_display_hooks = NULL;
while (TRUE) {
hook = display->close_display_hooks;
if (hook == NULL)
break;
_cairo_xlib_remove_close_display_hook_internal (display, hook);
CAIRO_MUTEX_UNLOCK (display->mutex);
list = hooks;
do {
cairo_xlib_hook_t *hook = list;
list = hook->next;
hook->func (display->display, hook->data);
} while (list != NULL);
hook->func (display, hook);
CAIRO_MUTEX_LOCK (display->mutex);
do {
cairo_xlib_hook_t *hook = hooks;
hooks = hook->next;
_cairo_freelist_free (&display->hook_freelist, hook);
} while (hooks != NULL);
hooks = display->close_display_hooks;
}
display->closed = TRUE;
@ -153,7 +147,6 @@ _cairo_xlib_display_destroy (cairo_xlib_display_t *display)
_cairo_freelist_free (&display->wq_freelist, job);
}
_cairo_freelist_fini (&display->wq_freelist);
_cairo_freelist_fini (&display->hook_freelist);
CAIRO_MUTEX_FINI (display->mutex);
@ -279,7 +272,6 @@ _cairo_xlib_display_get (Display *dpy)
XESetCloseDisplay (dpy, codes->extension, _cairo_xlib_close_display);
_cairo_freelist_init (&display->wq_freelist, sizeof (cairo_xlib_job_t));
_cairo_freelist_init (&display->hook_freelist, sizeof (cairo_xlib_hook_t));
CAIRO_REFERENCE_COUNT_INIT (&display->ref_count, 2); /* add one for the CloseDisplay */
CAIRO_MUTEX_INIT (display->mutex);
@ -338,61 +330,43 @@ UNLOCK:
return display;
}
cairo_bool_t
_cairo_xlib_add_close_display_hook (Display *dpy, void (*func) (Display *, void *), void *data, const void *key)
void
_cairo_xlib_add_close_display_hook (cairo_xlib_display_t *display,
cairo_xlib_hook_t *hook)
{
cairo_xlib_display_t *display;
cairo_xlib_hook_t *hook;
cairo_bool_t ret = FALSE;
display = _cairo_xlib_display_get (dpy);
if (display == NULL)
return FALSE;
CAIRO_MUTEX_LOCK (display->mutex);
if (display->closed == FALSE) {
hook = _cairo_freelist_alloc (&display->hook_freelist);
if (hook != NULL) {
hook->func = func;
hook->data = data;
hook->key = key;
hook->next = display->close_display_hooks;
display->close_display_hooks = hook;
ret = TRUE;
}
}
hook->prev = NULL;
hook->next = display->close_display_hooks;
if (hook->next != NULL)
hook->next->prev = hook;
display->close_display_hooks = hook;
CAIRO_MUTEX_UNLOCK (display->mutex);
}
_cairo_xlib_display_destroy (display);
/* display->mutex must be held */
static void
_cairo_xlib_remove_close_display_hook_internal (cairo_xlib_display_t *display,
cairo_xlib_hook_t *hook)
{
if (display->close_display_hooks == hook)
display->close_display_hooks = hook->next;
else if (hook->prev != NULL)
hook->prev->next = hook->next;
return ret;
if (hook->next != NULL)
hook->next->prev = hook->prev;
hook->prev = NULL;
hook->next = NULL;
}
void
_cairo_xlib_remove_close_display_hooks (Display *dpy, const void *key)
_cairo_xlib_remove_close_display_hook (cairo_xlib_display_t *display,
cairo_xlib_hook_t *hook)
{
cairo_xlib_display_t *display;
cairo_xlib_hook_t *hook, *next, **prev;
display = _cairo_xlib_display_get (dpy);
if (display == NULL)
return;
CAIRO_MUTEX_LOCK (display->mutex);
prev = &display->close_display_hooks;
for (hook = display->close_display_hooks; hook != NULL; hook = next) {
next = hook->next;
if (hook->key == key) {
*prev = hook->next;
_cairo_freelist_free (&display->hook_freelist, hook);
} else
prev = &hook->next;
}
*prev = NULL;
_cairo_xlib_remove_close_display_hook_internal (display, hook);
CAIRO_MUTEX_UNLOCK (display->mutex);
_cairo_xlib_display_destroy (display);
}
cairo_status_t

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

@ -28,6 +28,10 @@
* The Original Code is the cairo graphics library.
*
* The Initial Developer of the Original Code is Red Hat, Inc.
*
* Contributors(s):
* Chris Wilson <chris@chris-wilson.co.uk>
* Karl Tomlinson <karlt+@karlt.net>, Mozilla Corporation
*/
#ifndef CAIRO_XLIB_PRIVATE_H
@ -48,10 +52,8 @@ typedef void (*cairo_xlib_notify_func) (Display *, void *);
typedef void (*cairo_xlib_notify_resource_func) (Display *, XID);
struct _cairo_xlib_hook {
cairo_xlib_hook_t *next;
void (*func) (Display *display, void *data);
void *data;
const void *key;
cairo_xlib_hook_t *prev, *next; /* private */
void (*func) (cairo_xlib_display_t *display, void *data);
};
struct _cairo_xlib_display {
@ -67,7 +69,6 @@ struct _cairo_xlib_display {
cairo_xlib_job_t *workqueue;
cairo_freelist_t wq_freelist;
cairo_freelist_t hook_freelist;
cairo_xlib_hook_t *close_display_hooks;
unsigned int buggy_repeat :1;
unsigned int closed :1;
@ -112,10 +113,11 @@ _cairo_xlib_display_reference (cairo_xlib_display_t *info);
cairo_private void
_cairo_xlib_display_destroy (cairo_xlib_display_t *info);
cairo_private cairo_bool_t
_cairo_xlib_add_close_display_hook (Display *display, void (*func) (Display *, void *), void *data, const void *key);
cairo_private void
_cairo_xlib_remove_close_display_hooks (Display *display, const void *key);
_cairo_xlib_add_close_display_hook (cairo_xlib_display_t *display, cairo_xlib_hook_t *hook);
cairo_private void
_cairo_xlib_remove_close_display_hook (cairo_xlib_display_t *display, cairo_xlib_hook_t *hook);
cairo_private cairo_status_t
_cairo_xlib_display_queue_work (cairo_xlib_display_t *display,
@ -134,7 +136,7 @@ _cairo_xlib_display_get_xrender_format (cairo_xlib_display_t *display,
cairo_format_t format);
cairo_private cairo_xlib_screen_info_t *
_cairo_xlib_screen_info_get (Display *display, Screen *screen);
_cairo_xlib_screen_info_get (cairo_xlib_display_t *display, Screen *screen);
cairo_private cairo_xlib_screen_info_t *
_cairo_xlib_screen_info_reference (cairo_xlib_screen_info_t *info);

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

@ -106,7 +106,6 @@ get_integer_default (Display *dpy,
const char *option,
int *value)
{
int i;
char *v, *e;
v = XGetDefault (dpy, "Xft", option);
@ -116,7 +115,7 @@ get_integer_default (Display *dpy,
return TRUE;
#endif
i = strtol (v, &e, 0);
*value = strtol (v, &e, 0);
if (e != v)
return TRUE;
}
@ -132,6 +131,18 @@ get_integer_default (Display *dpy,
#define FC_HINT_FULL 3
#endif
/* Fontconfig version older than 2.6 didn't have these options */
#ifndef FC_LCD_FILTER
#define FC_LCD_FILTER "lcdfilter"
#endif
/* Some Ubuntu versions defined FC_LCD_FILTER without defining the following */
#ifndef FC_LCD_NONE
#define FC_LCD_NONE 0
#define FC_LCD_DEFAULT 1
#define FC_LCD_LIGHT 2
#define FC_LCD_LEGACY 3
#endif
static void
_cairo_xlib_init_screen_font_options (Display *dpy, cairo_xlib_screen_info_t *info)
{
@ -139,13 +150,22 @@ _cairo_xlib_init_screen_font_options (Display *dpy, cairo_xlib_screen_info_t *in
cairo_bool_t xft_antialias;
int xft_hintstyle;
int xft_rgba;
int xft_lcdfilter;
cairo_antialias_t antialias;
cairo_subpixel_order_t subpixel_order;
cairo_lcd_filter_t lcd_filter;
cairo_hint_style_t hint_style;
if (!get_boolean_default (dpy, "antialias", &xft_antialias))
xft_antialias = TRUE;
if (!get_integer_default (dpy, "lcdfilter", &xft_lcdfilter)) {
/* -1 is an non-existant Fontconfig constant used to differentiate
* the case when no lcdfilter property is available.
*/
xft_lcdfilter = -1;
}
if (!get_boolean_default (dpy, "hinting", &xft_hinting))
xft_hinting = TRUE;
@ -228,6 +248,24 @@ _cairo_xlib_init_screen_font_options (Display *dpy, cairo_xlib_screen_info_t *in
subpixel_order = CAIRO_SUBPIXEL_ORDER_DEFAULT;
}
switch (xft_lcdfilter) {
case FC_LCD_NONE:
lcd_filter = CAIRO_LCD_FILTER_NONE;
break;
case FC_LCD_DEFAULT:
lcd_filter = CAIRO_LCD_FILTER_FIR5;
break;
case FC_LCD_LIGHT:
lcd_filter = CAIRO_LCD_FILTER_FIR3;
break;
case FC_LCD_LEGACY:
lcd_filter = CAIRO_LCD_FILTER_INTRA_PIXEL;
break;
default:
lcd_filter = CAIRO_LCD_FILTER_DEFAULT;
break;
}
if (xft_antialias) {
if (subpixel_order == CAIRO_SUBPIXEL_ORDER_DEFAULT)
antialias = CAIRO_ANTIALIAS_GRAY;
@ -240,6 +278,7 @@ _cairo_xlib_init_screen_font_options (Display *dpy, cairo_xlib_screen_info_t *in
cairo_font_options_set_hint_style (&info->font_options, hint_style);
cairo_font_options_set_antialias (&info->font_options, antialias);
cairo_font_options_set_subpixel_order (&info->font_options, subpixel_order);
cairo_font_options_set_lcd_filter (&info->font_options, lcd_filter);
cairo_font_options_set_hint_metrics (&info->font_options, CAIRO_HINT_METRICS_ON);
}
@ -307,19 +346,14 @@ _cairo_xlib_screen_info_destroy (cairo_xlib_screen_info_t *info)
}
cairo_xlib_screen_info_t *
_cairo_xlib_screen_info_get (Display *dpy, Screen *screen)
_cairo_xlib_screen_info_get (cairo_xlib_display_t *display, Screen *screen)
{
cairo_xlib_display_t *display;
cairo_xlib_screen_info_t *info = NULL, **prev;
display = _cairo_xlib_display_get (dpy);
if (display == NULL)
return NULL;
CAIRO_MUTEX_LOCK (display->mutex);
if (display->closed) {
CAIRO_MUTEX_UNLOCK (display->mutex);
goto DONE;
return NULL;
}
for (prev = &display->screens; (info = *prev); prev = &(*prev)->next) {
@ -355,7 +389,9 @@ _cairo_xlib_screen_info_get (Display *dpy, Screen *screen)
sizeof (cairo_xlib_visual_info_t*));
if (screen) {
Display *dpy = display->display;
int event_base, error_base;
info->has_render = (XRenderQueryExtension (dpy, &event_base, &error_base) &&
(XRenderFindVisualFormat (dpy, DefaultVisual (dpy, DefaultScreen (dpy))) != 0));
_cairo_xlib_init_screen_font_options (dpy, info);
@ -368,9 +404,6 @@ _cairo_xlib_screen_info_get (Display *dpy, Screen *screen)
}
}
DONE:
_cairo_xlib_display_destroy (display);
return info;
}

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

@ -45,7 +45,9 @@ struct _cairo_xlib_surface {
cairo_surface_t base;
Display *dpy;
cairo_xlib_display_t *display;
cairo_xlib_screen_info_t *screen_info;
cairo_xlib_hook_t close_display_hook;
GC gc;
Drawable drawable;

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

@ -1,3 +1,4 @@
/* -*- Mode: c; c-basic-offset: 4; indent-tabs-mode: t; tab-width: 8; -*- */
/* cairo - a vector graphics library with display and print output
*
* Copyright © 2002 University of Southern California
@ -34,6 +35,8 @@
* Contributor(s):
* Carl D. Worth <cworth@cworth.org>
* Behdad Esfahbod <behdad@behdad.org>
* Chris Wilson <chris@chris-wilson.co.uk>
* Karl Tomlinson <karlt+@karlt.net>, Mozilla Corporation
*/
#include "cairoint.h"
@ -45,6 +48,8 @@
#include <X11/Xutil.h> /* for XDestroyImage */
#define XLIB_COORD_MAX 32767
/* Xlib doesn't define a typedef, so define one ourselves */
typedef int (*cairo_xlib_error_func_t) (Display *display,
XErrorEvent *event);
@ -130,6 +135,9 @@ _cairo_xlib_surface_create_similar_with_format (void *abstract_src,
cairo_xlib_surface_t *surface;
XRenderPictFormat *xrender_format;
if (width > XLIB_COORD_MAX || height > XLIB_COORD_MAX)
return NULL;
/* As a good first approximation, if the display doesn't have even
* the most elementary RENDER operation, then we're better off
* using image surfaces for all temporary operations, so return NULL
@ -200,6 +208,9 @@ _cairo_xlib_surface_create_similar (void *abstract_src,
cairo_xlib_surface_t *surface;
Pixmap pix;
if (width > XLIB_COORD_MAX || height > XLIB_COORD_MAX)
return _cairo_surface_create_in_error (_cairo_error(CAIRO_STATUS_NO_MEMORY));
_cairo_xlib_display_notify (src->screen_info->display);
/* Start by examining the surface's XRenderFormat, or if it
@ -309,11 +320,14 @@ _cairo_xlib_surface_finish (void *abstract_surface)
if (surface->screen_info != NULL)
_cairo_xlib_screen_info_destroy (surface->screen_info);
if (surface->dpy != NULL) {
_cairo_xlib_remove_close_display_hooks (surface->dpy, surface);
surface->dpy = NULL;
if (surface->display != NULL) {
_cairo_xlib_remove_close_display_hook (surface->display,
&surface->close_display_hook);
_cairo_xlib_display_destroy (surface->display);
}
surface->dpy = NULL;
return status;
}
@ -637,9 +651,9 @@ _get_image_surface (cairo_xlib_surface_t *surface,
return status;
pixmap = XCreatePixmap (surface->dpy,
surface->drawable,
x2 - x1, y2 - y1,
surface->depth);
surface->drawable,
x2 - x1, y2 - y1,
surface->depth);
if (pixmap) {
XCopyArea (surface->dpy, surface->drawable, pixmap, surface->gc,
x1, y1, x2 - x1, y2 - y1, 0, 0);
@ -909,11 +923,15 @@ _draw_image_surface (cairo_xlib_surface_t *surface,
image_masks.green_mask == surface->g_mask &&
image_masks.blue_mask == surface->b_mask)
{
int ret;
ximage.bits_per_pixel = image_masks.bpp;
ximage.bytes_per_line = image->stride;
ximage.data = (char *)image->data;
own_data = FALSE;
XInitImage (&ximage);
ret = XInitImage (&ximage);
assert (ret != 0);
} else {
unsigned int stride, rowstride;
int x, y, x0, y0, x_off, y_off;
@ -923,6 +941,8 @@ _draw_image_surface (cairo_xlib_surface_t *surface,
int o_a_width=0, o_r_width=0, o_g_width=0, o_b_width=0;
int o_a_shift=0, o_r_shift=0, o_g_shift=0, o_b_shift=0;
cairo_xlib_visual_info_t *visual_info = NULL;
cairo_bool_t true_color;
int ret;
if (surface->depth > 16) {
ximage.bits_per_pixel = 32;
@ -942,28 +962,27 @@ _draw_image_surface (cairo_xlib_surface_t *surface,
own_data = TRUE;
XInitImage (&ximage);
ret = XInitImage (&ximage);
assert (ret != 0);
_characterize_field (image_masks.alpha_mask, &i_a_width, &i_a_shift);
_characterize_field (image_masks.red_mask , &i_r_width, &i_r_shift);
_characterize_field (image_masks.green_mask, &i_g_width, &i_g_shift);
_characterize_field (image_masks.blue_mask , &i_b_width, &i_b_shift);
if (surface->visual == NULL || surface->visual->class == TrueColor) {
true_color = surface->visual == NULL ||
surface->visual->class == TrueColor;
if (true_color) {
_characterize_field (surface->a_mask, &o_a_width, &o_a_shift);
_characterize_field (surface->r_mask, &o_r_width, &o_r_shift);
_characterize_field (surface->g_mask, &o_g_width, &o_g_shift);
_characterize_field (surface->b_mask, &o_b_width, &o_b_shift);
} else {
status = _cairo_xlib_screen_get_visual_info (surface->screen_info,
surface->visual,
&visual_info);
if (status)
goto BAIL;
}
rowstride = cairo_image_surface_get_stride (&image->base) >> 2;
@ -972,13 +991,15 @@ _draw_image_surface (cairo_xlib_surface_t *surface,
y0 = dst_y + surface->base.device_transform.y0;
for (y = 0, y_off = y0 % ARRAY_LENGTH (dither_pattern);
y < ximage.height;
y++, y_off = (y_off+1) % ARRAY_LENGTH (dither_pattern)) {
y++, y_off = (y_off+1) % ARRAY_LENGTH (dither_pattern))
{
const int8_t *dither_row = dither_pattern[y_off];
for (x = 0, x_off = x0 % ARRAY_LENGTH (dither_pattern[0]);
x < ximage.width;
x++, x_off = (x_off+1) % ARRAY_LENGTH (dither_pattern[0])) {
x++, x_off = (x_off+1) % ARRAY_LENGTH (dither_pattern[0]))
{
int dither_adjustment = dither_row[x_off];
int a, r, g, b;
if (image_masks.bpp <= 8)
@ -987,20 +1008,24 @@ _draw_image_surface (cairo_xlib_surface_t *surface,
in_pixel = ((uint16_t*)row)[x];
else
in_pixel = row[x];
a = _field_to_8 (in_pixel & image_masks.alpha_mask, i_a_width, i_a_shift);
r = _field_to_8 (in_pixel & image_masks.red_mask , i_r_width, i_r_shift);
g = _field_to_8 (in_pixel & image_masks.green_mask, i_g_width, i_g_shift);
b = _field_to_8 (in_pixel & image_masks.blue_mask , i_b_width, i_b_shift);
if (surface->visual == NULL || surface->visual->class == TrueColor) {
out_pixel = (_field_from_8 (a, o_a_width, o_a_shift) |
_field_from_8_dither (r, o_r_width, o_r_shift, dither_adjustment) |
_field_from_8_dither (g, o_g_width, o_g_shift, dither_adjustment) |
_field_from_8_dither (b, o_b_width, o_b_shift, dither_adjustment));
if (true_color) {
out_pixel = _field_from_8 (a, o_a_width, o_a_shift) |
_field_from_8_dither (r, o_r_width, o_r_shift, dither_adjustment) |
_field_from_8_dither (g, o_g_width, o_g_shift, dither_adjustment) |
_field_from_8_dither (b, o_b_width, o_b_shift, dither_adjustment);
} else {
out_pixel = _pseudocolor_from_rgb888_dither (visual_info, r, g, b, dither_adjustment);
}
XPutPixel (&ximage, x, y, out_pixel);
}
row += rowstride;
}
}
@ -1131,6 +1156,9 @@ _cairo_xlib_surface_clone_similar (void *abstract_surface,
if (! CAIRO_FORMAT_VALID (image_src->format))
return CAIRO_INT_STATUS_UNSUPPORTED;
if (image_src->width > XLIB_COORD_MAX || image_src->height > XLIB_COORD_MAX)
return CAIRO_STATUS_NO_MEMORY;
clone = (cairo_xlib_surface_t *)
_cairo_xlib_surface_create_similar_with_format (surface, image_src->format,
image_src->width, image_src->height);
@ -1172,31 +1200,36 @@ _cairo_xlib_surface_create_solid_pattern_surface (void *abstrac
cairo_xlib_surface_t *surface = NULL;
cairo_status_t status = CAIRO_STATUS_SUCCESS;
Pixmap pixmap;
int width = ARRAY_LENGTH (dither_pattern[0]);
int height = ARRAY_LENGTH (dither_pattern);
Pixmap pixmap = None;
if (CAIRO_SURFACE_RENDER_HAS_COMPOSITE (other))
return NULL;
if (width > XLIB_COORD_MAX || height > XLIB_COORD_MAX)
return NULL;
image = (cairo_image_surface_t *)
_cairo_image_surface_create_with_content (solid_pattern->content,
ARRAY_LENGTH (dither_pattern[0]),
ARRAY_LENGTH (dither_pattern));
width, height);
status = image->base.status;
if (status)
goto BAIL;
pixmap = XCreatePixmap (other->dpy,
other->drawable,
image->width, image->height,
width, height,
other->depth);
surface = (cairo_xlib_surface_t *)
_cairo_xlib_surface_create_internal (other->dpy,
pixmap,
other->screen, other->visual,
NULL,
image->width, image->height,
0);
other->xrender_format,
width, height,
other->depth);
status = surface->base.status;
if (status)
goto BAIL;
@ -1208,7 +1241,7 @@ _cairo_xlib_surface_create_solid_pattern_surface (void *abstrac
status = _draw_image_surface (surface, image,
0, 0,
image->width, image->height,
width, height,
0, 0);
if (status)
goto BAIL;
@ -1313,25 +1346,23 @@ _cairo_xlib_surface_set_filter (cairo_xlib_surface_t *surface,
return CAIRO_STATUS_SUCCESS;
}
static cairo_status_t
static void
_cairo_xlib_surface_set_repeat (cairo_xlib_surface_t *surface, int repeat)
{
XRenderPictureAttributes pa;
unsigned long mask;
if (!surface->src_picture)
return CAIRO_STATUS_SUCCESS;
return;
if (surface->repeat == repeat)
return CAIRO_STATUS_SUCCESS;
return;
mask = CPRepeat;
pa.repeat = repeat;
XRenderChangePicture (surface->dpy, surface->src_picture, mask, &pa);
surface->repeat = repeat;
return CAIRO_STATUS_SUCCESS;
}
static cairo_int_status_t
@ -1348,18 +1379,16 @@ _cairo_xlib_surface_set_attributes (cairo_xlib_surface_t *surface,
switch (attributes->extend) {
case CAIRO_EXTEND_NONE:
status = _cairo_xlib_surface_set_repeat (surface, 0);
_cairo_xlib_surface_set_repeat (surface, 0);
break;
case CAIRO_EXTEND_REPEAT:
status = _cairo_xlib_surface_set_repeat (surface, 1);
_cairo_xlib_surface_set_repeat (surface, 1);
break;
case CAIRO_EXTEND_REFLECT:
case CAIRO_EXTEND_PAD:
default:
status = CAIRO_INT_STATUS_UNSUPPORTED;
return CAIRO_INT_STATUS_UNSUPPORTED;
}
if (status)
return status;
status = _cairo_xlib_surface_set_filter (surface, attributes->filter);
if (status)
@ -1887,12 +1916,17 @@ _create_a8_picture (cairo_xlib_surface_t *surface,
XRenderPictureAttributes pa;
unsigned long mask = 0;
Pixmap pixmap = XCreatePixmap (surface->dpy, surface->drawable,
width <= 0 ? 1 : width,
height <= 0 ? 1 : height,
8);
Pixmap pixmap;
Picture picture;
if (width > XLIB_COORD_MAX || height > XLIB_COORD_MAX)
return None;
pixmap = XCreatePixmap (surface->dpy, surface->drawable,
width <= 0 ? 1 : width,
height <= 0 ? 1 : height,
8);
if (repeat) {
pa.repeat = TRUE;
mask = CPRepeat;
@ -1935,7 +1969,7 @@ _create_trapezoid_mask (cairo_xlib_surface_t *dst,
* the servers that have XRenderAddTraps().
*/
mask_picture = _create_a8_picture (dst, &transparent, width, height, FALSE);
if (num_traps == 0)
if (mask_picture == None || num_traps == 0)
return mask_picture;
offset_traps = _cairo_malloc_ab (num_traps, sizeof (XTrapezoid));
@ -2171,8 +2205,11 @@ _cairo_xlib_surface_set_clip_region (void *abstract_surface,
}
status = _cairo_region_get_boxes (&bounded, &n_boxes, &boxes);
if (status)
return status;
if (status) {
_cairo_region_fini (&bound);
_cairo_region_fini (&bounded);
return status;
}
if (n_boxes > ARRAY_LENGTH (surface->embedded_clip_rects)) {
rects = _cairo_malloc_ab (n_boxes, sizeof (XRectangle));
@ -2344,11 +2381,16 @@ _cairo_surface_is_xlib (cairo_surface_t *surface)
return surface->backend == &cairo_xlib_surface_backend;
}
/* callback from CloseDisplay */
static void
_cairo_xlib_surface_detach_display (Display *dpy, void *data)
_cairo_xlib_surface_detach_display (cairo_xlib_display_t *display, void *data)
{
cairo_xlib_surface_t *surface = data;
cairo_xlib_surface_t *surface = cairo_container_of (data,
cairo_xlib_surface_t,
close_display_hook);
Display *dpy;
dpy = surface->dpy;
surface->dpy = NULL;
if (surface->dst_picture != None) {
@ -2384,35 +2426,22 @@ _cairo_xlib_surface_create_internal (Display *dpy,
int depth)
{
cairo_xlib_surface_t *surface;
cairo_xlib_display_t *display;
cairo_xlib_screen_info_t *screen_info;
CAIRO_MUTEX_INITIALIZE ();
screen_info = _cairo_xlib_screen_info_get (dpy, screen);
if (screen_info == NULL)
return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY));
surface = malloc (sizeof (cairo_xlib_surface_t));
if (surface == NULL) {
_cairo_xlib_screen_info_destroy (screen_info);
return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY));
}
if (! _cairo_xlib_add_close_display_hook (dpy,
_cairo_xlib_surface_detach_display, surface, surface)) {
free (surface);
_cairo_xlib_screen_info_destroy (screen_info);
return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY));
}
if (xrender_format) {
depth = xrender_format->depth;
/* XXX find matching visual for core/dithering fallbacks? */
} else if (visual) {
int j, k;
/* This is ugly, but we have to walk over all visuals
* for the display to find the depth.
* for the display to find the correct depth.
*/
depth = 0;
for (j = 0; j < screen->ndepths; j++) {
Depth *d = &screen->depths[j];
for (k = 0; k < d->nvisuals; k++) {
@ -2426,6 +2455,30 @@ _cairo_xlib_surface_create_internal (Display *dpy,
;
}
if (depth == 0)
return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_INVALID_VISUAL));
display = _cairo_xlib_display_get (dpy);
if (display == NULL)
return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY));
screen_info = _cairo_xlib_screen_info_get (display, screen);
if (screen_info == NULL) {
_cairo_xlib_display_destroy (display);
return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY));
}
surface = malloc (sizeof (cairo_xlib_surface_t));
if (surface == NULL) {
_cairo_xlib_screen_info_destroy (screen_info);
_cairo_xlib_display_destroy (display);
return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY));
}
/* initialize and hook into the CloseDisplay callback */
surface->close_display_hook.func = _cairo_xlib_surface_detach_display;
_cairo_xlib_add_close_display_hook (display, &surface->close_display_hook);
if (! XRenderQueryVersion (dpy, &surface->render_major, &surface->render_minor)) {
surface->render_major = -1;
surface->render_minor = -1;
@ -2446,6 +2499,7 @@ _cairo_xlib_surface_create_internal (Display *dpy,
_xrender_format_to_content (xrender_format));
surface->dpy = dpy;
surface->display = display;
surface->screen_info = screen_info;
surface->gc = NULL;
@ -2945,16 +2999,24 @@ typedef struct _cairo_xlib_font_glyphset_info {
} cairo_xlib_font_glyphset_info_t;
typedef struct _cairo_xlib_surface_font_private {
cairo_scaled_font_t *scaled_font;
cairo_xlib_hook_t close_display_hook;
cairo_xlib_display_t *display;
cairo_xlib_font_glyphset_info_t glyphset_info[NUM_GLYPHSETS];
} cairo_xlib_surface_font_private_t;
/* callback from CloseDisplay */
static void
_cairo_xlib_surface_remove_scaled_font (Display *dpy,
void *data)
_cairo_xlib_surface_remove_scaled_font (cairo_xlib_display_t *display,
void *data)
{
cairo_scaled_font_t *scaled_font = data;
cairo_xlib_surface_font_private_t *font_private;
cairo_scaled_font_t *scaled_font;
font_private = cairo_container_of (data,
cairo_xlib_surface_font_private_t,
close_display_hook);
scaled_font = font_private->scaled_font;
CAIRO_MUTEX_LOCK (scaled_font->mutex);
font_private = scaled_font->surface_private;
@ -2964,14 +3026,19 @@ _cairo_xlib_surface_remove_scaled_font (Display *dpy,
CAIRO_MUTEX_UNLOCK (scaled_font->mutex);
if (font_private != NULL) {
Display *dpy;
int i;
dpy = display->display;
for (i = 0; i < NUM_GLYPHSETS; i++) {
cairo_xlib_font_glyphset_info_t *glyphset_info;
glyphset_info = &font_private->glyphset_info[i];
if (glyphset_info->glyphset)
XRenderFreeGlyphSet (dpy, glyphset_info->glyphset);
if (glyphset_info->pending_free_glyphs != NULL)
free (glyphset_info->pending_free_glyphs);
}
_cairo_xlib_display_destroy (font_private->display);
@ -2990,16 +3057,20 @@ _cairo_xlib_surface_font_init (Display *dpy,
if (font_private == NULL)
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
if (! _cairo_xlib_add_close_display_hook (dpy,
_cairo_xlib_surface_remove_scaled_font,
scaled_font, scaled_font))
{
font_private->scaled_font = scaled_font;
font_private->display = _cairo_xlib_display_get (dpy);
if (font_private->display == NULL) {
free (font_private);
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
}
/* initialize and hook into the CloseDisplay callback */
font_private->close_display_hook.func =
_cairo_xlib_surface_remove_scaled_font;
_cairo_xlib_add_close_display_hook (font_private->display,
&font_private->close_display_hook);
font_private->display = _cairo_xlib_display_get (dpy);
for (i = 0; i < NUM_GLYPHSETS; i++) {
cairo_xlib_font_glyphset_info_t *glyphset_info = &font_private->glyphset_info[i];
switch (i) {
@ -3030,7 +3101,8 @@ _cairo_xlib_surface_scaled_font_fini (cairo_scaled_font_t *scaled_font)
int i;
display = font_private->display;
_cairo_xlib_remove_close_display_hooks (display->display, scaled_font);
_cairo_xlib_remove_close_display_hook (display,
&font_private->close_display_hook);
for (i = 0; i < NUM_GLYPHSETS; i++) {
cairo_xlib_font_glyphset_info_t *glyphset_info;

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

@ -33,6 +33,11 @@
#ifndef CAIRO_XLIB_XRENDER_PRIVATE_H
#define CAIRO_XLIB_XRENDER_PRIVATE_H
#include "cairo-features.h"
#include "cairo-compiler-private.h"
#include <X11/Xlib.h>
#if CAIRO_HAS_XLIB_XRENDER_SURFACE
#include "cairo-xlib-xrender.h"
@ -52,7 +57,7 @@
* take a pointer as first argument */
__attribute__((__unused__)) static void _void_consume (void *p, ...) { }
__attribute__((__unused__)) static void * _voidp_consume (void *p, ...) { return NULL; }
__attribute__((__unused__)) static void * _voidp_consume (void *p, ...) { return (void *)0; }
__attribute__((__unused__)) static int _int_consume (void *p, ...) { return 0; }
__attribute__((__unused__)) static void _void_consume_free (Display *p, XID n) { }

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

@ -119,49 +119,6 @@ _cairo_set_error (cairo_t *cr, cairo_status_t status)
status = _cairo_error (status);
}
/**
* cairo_version:
*
* Returns the version of the cairo library encoded in a single
* integer as per %CAIRO_VERSION_ENCODE. The encoding ensures that
* later versions compare greater than earlier versions.
*
* A run-time comparison to check that cairo's version is greater than
* or equal to version X.Y.Z could be performed as follows:
*
* <informalexample><programlisting>
* if (cairo_version() >= CAIRO_VERSION_ENCODE(X,Y,Z)) {...}
* </programlisting></informalexample>
*
* See also cairo_version_string() as well as the compile-time
* equivalents %CAIRO_VERSION and %CAIRO_VERSION_STRING.
*
* Return value: the encoded version.
**/
int
cairo_version (void)
{
return CAIRO_VERSION;
}
/**
* cairo_version_string:
*
* Returns the version of the cairo library as a human-readable string
* of the form "X.Y.Z".
*
* See also cairo_version() as well as the compile-time equivalents
* %CAIRO_VERSION_STRING and %CAIRO_VERSION.
*
* Return value: a string containing the version.
**/
const char*
cairo_version_string (void)
{
return CAIRO_VERSION_STRING;
}
slim_hidden_def (cairo_version_string);
/**
* cairo_create:
* @target: target surface for the context
@ -587,7 +544,17 @@ cairo_pop_group (cairo_t *cr)
}
_cairo_gstate_get_matrix (cr->gstate, &group_matrix);
cairo_pattern_set_matrix (group_pattern, &group_matrix);
/* Transform by group_matrix centered around device_transform so that when
* we call _cairo_gstate_copy_transformed_pattern the result is a pattern
* with a matrix equivalent to the device_transform of group_surface. */
if (_cairo_surface_has_device_transform (group_surface)) {
cairo_pattern_set_matrix (group_pattern, &group_surface->device_transform);
_cairo_pattern_transform (group_pattern, &group_matrix);
_cairo_pattern_transform (group_pattern, &group_surface->device_transform_inverse);
} else {
cairo_pattern_set_matrix (group_pattern, &group_matrix);
}
done:
cairo_surface_destroy (group_surface);
@ -2609,7 +2576,7 @@ cairo_copy_clip_rectangle_list (cairo_t *cr)
* 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",
* remember), but the standard CSS2 generic family names, ("serif",
* "sans-serif", "cursive", "fantasy", "monospace"), are likely to
* work as expected.
*
@ -2631,8 +2598,12 @@ cairo_copy_clip_rectangle_list (cairo_t *cr)
*
* 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
* family is platform-specific, but is essentially "sans-serif".
* Default slant is %CAIRO_FONT_SLANT_NORMAL, and default weight is
* %CAIRO_FONT_WEIGHT_NORMAL.
*
* This function is equivalent to a call to cairo_toy_font_face_create()
* followed by cairo_set_font_face().
**/
void
cairo_select_font_face (cairo_t *cr,
@ -2891,6 +2862,11 @@ cairo_set_scaled_font (cairo_t *cr,
if (cr->status)
return;
if (scaled_font == NULL) {
status = CAIRO_STATUS_NULL_POINTER;
goto BAIL;
}
status = scaled_font->status;
if (status)
goto BAIL;
@ -2952,7 +2928,7 @@ cairo_get_scaled_font (cairo_t *cr)
/**
* cairo_text_extents:
* @cr: a #cairo_t
* @utf8: a string of text encoded in UTF-8, or %NULL
* @utf8: a NUL-terminated string of text encoded in UTF-8, or %NULL
* @extents: a #cairo_text_extents_t object into which the results
* will be stored
*
@ -2994,16 +2970,18 @@ cairo_text_extents (cairo_t *cr,
cairo_get_current_point (cr, &x, &y);
status = _cairo_gstate_text_to_glyphs (cr->gstate, utf8,
status = _cairo_gstate_text_to_glyphs (cr->gstate,
x, y,
&glyphs, &num_glyphs);
utf8, strlen (utf8),
&glyphs, &num_glyphs,
NULL, NULL,
NULL);
if (status == CAIRO_STATUS_SUCCESS)
status = _cairo_gstate_glyph_extents (cr->gstate,
glyphs, num_glyphs,
extents);
if (glyphs)
free (glyphs);
cairo_glyph_free (glyphs);
if (status)
_cairo_set_error (cr, status);
@ -3067,7 +3045,7 @@ cairo_glyph_extents (cairo_t *cr,
/**
* cairo_show_text:
* @cr: a cairo context
* @utf8: a string of text encoded in UTF-8, or %NULL
* @utf8: a NUL-terminated string of text encoded in UTF-8, or %NULL
*
* A drawing operator that generates the shape from a string of UTF-8
* characters, rendered according to the current font_face, font_size
@ -3097,7 +3075,9 @@ cairo_show_text (cairo_t *cr, const char *utf8)
cairo_text_extents_t extents;
cairo_status_t status;
cairo_glyph_t *glyphs = NULL, *last_glyph;
int num_glyphs;
cairo_text_cluster_t *clusters = NULL;
int utf8_len, num_glyphs, num_clusters;
cairo_bool_t backward;
double x, y;
if (cr->status)
@ -3108,9 +3088,14 @@ cairo_show_text (cairo_t *cr, const char *utf8)
cairo_get_current_point (cr, &x, &y);
status = _cairo_gstate_text_to_glyphs (cr->gstate, utf8,
utf8_len = strlen (utf8);
status = _cairo_gstate_text_to_glyphs (cr->gstate,
x, y,
&glyphs, &num_glyphs);
utf8, utf8_len,
&glyphs, &num_glyphs,
cairo_has_show_text_glyphs (cr) ? &clusters : NULL, &num_clusters,
&backward);
if (status)
goto BAIL;
@ -3118,10 +3103,10 @@ cairo_show_text (cairo_t *cr, const char *utf8)
return;
status = _cairo_gstate_show_text_glyphs (cr->gstate,
NULL, 0,
utf8, utf8_len,
glyphs, num_glyphs,
NULL, 0,
FALSE);
clusters, num_clusters,
backward);
if (status)
goto BAIL;
@ -3137,8 +3122,8 @@ cairo_show_text (cairo_t *cr, const char *utf8)
cairo_move_to (cr, x, y);
BAIL:
if (glyphs)
free (glyphs);
cairo_glyph_free (glyphs);
cairo_text_cluster_free (clusters);
if (status)
_cairo_set_error (cr, status);
@ -3151,8 +3136,8 @@ cairo_show_text (cairo_t *cr, const char *utf8)
* @num_glyphs: number of glyphs to show
*
* A drawing operator that generates the shape from an array of glyphs,
* rendered according to the current font_face, font_size
* (font_matrix), and font_options.
* rendered according to the current font face, font size
* (font matrix), and font options.
**/
void
cairo_show_glyphs (cairo_t *cr, const cairo_glyph_t *glyphs, int num_glyphs)
@ -3184,12 +3169,69 @@ cairo_show_glyphs (cairo_t *cr, const cairo_glyph_t *glyphs, int num_glyphs)
_cairo_set_error (cr, status);
}
/**
* cairo_has_show_text_glyphs:
* @cr: a cairo context
*
* Returns whether the target surface of a cairo context supports
* sophisticated cairo_show_text_glyphs() operations. That is,
* whether it actually uses the provided text and cluster data
* to a cairo_show_text_glyphs() call.
*
* Note: Even if this function returns %FALSE, a
* cairo_show_text_glyphs() operation will still succeed. It just will
* act like a cairo_show_glyphs() operation. Users can use this
* function to avoid computing UTF-8 text and cluster mapping if the
* target surface does not use it.
*
* This is a convenience function that simply calls
* cairo_surface_has_show_text_glyphs() on @cr's target.
*
* Return value: %TRUE if the target surface of @cr supports
* cairo_show_text_glyphs(), %FALSE otherwise
*
* Since: 1.8
**/
cairo_bool_t
cairo_has_show_text_glyphs (cairo_t *cr)
{
return _cairo_gstate_has_show_text_glyphs (cr->gstate);
}
slim_hidden_def (cairo_has_show_text_glyphs);
/**
* cairo_show_text_glyphs:
* @cr: a cairo context
* @utf8: a string of text encoded in UTF-8
* @utf8_len: length of @utf8 in bytes, or -1 if it is NUL-terminated
* @glyphs: array of glyphs to show
* @num_glyphs: number of glyphs to show
* @clusters: array of cluster mapping information
* @num_clusters: number of clusters in the mapping
* @backward: whether the text to glyphs mapping goes backward
*
* This operation has rendering effects similar to cairo_show_glyphs()
* but, if the target surface supports it, uses the provided text and
* cluster mapping to embed the text for the glyphs shown in the output.
* The cairo_has_show_text_glyphs() function can be used to query that.
* If the target does not support it, this function acts like
* cairo_show_glyphs().
*
* The mapping between @utf8 and @glyphs is provided by an array of
* <firstterm>clusters</firstterm>. Each cluster covers a number of
* text bytes and glyphs, and neighboring clusters cover neighboring
* areas of @utf8 and @glyphs. The clusters should collectively cover @utf8
* and @glyphs in entirety.
*
* The first cluster always covers bytes from the beginning of @utf8.
* If @backward is %FALSE, the first cluster also covers the beginning
* of @glyphs, otherwise it covers the end of the @glyphs array and
* following clusters move backward.
*
* See #cairo_text_cluster_t for constraints on valid clusters.
*
* Since: 1.8
**/
void
cairo_show_text_glyphs (cairo_t *cr,
const char *utf8,
@ -3207,6 +3249,18 @@ cairo_show_text_glyphs (cairo_t *cr,
/* A slew of sanity checks */
/* Special case for NULL and -1 */
if (utf8 == NULL && utf8_len == -1)
utf8_len = 0;
/* No NULLs for non-zeros */
if ((num_glyphs && glyphs == NULL) ||
(utf8_len && utf8 == NULL) ||
(num_clusters && clusters == NULL)) {
_cairo_set_error (cr, CAIRO_STATUS_NULL_POINTER);
return;
}
/* A -1 for utf8_len means NUL-terminated */
if (utf8_len == -1)
utf8_len = strlen (utf8);
@ -3217,58 +3271,24 @@ cairo_show_text_glyphs (cairo_t *cr,
return;
}
/* And no NULLs for non-zeros */
if ((num_glyphs && glyphs == NULL) ||
(utf8_len && utf8 == NULL) ||
(num_clusters && clusters == NULL)) {
_cairo_set_error (cr, CAIRO_STATUS_NULL_POINTER);
return;
}
/* Make sure clusters cover the entire glyphs and utf8 arrays,
* and that cluster boundaries are UTF-8 boundaries. */
{
unsigned int n_bytes = 0;
unsigned int n_glyphs = 0;
int i;
status = _cairo_validate_text_clusters (utf8, utf8_len,
glyphs, num_glyphs,
clusters, num_clusters,
backward);
if (status == CAIRO_STATUS_INVALID_CLUSTERS) {
/* Either got invalid UTF-8 text, or cluster mapping is bad.
* Differentiate those. */
for (i = 0; i < num_clusters; i++) {
int cluster_bytes = clusters[i].num_bytes;
int cluster_glyphs = clusters[i].num_glyphs;
cairo_status_t status2;
if (cluster_bytes < 0 || cluster_glyphs < 0)
goto BAD;
status2 = _cairo_utf8_to_ucs4 (utf8, utf8_len, NULL, NULL);
if (status2)
status = status2;
/* A cluster should cover at least one character or glyph.
* I can't see any use for a 0,0 cluster.
* I can't see an immediate use for a zero-text cluster
* right now either, but they don't harm.
* Zero-glyph clusters on the other hand are useful for
* things like U+200C ZERO WIDTH NON-JOINER */
if (cluster_bytes == 0 && cluster_glyphs == 0)
goto BAD;
/* Since n_bytes and n_glyphs are unsigned, but the rest of
* values involved are signed, we can detect overflow easily */
if (n_bytes+cluster_bytes > (unsigned int)utf8_len || n_glyphs+cluster_glyphs > (unsigned int)num_glyphs)
goto BAD;
/* Make sure we've got valid UTF-8 for the cluster */
status = _cairo_utf8_to_ucs4 (utf8+n_bytes, cluster_bytes, NULL, NULL);
if (status) {
_cairo_set_error (cr, status);
return;
}
n_bytes += cluster_bytes ;
n_glyphs += cluster_glyphs;
}
if (n_bytes != (unsigned int)utf8_len || n_glyphs != (unsigned int)num_glyphs) {
BAD:
_cairo_set_error (cr, CAIRO_STATUS_INVALID_CLUSTERS);
return;
}
_cairo_set_error (cr, status);
return;
}
if (num_glyphs == 0 && utf8_len == 0)
@ -3286,7 +3306,7 @@ cairo_show_text_glyphs (cairo_t *cr,
/**
* cairo_text_path:
* @cr: a cairo context
* @utf8: a string of text encoded in UTF-8, or %NULL
* @utf8: a NUL-terminated string of text encoded in UTF-8, or %NULL
*
* Adds closed paths for text to the current path. The generated
* path if filled, achieves an effect similar to that of
@ -3324,9 +3344,12 @@ cairo_text_path (cairo_t *cr, const char *utf8)
cairo_get_current_point (cr, &x, &y);
status = _cairo_gstate_text_to_glyphs (cr->gstate, utf8,
status = _cairo_gstate_text_to_glyphs (cr->gstate,
x, y,
&glyphs, &num_glyphs);
utf8, strlen (utf8),
&glyphs, &num_glyphs,
NULL, NULL,
NULL);
if (status)
goto BAIL;
@ -3354,8 +3377,7 @@ cairo_text_path (cairo_t *cr, const char *utf8)
cairo_move_to (cr, x, y);
BAIL:
if (glyphs)
free (glyphs);
cairo_glyph_free (glyphs);
if (status)
_cairo_set_error (cr, status);
@ -3492,11 +3514,11 @@ cairo_has_current_point (cairo_t *cr)
* cairo_move_to(), cairo_line_to(), cairo_curve_to(),
* cairo_rel_move_to(), cairo_rel_line_to(), cairo_rel_curve_to(),
* cairo_arc(), cairo_arc_negative(), cairo_rectangle(),
* cairo_text_path(), cairo_glyph_path(), cairo_stroke_to_path()
* cairo_text_path(), cairo_glyph_path(), cairo_stroke_to_path().
*
* Some functions use and alter the current point but do not otherwise
* change current path:
* cairo_show_text(), cairo_show_glyphs().
* Some functions use and alter the current point but do not
* otherwise change current path:
* cairo_show_text().
*
* Some functions unset the current path and as a result, current point:
* cairo_fill(), cairo_stroke().
@ -3658,6 +3680,7 @@ cairo_get_target (cairo_t *cr)
return _cairo_gstate_get_original_target (cr->gstate);
}
slim_hidden_def (cairo_get_target);
/**
* cairo_get_group_target:

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

@ -38,21 +38,46 @@
#ifndef CAIRO_H
#define CAIRO_H
#include "cairo-version.h"
#include "cairo-features.h"
#include "cairo-deprecated.h"
#ifdef __cplusplus
# define CAIRO_BEGIN_DECLS extern "C" {
# define CAIRO_END_DECLS }
#else
# define CAIRO_BEGIN_DECLS
# define CAIRO_END_DECLS
#endif
#ifndef cairo_public
# define cairo_public
#endif
CAIRO_BEGIN_DECLS
#define CAIRO_VERSION_ENCODE(major, minor, micro) ( \
((major) * 10000) \
+ ((minor) * 100) \
#define CAIRO_VERSION_ENCODE(major, minor, micro) ( \
((major) * 10000) \
+ ((minor) * 100) \
+ ((micro) * 1))
#define CAIRO_VERSION CAIRO_VERSION_ENCODE( \
CAIRO_VERSION_MAJOR, \
CAIRO_VERSION_MINOR, \
#define CAIRO_VERSION CAIRO_VERSION_ENCODE( \
CAIRO_VERSION_MAJOR, \
CAIRO_VERSION_MINOR, \
CAIRO_VERSION_MICRO)
#define CAIRO_VERSION_STRINGIZE_(major, minor, micro) \
#major"."#minor"."#micro
#define CAIRO_VERSION_STRINGIZE(major, minor, micro) \
CAIRO_VERSION_STRINGIZE_(major, minor, micro)
#define CAIRO_VERSION_STRING CAIRO_VERSION_STRINGIZE( \
CAIRO_VERSION_MAJOR, \
CAIRO_VERSION_MINOR, \
CAIRO_VERSION_MICRO)
cairo_public int
cairo_version (void);
@ -208,6 +233,8 @@ typedef struct _cairo_user_data_key {
* @CAIRO_STATUS_USER_FONT_ERROR: error occurred in a user-font callback function (Since 1.8)
* @CAIRO_STATUS_NEGATIVE_COUNT: negative number used where it is not allowed (Since 1.8)
* @CAIRO_STATUS_INVALID_CLUSTERS: input clusters do not represent the accompanying text and glyph array (Since 1.8)
* @CAIRO_STATUS_INVALID_SLANT: invalid value for an input #cairo_font_slant_t (Since 1.8)
* @CAIRO_STATUS_INVALID_WEIGHT: invalid value for an input #cairo_font_weight_t (Since 1.8)
*
* #cairo_status_t is used to indicate errors that can occur when
* using Cairo. In some cases it is returned directly by functions.
@ -247,7 +274,9 @@ typedef enum _cairo_status {
CAIRO_STATUS_USER_FONT_IMMUTABLE,
CAIRO_STATUS_USER_FONT_ERROR,
CAIRO_STATUS_NEGATIVE_COUNT,
CAIRO_STATUS_INVALID_CLUSTERS
CAIRO_STATUS_INVALID_CLUSTERS,
CAIRO_STATUS_INVALID_SLANT,
CAIRO_STATUS_INVALID_WEIGHT
/* after adding a new error: update CAIRO_STATUS_LAST_STATUS in cairoint.h */
} cairo_status_t;
@ -826,11 +855,43 @@ typedef struct {
double y;
} cairo_glyph_t;
cairo_public cairo_glyph_t *
cairo_glyph_allocate (int num_glyphs);
cairo_public void
cairo_glyph_free (cairo_glyph_t *glyphs);
/**
* cairo_text_cluster_t:
* @num_bytes: the number of bytes of UTF-8 text covered by cluster
* @num_glyphs: the number of glyphs covered by cluster
*
* The #cairo_text_cluster_t structure holds information about a single
* <firstterm>text cluster</firstterm>. A text cluster is a minimal
* mapping of some glyphs corresponding to some UTF-8 text.
*
* For a cluster to be valid, both @num_bytes and @num_glyphs should
* be non-negative, and at least one should be non-zero.
* Note that clusters with zero glyphs are not as well supported as
* normal clusters. For example, PDF rendering applications typically
* ignore those clusters when PDF text is being selected.
*
* See cairo_show_text_glyphs() for how clusters are used in advanced
* text operations.
*
* Since: 1.8
**/
typedef struct {
int num_bytes;
int num_glyphs;
} cairo_text_cluster_t;
cairo_public cairo_text_cluster_t *
cairo_text_cluster_allocate (int num_clusters);
cairo_public void
cairo_text_cluster_free (cairo_text_cluster_t *clusters);
/**
* cairo_text_extents_t:
* @x_bearing: the horizontal distance from the origin to the
@ -967,6 +1028,28 @@ typedef enum _cairo_subpixel_order {
CAIRO_SUBPIXEL_ORDER_VBGR
} cairo_subpixel_order_t;
/**
* cairo_lcd_filter_t:
* @CAIRO_LCD_FILTER_DEFAULT: Use the default LCD filter for
* font backend and target device
* @CAIRO_LCD_FILTER_NONE: Do not perform LCD filtering
* @CAIRO_LCD_FILTER_INTRA_PIXEL: Intra-pixel filter
* @CAIRO_LCD_FILTER_FIR3: FIR filter with a 3x3 kernel
* @CAIRO_LCD_FILTER_FIR5: FIR filter with a 5x5 kernel
*
* The LCD filter specifies the low-pass filter applied to LCD-optimized
* bitmaps generated with an antialiasing mode of %CAIRO_ANTIALIAS_SUBPIXEL.
*
* Since: 1.8
**/
typedef enum _cairo_lcd_filter {
CAIRO_LCD_FILTER_DEFAULT,
CAIRO_LCD_FILTER_NONE,
CAIRO_LCD_FILTER_INTRA_PIXEL,
CAIRO_LCD_FILTER_FIR3,
CAIRO_LCD_FILTER_FIR5
} cairo_lcd_filter_t;
/**
* cairo_hint_style_t:
* @CAIRO_HINT_STYLE_DEFAULT: Use the default hint style for
@ -1072,6 +1155,12 @@ cairo_font_options_set_subpixel_order (cairo_font_options_t *options,
cairo_public cairo_subpixel_order_t
cairo_font_options_get_subpixel_order (const cairo_font_options_t *options);
cairo_public void
cairo_font_options_set_lcd_filter (cairo_font_options_t *options,
cairo_lcd_filter_t lcd_filter);
cairo_public cairo_lcd_filter_t
cairo_font_options_get_lcd_filter (const cairo_font_options_t *options);
cairo_public void
cairo_font_options_set_hint_style (cairo_font_options_t *options,
cairo_hint_style_t hint_style);
@ -1286,6 +1375,18 @@ cairo_scaled_font_glyph_extents (cairo_scaled_font_t *scaled_font,
int num_glyphs,
cairo_text_extents_t *extents);
cairo_public cairo_status_t
cairo_scaled_font_text_to_glyphs (cairo_scaled_font_t *scaled_font,
double x,
double y,
const char *utf8,
int utf8_len,
cairo_glyph_t **glyphs,
int *num_glyphs,
cairo_text_cluster_t **clusters,
int *num_clusters,
cairo_bool_t *backward);
cairo_public cairo_font_face_t *
cairo_scaled_font_get_font_face (cairo_scaled_font_t *scaled_font);
@ -1305,6 +1406,24 @@ cairo_public void
cairo_scaled_font_get_font_options (cairo_scaled_font_t *scaled_font,
cairo_font_options_t *options);
/* Toy fonts */
cairo_public cairo_font_face_t *
cairo_toy_font_face_create (const char *family,
cairo_font_slant_t slant,
cairo_font_weight_t weight);
cairo_public const char *
cairo_toy_font_face_get_family (cairo_font_face_t *font_face);
cairo_public cairo_font_slant_t
cairo_toy_font_face_get_slant (cairo_font_face_t *font_face);
cairo_public cairo_font_weight_t
cairo_toy_font_face_get_weight (cairo_font_face_t *font_face);
/* User fonts */
cairo_public cairo_font_face_t *
@ -1315,11 +1434,18 @@ cairo_user_font_face_create (void);
/**
* cairo_user_scaled_font_init_func_t:
* @scaled_font: the scaled-font being created
* @cr: a cairo context, in font space
* @extents: font extents to fill in, in font space
*
* #cairo_user_scaled_font_init_func_t is the type of function which is
* called when a scaled-font needs to be created for a user font-face.
*
* The cairo context @cr is not used by the caller, but is prepared in font
* space, similar to what the cairo contexts passed to the render_glyph
* method will look like. The callback can use this context for extents
* computation for example. After the callback is called, @cr is checked
* for any error status.
*
* The @extents argument is where the user font sets the font extents for
* @scaled_font. It is in font space, which means that for most cases its
* ascent and descent members should add to 1.0. @extents is preset to
@ -1336,11 +1462,10 @@ cairo_user_font_face_create (void);
* Returns: %CAIRO_STATUS_SUCCESS upon success, or
* %CAIRO_STATUS_USER_FONT_ERROR or any other error status on error.
*
* Returns: the status code of the operation
*
* Since: 1.8
**/
typedef cairo_status_t (*cairo_user_scaled_font_init_func_t) (cairo_scaled_font_t *scaled_font,
cairo_t *cr,
cairo_font_extents_t *extents);
/**
@ -1394,15 +1519,19 @@ typedef cairo_status_t (*cairo_user_scaled_font_render_glyph_func_t) (cairo_scal
/**
* cairo_user_scaled_font_text_to_glyphs_func_t:
* @scaled_font: the scaled-font being created
* @utf8: input string of text, encoded in UTF-8
* @glyphs: output array of glyphs, in font space
* @num_glyphs: number of output glyphs
* @utf8: a string of text encoded in UTF-8
* @utf8_len: length of @utf8 in bytes
* @glyphs: pointer to array of glyphs to fill, in font space
* @num_glyphs: pointer to number of glyphs
* @clusters: pointer to array of cluster mapping information to fill, or %NULL
* @num_clusters: pointer to number of clusters
* @backward: pointer to whether the text to glyphs mapping goes backward
*
* #cairo_user_scaled_font_text_to_glyphs_func_t is the type of function which
* is called to convert input text to an array of glyphs. This is used by the
* cairo_show_text() operation.
*
* Using this callback the user font has full control on glyphs and their
* Using this callback the user-font has full control on glyphs and their
* positions. That means, it allows for features like ligatures and kerning,
* as well as complex <firstterm>shaping</firstterm> required for scripts like
* Arabic and Indic.
@ -1413,12 +1542,39 @@ typedef cairo_status_t (*cairo_user_scaled_font_render_glyph_func_t) (cairo_scal
* origin. Cairo will free the glyph array when done with it, no matter what
* the return value of the callback is.
*
* If @glyphs initially points to a non-%NULL value, that array can be used
* as a glyph buffer, and @num_glyphs points to the number of glyph
* entries available there. If the provided glyph array is too short for
* the conversion (or for convenience), a new glyph array may be allocated
* using cairo_glyph_allocate() and placed in @glyphs. Upon return,
* @num_glyphs should contain the number of generated glyphs.
* If the value @glyphs points at has changed after the call, cairo will
* free the allocated glyph array using cairo_glyph_free().
*
* If @clusters is not %NULL, @num_clusters and @backward are also non-%NULL,
* and cluster mapping should be computed.
* The semantics of how cluster array allocation works is similar to the glyph
* array. That is,
* if @clusters initially points to a non-%NULL value, that array may be used
* as a cluster buffer, and @num_clusters points to the number of cluster
* entries available there. If the provided cluster array is too short for
* the conversion (or for convenience), a new cluster array may be allocated
* using cairo_text_cluster_allocate() and placed in @clusters. Upon return,
* @num_clusters should contain the number of generated clusters.
* If the value @clusters points at has changed after the call, cairo will
* free the allocated cluster array using cairo_text_cluster_free().
*
* The callback is optional. If not set, or if @num_glyphs is negative upon
* the callback returning (which by default is), the unicode_to_glyph callback
* the callback returning, the unicode_to_glyph callback
* is tried. See #cairo_user_scaled_font_unicode_to_glyph_func_t.
*
* Note: The signature and details of this callback is expected to change
* before cairo 1.8.0 is released.
* Note: While cairo does not impose any limitation on glyph indices,
* some applications may assume that a glyph index fits in a 16-bit
* unsigned integer. As such, it is advised that user-fonts keep their
* glyphs in the 0 to 65535 range. Furthermore, some applications may
* assume that glyph 0 is a special glyph-not-found glyph. User-fonts
* are advised to use glyph 0 for such purposes and do not use that
* glyph value for other purposes.
*
* Returns: %CAIRO_STATUS_SUCCESS upon success, or
* %CAIRO_STATUS_USER_FONT_ERROR or any other error status on error.
@ -1426,9 +1582,13 @@ typedef cairo_status_t (*cairo_user_scaled_font_render_glyph_func_t) (cairo_scal
* Since: 1.8
**/
typedef cairo_status_t (*cairo_user_scaled_font_text_to_glyphs_func_t) (cairo_scaled_font_t *scaled_font,
const char *utf8,
cairo_glyph_t **glyphs,
int *num_glyphs);
const char *utf8,
int utf8_len,
cairo_glyph_t **glyphs,
int *num_glyphs,
cairo_text_cluster_t **clusters,
int *num_clusters,
cairo_bool_t *backward);
/**
* cairo_user_scaled_font_unicode_to_glyph_func_t:
@ -1453,6 +1613,14 @@ typedef cairo_status_t (*cairo_user_scaled_font_text_to_glyphs_func_t) (cairo_sc
* set or fails to return glyphs. If this callback is not set, an identity
* mapping from Unicode code-points to glyph indices is assumed.
*
* Note: While cairo does not impose any limitation on glyph indices,
* some applications may assume that a glyph index fits in a 16-bit
* unsigned integer. As such, it is advised that user-fonts keep their
* glyphs in the 0 to 65535 range. Furthermore, some applications may
* assume that glyph 0 is a special glyph-not-found glyph. User-fonts
* are advised to use glyph 0 for such purposes and do not use that
* glyph value for other purposes.
*
* Returns: %CAIRO_STATUS_SUCCESS upon success, or
* %CAIRO_STATUS_USER_FONT_ERROR or any other error status on error.
*
@ -1763,8 +1931,7 @@ typedef enum _cairo_surface_type {
CAIRO_SURFACE_TYPE_SVG,
CAIRO_SURFACE_TYPE_OS2,
CAIRO_SURFACE_TYPE_WIN32_PRINTING,
CAIRO_SURFACE_TYPE_QUARTZ_IMAGE,
CAIRO_SURFACE_TYPE_QPAINTER
CAIRO_SURFACE_TYPE_QUARTZ_IMAGE
} cairo_surface_type_t;
cairo_public cairo_surface_type_t
@ -1839,6 +2006,9 @@ cairo_surface_copy_page (cairo_surface_t *surface);
cairo_public void
cairo_surface_show_page (cairo_surface_t *surface);
cairo_public cairo_bool_t
cairo_surface_has_show_text_glyphs (cairo_surface_t *surface);
/* Image-surface functions */
/**

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

@ -50,6 +50,13 @@
#include "config.h"
#endif
/* We use our own macros */
#undef PACKAGE
#undef PACKAGE_NAME
#undef PACKAGE_STRING
#undef PACKAGE_TARNAME
#undef PACKAGE_VERSION
#include <assert.h>
#include <stdlib.h>
#include <string.h>
@ -68,6 +75,14 @@
#include "cairo-compiler-private.h"
#if defined(CAIRO_HAS_PS_SURFACE) || defined(CAIRO_HAS_PDF_SURFACE) || defined(CAIRO_HAS_SVG_SURFACE)
#define CAIRO_HAS_FONT_SUBSET 1
#endif
#if defined(CAIRO_HAS_PS_SURFACE) || defined(CAIRO_HAS_PDF_SURFACE)
#define CAIRO_HAS_PDF_OPERATORS 1
#endif
CAIRO_BEGIN_DECLS
#ifdef _WIN32
@ -117,7 +132,17 @@ _cairo_win32_tmpfile (void);
* a bit of a pain, but it should be easy to always catch as long as
* one adds a new test case to test a trigger of the new status value.
*/
#define CAIRO_STATUS_LAST_STATUS CAIRO_STATUS_INVALID_CLUSTERS
#define CAIRO_STATUS_LAST_STATUS CAIRO_STATUS_INVALID_SLANT
#ifdef __GNUC__
#define cairo_container_of(ptr, type, member) ({ \
const typeof(((type *) 0)->member) *mptr__ = (ptr); \
(type *) ((char *) mptr__ - offsetof (type, member)); \
})
#else
#define cairo_container_of(ptr, type, member) \
(type *)((char *) (ptr) - (char *) &((type *)0)->member)
#endif
/* Size in bytes of buffer to use off the stack per functions.
@ -306,8 +331,6 @@ _cairo_user_data_array_set_data (cairo_user_data_array_t *array,
cairo_private unsigned long
_cairo_hash_string (const char *c);
typedef struct _cairo_unscaled_font_backend cairo_unscaled_font_backend_t;
/*
* A #cairo_unscaled_font_t is just an opaque handle we use in the
* glyph cache.
@ -415,12 +438,16 @@ struct _cairo_scaled_font_backend {
* then just converting characters one by one.
*/
cairo_warn cairo_int_status_t
(*text_to_glyphs) (void *scaled_font,
double x,
double y,
const char *utf8,
cairo_glyph_t **glyphs,
int *num_glyphs);
(*text_to_glyphs) (void *scaled_font,
double x,
double y,
const char *utf8,
int utf8_len,
cairo_glyph_t **glyphs,
int *num_glyphs,
cairo_text_cluster_t **clusters,
int *num_clusters,
cairo_bool_t *backward);
unsigned long
(*ucs4_to_index) (void *scaled_font,
@ -490,8 +517,6 @@ extern const cairo_private struct _cairo_scaled_font_backend _cairo_quartz_scale
#endif
typedef struct _cairo_solid_pattern cairo_solid_pattern_t;
struct _cairo_surface_backend {
cairo_surface_type_t type;
@ -958,8 +983,6 @@ typedef struct _cairo_traps {
#define CAIRO_SURFACE_RESOLUTION_DEFAULT 72.0
#define CAIRO_SURFACE_FALLBACK_RESOLUTION_DEFAULT 300.0
typedef struct _cairo_gstate cairo_gstate_t;
typedef struct _cairo_stroke_face {
cairo_point_t ccw;
cairo_point_t point;
@ -1226,12 +1249,16 @@ _cairo_gstate_set_font_face (cairo_gstate_t *gstate,
cairo_font_face_t *font_face);
cairo_private cairo_status_t
_cairo_gstate_text_to_glyphs (cairo_gstate_t *font,
const char *utf8,
double x,
double y,
cairo_glyph_t **glyphs,
int *num_glyphs);
_cairo_gstate_text_to_glyphs (cairo_gstate_t *gstate,
double x,
double y,
const char *utf8,
int utf8_len,
cairo_glyph_t **glyphs,
int *num_glyphs,
cairo_text_cluster_t **clusters,
int *num_clusters,
cairo_bool_t *backward);
cairo_private cairo_status_t
_cairo_gstate_glyph_extents (cairo_gstate_t *gstate,
@ -1311,7 +1338,7 @@ _cairo_color_equal (const cairo_color_t *color_a,
/* cairo-font-face.c */
extern const cairo_private cairo_font_face_t _cairo_font_face_nil;
extern const cairo_private cairo_toy_font_face_t _cairo_font_face_nil;
cairo_private void
_cairo_font_face_init (cairo_font_face_t *font_face,
@ -1321,11 +1348,6 @@ cairo_private cairo_status_t
_cairo_font_face_set_error (cairo_font_face_t *font_face,
cairo_status_t status);
cairo_private cairo_font_face_t *
_cairo_toy_font_face_create (const char *family,
cairo_font_slant_t slant,
cairo_font_weight_t weight);
cairo_private void
_cairo_unscaled_font_init (cairo_unscaled_font_t *font,
const cairo_unscaled_font_backend_t *backend);
@ -1353,6 +1375,16 @@ _cairo_hull_compute (cairo_pen_vertex_t *vertices, int *num_vertices);
cairo_private unsigned char *
_cairo_lzw_compress (unsigned char *data, unsigned long *size_in_out);
/* cairo-misc.c */
cairo_private cairo_status_t
_cairo_validate_text_clusters (const char *utf8,
int utf8_len,
const cairo_glyph_t *glyphs,
int num_glyphs,
const cairo_text_cluster_t *clusters,
int num_clusters,
cairo_bool_t backward);
/* cairo-path-fixed.c */
cairo_private void
_cairo_path_fixed_init (cairo_path_fixed_t *path);
@ -1540,14 +1572,6 @@ cairo_private cairo_status_t
_cairo_scaled_font_font_extents (cairo_scaled_font_t *scaled_font,
cairo_font_extents_t *extents);
cairo_private cairo_status_t
_cairo_scaled_font_text_to_glyphs (cairo_scaled_font_t *scaled_font,
double x,
double y,
const char *utf8,
cairo_glyph_t **glyphs,
int *num_glyphs);
cairo_private cairo_status_t
_cairo_scaled_font_glyph_device_extents (cairo_scaled_font_t *scaled_font,
const cairo_glyph_t *glyphs,
@ -1754,9 +1778,6 @@ _cairo_surface_fill (cairo_surface_t *surface,
double tolerance,
cairo_antialias_t antialias);
cairo_private cairo_bool_t
_cairo_surface_has_show_text_glyphs (cairo_surface_t *surface);
cairo_private cairo_status_t
_cairo_surface_show_text_glyphs (cairo_surface_t *surface,
cairo_operator_t op,
@ -2138,11 +2159,11 @@ _cairo_matrix_transform_bounding_box_fixed (const cairo_matrix_t *matrix,
cairo_private cairo_bool_t
_cairo_matrix_is_invertible (const cairo_matrix_t *matrix);
cairo_private void
_cairo_matrix_compute_determinant (const cairo_matrix_t *matrix, double *det);
cairo_private double
_cairo_matrix_compute_determinant (const cairo_matrix_t *matrix);
cairo_private cairo_status_t
_cairo_matrix_compute_scale_factors (const cairo_matrix_t *matrix,
_cairo_matrix_compute_basis_scale_factors (const cairo_matrix_t *matrix,
double *sx, double *sy, int x_major);
cairo_private cairo_bool_t
@ -2328,6 +2349,10 @@ _cairo_gstate_get_antialias (cairo_gstate_t *gstate);
/* cairo-unicode.c */
cairo_private int
_cairo_utf8_get_char_validated (const char *p,
uint32_t *unicode);
cairo_private cairo_status_t
_cairo_utf8_to_ucs4 (const char *str,
int len,
@ -2373,11 +2398,16 @@ slim_hidden_proto (cairo_font_options_merge);
slim_hidden_proto (cairo_font_options_set_antialias);
slim_hidden_proto (cairo_font_options_set_hint_metrics);
slim_hidden_proto (cairo_font_options_set_hint_style);
slim_hidden_proto (cairo_font_options_set_lcd_filter);
slim_hidden_proto (cairo_font_options_set_subpixel_order);
slim_hidden_proto (cairo_font_options_status);
slim_hidden_proto (cairo_get_current_point);
slim_hidden_proto (cairo_get_matrix);
slim_hidden_proto (cairo_get_target);
slim_hidden_proto (cairo_get_tolerance);
slim_hidden_proto (cairo_has_show_text_glyphs);
slim_hidden_proto (cairo_glyph_allocate);
slim_hidden_proto (cairo_glyph_free);
slim_hidden_proto (cairo_image_surface_create);
slim_hidden_proto (cairo_image_surface_create_for_data);
slim_hidden_proto (cairo_image_surface_get_data);
@ -2426,6 +2456,7 @@ slim_hidden_proto (cairo_scaled_font_get_ctm);
slim_hidden_proto (cairo_scaled_font_get_font_face);
slim_hidden_proto (cairo_scaled_font_get_font_matrix);
slim_hidden_proto (cairo_scaled_font_get_font_options);
slim_hidden_proto (cairo_scaled_font_text_to_glyphs);
slim_hidden_proto (cairo_scaled_font_glyph_extents);
slim_hidden_proto_no_warn (cairo_scaled_font_reference);
slim_hidden_proto (cairo_scaled_font_status);
@ -2446,6 +2477,7 @@ slim_hidden_proto (cairo_surface_get_content);
slim_hidden_proto (cairo_surface_get_device_offset);
slim_hidden_proto (cairo_surface_get_font_options);
slim_hidden_proto (cairo_surface_get_type);
slim_hidden_proto (cairo_surface_has_show_text_glyphs);
slim_hidden_proto (cairo_surface_mark_dirty_rectangle);
slim_hidden_proto_no_warn (cairo_surface_reference);
slim_hidden_proto (cairo_surface_set_device_offset);
@ -2453,6 +2485,9 @@ slim_hidden_proto (cairo_surface_set_fallback_resolution);
slim_hidden_proto (cairo_surface_copy_page);
slim_hidden_proto (cairo_surface_show_page);
slim_hidden_proto (cairo_surface_status);
slim_hidden_proto (cairo_text_cluster_allocate);
slim_hidden_proto (cairo_text_cluster_free);
slim_hidden_proto (cairo_toy_font_face_create);
slim_hidden_proto (cairo_version_string);
#if CAIRO_HAS_PNG_FUNCTIONS

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

@ -0,0 +1,24 @@
#define CAIRO_VERSION_H 1
#include <cairo.h>
/* get the "real" version info instead of dummy cairo-version.h */
#undef CAIRO_VERSION_H
#include "../cairo-version.h"
#include <stdio.h>
int
main (void)
{
printf ("Check linking to the just built cairo library\n");
if (cairo_version () == CAIRO_VERSION) {
return 0;
} else {
fprintf (stderr,
"Error: linked to cairo version %s instead of %s\n",
cairo_version_string (),
CAIRO_VERSION_STRING);
return 1;
}
}

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

@ -260,7 +260,7 @@ _test_meta_surface_has_show_text_glyphs (void *abstract_surface)
{
test_meta_surface_t *surface = abstract_surface;
return _cairo_surface_has_show_text_glyphs (surface->meta);
return cairo_surface_has_show_text_glyphs (surface->meta);
}
static cairo_int_status_t

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

@ -237,7 +237,7 @@ _test_paginated_surface_has_show_text_glyphs (void *abstract_surface)
{
test_paginated_surface_t *surface = abstract_surface;
return _cairo_surface_has_show_text_glyphs (surface->target);
return cairo_surface_has_show_text_glyphs (surface->target);
}
static cairo_int_status_t

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

@ -1,31 +0,0 @@
diff -NrpU12 mozilla-trunk.56113bebf57f/gfx/cairo/cairo/src/cairo-clip.c mozilla-trunk/gfx/cairo/cairo/src/cairo-clip.c
--- mozilla-trunk.56113bebf57f/gfx/cairo/cairo/src/cairo-clip.c 2008-04-16 16:02:09.000000000 +1200
+++ mozilla-trunk/gfx/cairo/cairo/src/cairo-clip.c 2008-04-16 16:02:09.000000000 +1200
@@ -669,26 +669,25 @@ _cairo_clip_init_deep_copy (cairo_clip_t
* whatever the right handling is happen */
} else {
if (other->has_region) {
status = _cairo_region_copy (&clip->region, &other->region);
if (status)
goto BAIL;
clip->has_region = TRUE;
}
if (other->surface) {
status = _cairo_surface_clone_similar (target, other->surface,
- other->surface_rect.x,
- other->surface_rect.y,
+ 0, 0,
other->surface_rect.width,
other->surface_rect.height,
&clip->surface);
if (status)
goto BAIL;
clip->surface_rect = other->surface_rect;
}
if (other->path) {
status = _cairo_clip_path_reapply_clip_path (clip, other->path);
if (status && status != CAIRO_INT_STATUS_UNSUPPORTED)

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

@ -68,8 +68,7 @@ endif
# Build MMX code either with VC or with gcc-on-x86
ifdef _MSC_VER
USE_MMX=1
# no SSE2 yet, until compilation is fixed
#USE_SSE2=1
USE_SSE2=1
MMX_CFLAGS=
endif
@ -78,8 +77,8 @@ ifeq (86,$(findstring 86,$(OS_TEST)))
USE_MMX=1
MMX_CFLAGS=-mmmx -Winline
# See bug 410509 why we can't use SSE2 yet
#USE_SSE2=1
#MMX_CFLAGS+=-msse -msse2
USE_SSE2=1
MMX_CFLAGS+=-msse -msse2
ifneq ($(MOZ_WIDGET_TOOLKIT),os2)
MMX_CFLAGS+=--param inline-unit-growth=10000 --param large-function-growth=10000
endif
@ -114,7 +113,7 @@ DEFINES += -DUSE_MMX
endif
ifdef USE_SSE2
CSRCS += pixman-sse.c
CSRCS += pixman-sse2.c
DEFINES += -DUSE_SSE -DUSE_SSE2
endif
@ -141,7 +140,7 @@ pixman-mmx.$(OBJ_SUFFIX): pixman-mmx.c Makefile Makefile.in
@$(MAKE_DEPS_AUTO_CC)
$(ELOG) $(CC) $(OUTOPTION)$@ -c $(COMPILE_CFLAGS) $(MMX_CFLAGS) $(_VPATH_SRCS)
pixman-sse.$(OBJ_SUFFIX): pixman-sse.c Makefile Makefile.in
pixman-sse2.$(OBJ_SUFFIX): pixman-sse2.c Makefile Makefile.in
$(REPORT_BUILD)
@$(MAKE_DEPS_AUTO_CC)
$(ELOG) $(CC) $(OUTOPTION)$@ -c $(COMPILE_CFLAGS) $(MMX_CFLAGS) $(_VPATH_SRCS)

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

@ -61,19 +61,31 @@
x_c = (x_c * a) / 255 + y
*/
#define FbByteMulAdd(x, a, y) do { \
/* multiply and divide: trunc((i + 128)*257/65536) */ \
uint32_t t = ((x & RB_MASK) * a) + RB_ONE_HALF; \
t = (t + ((t >> COMPONENT_SIZE) & RB_MASK)) >> COMPONENT_SIZE; \
t &= RB_MASK; \
\
/* add */ \
t += y & RB_MASK; \
\
/* saturate */ \
t |= RB_MASK_PLUS_ONE - ((t >> COMPONENT_SIZE) & RB_MASK); \
t &= RB_MASK; \
\
/* multiply and divide */ \
x = (((x >> COMPONENT_SIZE) & RB_MASK) * a) + RB_ONE_HALF; \
x = (x + ((x >> COMPONENT_SIZE) & RB_MASK)) >> COMPONENT_SIZE; \
x &= RB_MASK; \
\
/* add */ \
x += (y >> COMPONENT_SIZE) & RB_MASK; \
\
/* saturate */ \
x |= RB_MASK_PLUS_ONE - ((x >> COMPONENT_SIZE) & RB_MASK); \
x &= RB_MASK; \
\
/* recombine */ \
x <<= COMPONENT_SIZE; \
x += t; \
} while (0)

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

@ -61,19 +61,31 @@
x_c = (x_c * a) / 255 + y
*/
#define FbByteMulAdd(x, a, y) do { \
/* multiply and divide: trunc((i + 128)*257/65536) */ \
uint64_t t = ((x & RB_MASK) * a) + RB_ONE_HALF; \
t = (t + ((t >> COMPONENT_SIZE) & RB_MASK)) >> COMPONENT_SIZE; \
t &= RB_MASK; \
\
/* add */ \
t += y & RB_MASK; \
\
/* saturate */ \
t |= RB_MASK_PLUS_ONE - ((t >> COMPONENT_SIZE) & RB_MASK); \
t &= RB_MASK; \
\
/* multiply and divide */ \
x = (((x >> COMPONENT_SIZE) & RB_MASK) * a) + RB_ONE_HALF; \
x = (x + ((x >> COMPONENT_SIZE) & RB_MASK)) >> COMPONENT_SIZE; \
x &= RB_MASK; \
\
/* add */ \
x += (y >> COMPONENT_SIZE) & RB_MASK; \
\
/* saturate */ \
x |= RB_MASK_PLUS_ONE - ((x >> COMPONENT_SIZE) & RB_MASK); \
x &= RB_MASK; \
\
/* recombine */ \
x <<= COMPONENT_SIZE; \
x += t; \
} while (0)

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

@ -36,9 +36,6 @@
#ifdef USE_MMX
#include <mmintrin.h>
#ifdef USE_SSE
#include <xmmintrin.h> /* for _mm_shuffle_pi16 and _MM_SHUFFLE */
#endif
#include "pixman-mmx.h"
@ -227,28 +224,6 @@ pix_add (__m64 a, __m64 b)
return _mm_adds_pu8 (a, b);
}
#ifdef USE_SSE
static inline __m64
expand_alpha (__m64 pixel)
{
return _mm_shuffle_pi16 (pixel, _MM_SHUFFLE(3, 3, 3, 3));
}
static inline __m64
expand_alpha_rev (__m64 pixel)
{
return _mm_shuffle_pi16 (pixel, _MM_SHUFFLE(0, 0, 0, 0));
}
static inline __m64
invert_colors (__m64 pixel)
{
return _mm_shuffle_pi16 (pixel, _MM_SHUFFLE(3, 0, 1, 2));
}
#else
static inline __m64
expand_alpha (__m64 pixel)
{
@ -300,8 +275,6 @@ invert_colors (__m64 pixel)
return x;
}
#endif
static inline __m64
over (__m64 src, __m64 srca, __m64 dest)
{

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

@ -33,7 +33,7 @@
#include "pixman-private.h"
#include "pixman-mmx.h"
#include "pixman-vmx.h"
#include "pixman-sse.h"
#include "pixman-sse2.h"
#include "pixman-combine32.h"
#ifdef __GNUC__
@ -1395,7 +1395,7 @@ static const FastPathInfo mmx_fast_paths[] =
#endif
#ifdef USE_SSE2
static const FastPathInfo sse_fast_paths[] =
static const FastPathInfo sse2_fast_paths[] =
{
{ PIXMAN_OP_OVER, PIXMAN_solid, PIXMAN_a8, PIXMAN_r5g6b5, fbCompositeSolidMask_nx8x0565sse2, 0 },
{ PIXMAN_OP_OVER, PIXMAN_solid, PIXMAN_a8, PIXMAN_b5g6r5, fbCompositeSolidMask_nx8x0565sse2, 0 },
@ -1755,7 +1755,7 @@ pixman_image_composite (pixman_op_t op,
#endif
#ifdef USE_SSE2
fbComposeSetupSSE();
fbComposeSetupSSE2();
#endif
if (srcRepeat && srcTransform &&
@ -1815,8 +1815,8 @@ pixman_image_composite (pixman_op_t op,
info = NULL;
#ifdef USE_SSE2
if (pixman_have_sse ())
info = get_fast_path (sse_fast_paths, op, pSrc, pMask, pDst, pixbuf);
if (pixman_have_sse2 ())
info = get_fast_path (sse2_fast_paths, op, pSrc, pMask, pDst, pixbuf);
#endif
#ifdef USE_MMX
@ -2149,19 +2149,19 @@ pixman_have_mmx (void)
#ifdef USE_SSE2
pixman_bool_t
pixman_have_sse (void)
pixman_have_sse2 (void)
{
static pixman_bool_t initialized = FALSE;
static pixman_bool_t sse_present;
static pixman_bool_t sse2_present;
if (!initialized)
{
unsigned int features = detectCPUFeatures();
sse_present = (features & (MMX|MMX_Extensions|SSE|SSE2)) == (MMX|MMX_Extensions|SSE|SSE2);
sse2_present = (features & (MMX|MMX_Extensions|SSE|SSE2)) == (MMX|MMX_Extensions|SSE|SSE2);
initialized = TRUE;
}
return sse_present;
return sse2_present;
}
#endif

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

@ -731,6 +731,9 @@ pixman_compute_composite_region32 (pixman_region32_t * pRegion,
/* GCC visibility */
#if defined(__GNUC__) && __GNUC__ >= 4
#define PIXMAN_EXPORT __attribute__ ((visibility("default")))
/* Sun Studio 8 visibility */
#elif defined(__SUNPRO_C) && (__SUNPRO_C >= 0x550)
#define PIXMAN_EXPORT __global
#else
#define PIXMAN_EXPORT
#endif

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

@ -34,7 +34,7 @@
#include <xmmintrin.h> /* for _mm_shuffle_pi16 and _MM_SHUFFLE */
#include <emmintrin.h> /* for SSE2 intrinsics */
#include "pixman-sse.h"
#include "pixman-sse2.h"
#ifdef USE_SSE2
@ -43,6 +43,10 @@
#define inline __forceinline
#endif
#ifdef __GNUC__
# define inline __inline__ __attribute__ ((__always_inline__))
#endif
/* -------------------------------------------------------------------------------------------------
* Locals
*/
@ -139,14 +143,9 @@ pack565_2x128_128 (__m128i lo, __m128i hi)
}
static inline __m128i
pack565_4x128_128 (__m128i xmm0, __m128i xmm1, __m128i xmm2, __m128i xmm3)
pack565_4x128_128 (__m128i* xmm0, __m128i* xmm1, __m128i* xmm2, __m128i* xmm3)
{
__m128i lo, hi;
lo = _mm_packus_epi16 (pack565_2x128_128 ( xmm0, xmm1 ), _mm_setzero_si128 ());
hi = _mm_packus_epi16 (_mm_setzero_si128 (), pack565_2x128_128 ( xmm2, xmm3 ));
return _mm_or_si128 (lo, hi);
return _mm_packus_epi16 (pack565_2x128_128 (*xmm0, *xmm1), pack565_2x128_128 (*xmm2, *xmm3));
}
static inline uint32_t
@ -192,12 +191,12 @@ expandAlphaRev_2x128 (__m128i dataLo, __m128i dataHi, __m128i* alphaLo, __m128i*
}
static inline void
pixMultiply_2x128 (__m128i dataLo, __m128i dataHi, __m128i alphaLo, __m128i alphaHi, __m128i* retLo, __m128i* retHi)
pixMultiply_2x128 (__m128i* dataLo, __m128i* dataHi, __m128i* alphaLo, __m128i* alphaHi, __m128i* retLo, __m128i* retHi)
{
__m128i lo, hi;
lo = _mm_mullo_epi16 (dataLo, alphaLo);
hi = _mm_mullo_epi16 (dataHi, alphaHi);
lo = _mm_mullo_epi16 (*dataLo, *alphaLo);
hi = _mm_mullo_epi16 (*dataHi, *alphaHi);
lo = _mm_adds_epu16 (lo, Mask0080);
hi = _mm_adds_epu16 (hi, Mask0080);
*retLo = _mm_mulhi_epu16 (lo, Mask0101);
@ -205,17 +204,17 @@ pixMultiply_2x128 (__m128i dataLo, __m128i dataHi, __m128i alphaLo, __m128i alph
}
static inline void
pixAddMultiply_2x128 (__m128i srcLo, __m128i srcHi, __m128i alphaDstLo, __m128i alphaDstHi,
__m128i dstLo, __m128i dstHi, __m128i alphaSrcLo, __m128i alphaSrcHi,
pixAddMultiply_2x128 (__m128i* srcLo, __m128i* srcHi, __m128i* alphaDstLo, __m128i* alphaDstHi,
__m128i* dstLo, __m128i* dstHi, __m128i* alphaSrcLo, __m128i* alphaSrcHi,
__m128i* retLo, __m128i* retHi)
{
__m128i lo, hi;
__m128i mulLo, mulHi;
lo = _mm_mullo_epi16 (srcLo, alphaDstLo);
hi = _mm_mullo_epi16 (srcHi, alphaDstHi);
mulLo = _mm_mullo_epi16 (dstLo, alphaSrcLo);
mulHi = _mm_mullo_epi16 (dstHi, alphaSrcHi);
lo = _mm_mullo_epi16 (*srcLo, *alphaDstLo);
hi = _mm_mullo_epi16 (*srcHi, *alphaDstHi);
mulLo = _mm_mullo_epi16 (*dstLo, *alphaSrcLo);
mulHi = _mm_mullo_epi16 (*dstHi, *alphaSrcHi);
lo = _mm_adds_epu16 (lo, Mask0080);
hi = _mm_adds_epu16 (hi, Mask0080);
lo = _mm_adds_epu16 (lo, mulLo);
@ -243,14 +242,14 @@ invertColors_2x128 (__m128i dataLo, __m128i dataHi, __m128i* invLo, __m128i* inv
}
static inline void
over_2x128 (__m128i srcLo, __m128i srcHi, __m128i alphaLo, __m128i alphaHi, __m128i* dstLo, __m128i* dstHi)
over_2x128 (__m128i* srcLo, __m128i* srcHi, __m128i* alphaLo, __m128i* alphaHi, __m128i* dstLo, __m128i* dstHi)
{
negate_2x128 (alphaLo, alphaHi, &alphaLo, &alphaHi);
negate_2x128 (*alphaLo, *alphaHi, alphaLo, alphaHi);
pixMultiply_2x128 (*dstLo, *dstHi, alphaLo, alphaHi, dstLo, dstHi);
pixMultiply_2x128 (dstLo, dstHi, alphaLo, alphaHi, dstLo, dstHi);
*dstLo = _mm_adds_epu8 (srcLo, *dstLo);
*dstHi = _mm_adds_epu8 (srcHi, *dstHi);
*dstLo = _mm_adds_epu8 (*srcLo, *dstLo);
*dstHi = _mm_adds_epu8 (*srcHi, *dstHi);
}
static inline void
@ -266,14 +265,14 @@ overRevNonPre_2x128 (__m128i srcLo, __m128i srcHi, __m128i* dstLo, __m128i* dstH
invertColors_2x128 (srcLo, srcHi, &srcLo, &srcHi);
pixMultiply_2x128 (srcLo, srcHi, lo, hi, &lo, &hi);
pixMultiply_2x128 (&srcLo, &srcHi, &lo, &hi, &lo, &hi);
over_2x128 (lo, hi, alphaLo, alphaHi, dstLo, dstHi);
over_2x128 (&lo, &hi, &alphaLo, &alphaHi, dstLo, dstHi);
}
static inline void
inOver_2x128 (__m128i srcLo, __m128i srcHi, __m128i alphaLo, __m128i alphaHi,
__m128i maskLo, __m128i maskHi, __m128i* dstLo, __m128i* dstHi)
inOver_2x128 (__m128i* srcLo, __m128i* srcHi, __m128i* alphaLo, __m128i* alphaHi,
__m128i* maskLo, __m128i* maskHi, __m128i* dstLo, __m128i* dstHi)
{
__m128i sLo, sHi;
__m128i aLo, aHi;
@ -281,7 +280,7 @@ inOver_2x128 (__m128i srcLo, __m128i srcHi, __m128i alphaLo, __m128i alphaHi
pixMultiply_2x128 ( srcLo, srcHi, maskLo, maskHi, &sLo, &sHi);
pixMultiply_2x128 (alphaLo, alphaHi, maskLo, maskHi, &aLo, &aHi);
over_2x128 (sLo, sHi, aLo, aHi, dstLo, dstHi);
over_2x128 (&sLo, &sHi, &aLo, &aHi, dstLo, dstHi);
}
static inline void
@ -368,11 +367,11 @@ pixMultiply_1x64 (__m64 data, __m64 alpha)
}
static inline __m64
pixAddMultiply_1x64 (__m64 src, __m64 alphaDst, __m64 dst, __m64 alphaSrc)
pixAddMultiply_1x64 (__m64* src, __m64* alphaDst, __m64* dst, __m64* alphaSrc)
{
return _mm_mulhi_pu16 (_mm_adds_pu16 (_mm_adds_pu16 (_mm_mullo_pi16 (src, alphaDst),
return _mm_mulhi_pu16 (_mm_adds_pu16 (_mm_adds_pu16 (_mm_mullo_pi16 (*src, *alphaDst),
xMask0080),
_mm_mullo_pi16 (dst, alphaSrc)),
_mm_mullo_pi16 (*dst, *alphaSrc)),
xMask0101);
}
@ -395,11 +394,11 @@ over_1x64 (__m64 src, __m64 alpha, __m64 dst)
}
static inline __m64
inOver_1x64 (__m64 src, __m64 alpha, __m64 mask, __m64 dst)
inOver_1x64 (__m64* src, __m64* alpha, __m64* mask, __m64* dst)
{
return over_1x64 (pixMultiply_1x64 (src, mask),
pixMultiply_1x64 (alpha, mask),
dst);
return over_1x64 (pixMultiply_1x64 (*src, *mask),
pixMultiply_1x64 (*alpha, *mask),
*dst);
}
static inline __m64
@ -530,7 +529,7 @@ coreCombineOverUsse2 (uint32_t* pd, const uint32_t* ps, int w)
expandAlpha_2x128 (xmmSrcLo, xmmSrcHi, &xmmAlphaLo, &xmmAlphaHi);
over_2x128 (xmmSrcLo, xmmSrcHi, xmmAlphaLo, xmmAlphaHi, &xmmDstLo, &xmmDstHi);
over_2x128 (&xmmSrcLo, &xmmSrcHi, &xmmAlphaLo, &xmmAlphaHi, &xmmDstLo, &xmmDstHi);
/* rebuid the 4 pixel data and save*/
save128Aligned ((__m128i*)pd, pack_2x128_128 (xmmDstLo, xmmDstHi));
@ -594,7 +593,7 @@ coreCombineOverReverseUsse2 (uint32_t* pd, const uint32_t* ps, int w)
expandAlpha_2x128 (xmmDstLo, xmmDstHi, &xmmAlphaLo, &xmmAlphaHi);
over_2x128 (xmmDstLo, xmmDstHi, xmmAlphaLo, xmmAlphaHi, &xmmSrcLo, &xmmSrcHi);
over_2x128 (&xmmDstLo, &xmmDstHi, &xmmAlphaLo, &xmmAlphaHi, &xmmSrcLo, &xmmSrcHi);
/* rebuid the 4 pixel data and save*/
save128Aligned ((__m128i*)pd, pack_2x128_128 (xmmSrcLo, xmmSrcHi));
@ -669,7 +668,7 @@ coreCombineInUsse2 (uint32_t* pd, const uint32_t* ps, int w)
expandAlpha_2x128 (xmmDstLo, xmmDstHi, &xmmDstLo, &xmmDstHi);
unpack_128_2x128 (xmmSrcHi, &xmmSrcLo, &xmmSrcHi);
pixMultiply_2x128 (xmmSrcLo, xmmSrcHi, xmmDstLo, xmmDstHi, &xmmDstLo, &xmmDstHi);
pixMultiply_2x128 (&xmmSrcLo, &xmmSrcHi, &xmmDstLo, &xmmDstHi, &xmmDstLo, &xmmDstHi);
save128Aligned ((__m128i*)pd, pack_2x128_128 (xmmDstLo, xmmDstHi));
@ -726,7 +725,7 @@ coreCombineReverseInUsse2 (uint32_t* pd, const uint32_t* ps, int w)
expandAlpha_2x128 (xmmSrcLo, xmmSrcHi, &xmmSrcLo, &xmmSrcHi);
unpack_128_2x128 (xmmDstHi, &xmmDstLo, &xmmDstHi);
pixMultiply_2x128 (xmmDstLo, xmmDstHi, xmmSrcLo, xmmSrcHi, &xmmDstLo, &xmmDstHi);
pixMultiply_2x128 (&xmmDstLo, &xmmDstHi, &xmmSrcLo, &xmmSrcHi, &xmmDstLo, &xmmDstHi);
save128Aligned ((__m128i*)pd, pack_2x128_128 (xmmDstLo, xmmDstHi));
@ -783,7 +782,7 @@ coreCombineReverseOutUsse2 (uint32_t* pd, const uint32_t* ps, int w)
expandAlpha_2x128 (xmmSrcLo, xmmSrcHi, &xmmSrcLo, &xmmSrcHi);
negate_2x128 (xmmSrcLo, xmmSrcHi, &xmmSrcLo, &xmmSrcHi);
pixMultiply_2x128 (xmmDstLo, xmmDstHi, xmmSrcLo, xmmSrcHi, &xmmDstLo, &xmmDstHi);
pixMultiply_2x128 (&xmmDstLo, &xmmDstHi, &xmmSrcLo, &xmmSrcHi, &xmmDstLo, &xmmDstHi);
save128Aligned ((__m128i*)pd, pack_2x128_128 (xmmDstLo, xmmDstHi));
@ -840,7 +839,7 @@ coreCombineOutUsse2 (uint32_t* pd, const uint32_t* ps, int w)
expandAlpha_2x128 (xmmDstLo, xmmDstHi, &xmmDstLo, &xmmDstHi);
negate_2x128 (xmmDstLo, xmmDstHi, &xmmDstLo, &xmmDstHi);
pixMultiply_2x128 (xmmSrcLo, xmmSrcHi, xmmDstLo, xmmDstHi, &xmmDstLo, &xmmDstHi);
pixMultiply_2x128 (&xmmSrcLo, &xmmSrcHi, &xmmDstLo, &xmmDstHi, &xmmDstLo, &xmmDstHi);
save128Aligned ((__m128i*)pd, pack_2x128_128 (xmmDstLo, xmmDstHi));
@ -868,7 +867,7 @@ coreCombineAtopUPixelsse2 (uint32_t src, uint32_t dst)
__m64 sa = negate_1x64 (expandAlpha_1x64 (s));
__m64 da = expandAlpha_1x64 (d);
return pack_1x64_32 (pixAddMultiply_1x64 (s, da, d, sa));
return pack_1x64_32 (pixAddMultiply_1x64 (&s, &da, &d, &sa));
}
static inline void
@ -915,8 +914,8 @@ coreCombineAtopUsse2 (uint32_t* pd, const uint32_t* ps, int w)
negate_2x128 (xmmAlphaSrcLo, xmmAlphaSrcHi, &xmmAlphaSrcLo, &xmmAlphaSrcHi);
pixAddMultiply_2x128 ( xmmSrcLo, xmmSrcHi, xmmAlphaDstLo, xmmAlphaDstHi,
xmmDstLo, xmmDstHi, xmmAlphaSrcLo, xmmAlphaSrcHi,
pixAddMultiply_2x128 ( &xmmSrcLo, &xmmSrcHi, &xmmAlphaDstLo, &xmmAlphaDstHi,
&xmmDstLo, &xmmDstHi, &xmmAlphaSrcLo, &xmmAlphaSrcHi,
&xmmDstLo, &xmmDstHi );
save128Aligned ((__m128i*)pd, pack_2x128_128 (xmmDstLo, xmmDstHi));
@ -945,7 +944,7 @@ coreCombineReverseAtopUPixelsse2 (uint32_t src, uint32_t dst)
__m64 sa = expandAlpha_1x64 (s);
__m64 da = negate_1x64 (expandAlpha_1x64 (d));
return pack_1x64_32 (pixAddMultiply_1x64 (s, da, d, sa));
return pack_1x64_32 (pixAddMultiply_1x64 (&s, &da, &d, &sa));
}
static inline void
@ -992,8 +991,8 @@ coreCombineReverseAtopUsse2 (uint32_t* pd, const uint32_t* ps, int w)
negate_2x128 (xmmAlphaDstLo, xmmAlphaDstHi, &xmmAlphaDstLo, &xmmAlphaDstHi);
pixAddMultiply_2x128 ( xmmSrcLo, xmmSrcHi, xmmAlphaDstLo, xmmAlphaDstHi,
xmmDstLo, xmmDstHi, xmmAlphaSrcLo, xmmAlphaSrcHi,
pixAddMultiply_2x128 ( &xmmSrcLo, &xmmSrcHi, &xmmAlphaDstLo, &xmmAlphaDstHi,
&xmmDstLo, &xmmDstHi, &xmmAlphaSrcLo, &xmmAlphaSrcHi,
&xmmDstLo, &xmmDstHi );
save128Aligned ((__m128i*)pd, pack_2x128_128 (xmmDstLo, xmmDstHi));
@ -1019,7 +1018,10 @@ coreCombineXorUPixelsse2 (uint32_t src, uint32_t dst)
__m64 s = unpack_32_1x64 (src);
__m64 d = unpack_32_1x64 (dst);
return pack_1x64_32 (pixAddMultiply_1x64 (s, negate_1x64 (expandAlpha_1x64 (d)), d, negate_1x64 (expandAlpha_1x64 (s))));
__m64 negD = negate_1x64 (expandAlpha_1x64 (d));
__m64 negS = negate_1x64 (expandAlpha_1x64 (s));
return pack_1x64_32 (pixAddMultiply_1x64 (&s, &negD, &d, &negS));
}
static inline void
@ -1070,8 +1072,8 @@ coreCombineXorUsse2 (uint32_t* dst, const uint32_t* src, int width)
negate_2x128 (xmmAlphaSrcLo, xmmAlphaSrcHi, &xmmAlphaSrcLo, &xmmAlphaSrcHi);
negate_2x128 (xmmAlphaDstLo, xmmAlphaDstHi, &xmmAlphaDstLo, &xmmAlphaDstHi);
pixAddMultiply_2x128 ( xmmSrcLo, xmmSrcHi, xmmAlphaDstLo, xmmAlphaDstHi,
xmmDstLo, xmmDstHi, xmmAlphaSrcLo, xmmAlphaSrcHi,
pixAddMultiply_2x128 ( &xmmSrcLo, &xmmSrcHi, &xmmAlphaDstLo, &xmmAlphaDstHi,
&xmmDstLo, &xmmDstHi, &xmmAlphaSrcLo, &xmmAlphaSrcHi,
&xmmDstLo, &xmmDstHi );
save128Aligned ((__m128i*)pd, pack_2x128_128 (xmmDstLo, xmmDstHi));
@ -1267,7 +1269,7 @@ coreCombineSrcCsse2 (uint32_t* pd, const uint32_t* ps, const uint32_t *pm, int w
unpack_128_2x128 (xmmSrcHi, &xmmSrcLo, &xmmSrcHi);
unpack_128_2x128 (xmmMaskHi, &xmmMaskLo, &xmmMaskHi);
pixMultiply_2x128 (xmmSrcLo, xmmSrcHi, xmmMaskLo, xmmMaskHi, &xmmDstLo, &xmmDstHi);
pixMultiply_2x128 (&xmmSrcLo, &xmmSrcHi, &xmmMaskLo, &xmmMaskHi, &xmmDstLo, &xmmDstHi);
save128Aligned( (__m128i*)pd, pack_2x128_128 (xmmDstLo, xmmDstHi));
@ -1290,8 +1292,11 @@ static inline uint32_t
coreCombineOverCPixelsse2 (uint32_t src, uint32_t mask, uint32_t dst)
{
__m64 s = unpack_32_1x64 (src);
__m64 expAlpha = expandAlpha_1x64 (s);
__m64 unpkMask = unpack_32_1x64 (mask);
__m64 unpkDst = unpack_32_1x64 (dst);
return pack_1x64_32 (inOver_1x64 (s, expandAlpha_1x64 (s), unpack_32_1x64 (mask), unpack_32_1x64 (dst)));
return pack_1x64_32 (inOver_1x64 (&s, &expAlpha, &unpkMask, &unpkDst));
}
static inline void
@ -1341,7 +1346,7 @@ coreCombineOverCsse2 (uint32_t* pd, const uint32_t* ps, const uint32_t *pm, int
expandAlpha_2x128 (xmmSrcLo, xmmSrcHi, &xmmAlphaLo, &xmmAlphaHi);
inOver_2x128 (xmmSrcLo, xmmSrcHi, xmmAlphaLo, xmmAlphaHi, xmmMaskLo, xmmMaskHi, &xmmDstLo, &xmmDstHi);
inOver_2x128 (&xmmSrcLo, &xmmSrcHi, &xmmAlphaLo, &xmmAlphaHi, &xmmMaskLo, &xmmMaskHi, &xmmDstLo, &xmmDstHi);
save128Aligned( (__m128i*)pd, pack_2x128_128 (xmmDstLo, xmmDstHi));
@ -1416,9 +1421,9 @@ coreCombineOverReverseCsse2 (uint32_t* pd, const uint32_t* ps, const uint32_t *p
unpack_128_2x128 (xmmMaskHi, &xmmMaskLo, &xmmMaskHi);
expandAlpha_2x128 (xmmDstLo, xmmDstHi, &xmmAlphaLo, &xmmAlphaHi);
pixMultiply_2x128 (xmmSrcLo, xmmSrcHi, xmmMaskLo, xmmMaskHi, &xmmMaskLo, &xmmMaskHi);
pixMultiply_2x128 (&xmmSrcLo, &xmmSrcHi, &xmmMaskLo, &xmmMaskHi, &xmmMaskLo, &xmmMaskHi);
over_2x128 (xmmDstLo, xmmDstHi, xmmAlphaLo, xmmAlphaHi, &xmmMaskLo, &xmmMaskHi);
over_2x128 (&xmmDstLo, &xmmDstHi, &xmmAlphaLo, &xmmAlphaHi, &xmmMaskLo, &xmmMaskHi);
save128Aligned( (__m128i*)pd, pack_2x128_128 (xmmMaskLo, xmmMaskHi));
@ -1486,9 +1491,9 @@ coreCombineInCsse2 (uint32_t *pd, uint32_t *ps, uint32_t *pm, int w)
unpack_128_2x128 (xmmMaskHi, &xmmMaskLo, &xmmMaskHi);
expandAlpha_2x128 (xmmDstLo, xmmDstHi, &xmmAlphaLo, &xmmAlphaHi);
pixMultiply_2x128 (xmmSrcLo, xmmSrcHi, xmmMaskLo, xmmMaskHi, &xmmDstLo, &xmmDstHi);
pixMultiply_2x128 (&xmmSrcLo, &xmmSrcHi, &xmmMaskLo, &xmmMaskHi, &xmmDstLo, &xmmDstHi);
pixMultiply_2x128 (xmmDstLo, xmmDstHi, xmmAlphaLo, xmmAlphaHi, &xmmDstLo, &xmmDstHi);
pixMultiply_2x128 (&xmmDstLo, &xmmDstHi, &xmmAlphaLo, &xmmAlphaHi, &xmmDstLo, &xmmDstHi);
save128Aligned( (__m128i*)pd, pack_2x128_128 (xmmDstLo, xmmDstHi));
@ -1558,9 +1563,9 @@ coreCombineInReverseCsse2 (uint32_t *pd, uint32_t *ps, uint32_t *pm, int w)
unpack_128_2x128 (xmmMaskHi, &xmmMaskLo, &xmmMaskHi);
expandAlpha_2x128 (xmmSrcLo, xmmSrcHi, &xmmAlphaLo, &xmmAlphaHi);
pixMultiply_2x128 (xmmMaskLo, xmmMaskHi, xmmAlphaLo, xmmAlphaHi, &xmmAlphaLo, &xmmAlphaHi);
pixMultiply_2x128 (&xmmMaskLo, &xmmMaskHi, &xmmAlphaLo, &xmmAlphaHi, &xmmAlphaLo, &xmmAlphaHi);
pixMultiply_2x128 (xmmDstLo, xmmDstHi, xmmAlphaLo, xmmAlphaHi, &xmmDstLo, &xmmDstHi);
pixMultiply_2x128 (&xmmDstLo, &xmmDstHi, &xmmAlphaLo, &xmmAlphaHi, &xmmDstLo, &xmmDstHi);
save128Aligned( (__m128i*)pd, pack_2x128_128 (xmmDstLo, xmmDstHi));
@ -1632,8 +1637,8 @@ coreCombineOutCsse2 (uint32_t *pd, uint32_t *ps, uint32_t *pm, int w)
expandAlpha_2x128 (xmmDstLo, xmmDstHi, &xmmAlphaLo, &xmmAlphaHi);
negate_2x128 (xmmAlphaLo, xmmAlphaHi, &xmmAlphaLo, &xmmAlphaHi);
pixMultiply_2x128 (xmmSrcLo, xmmSrcHi, xmmMaskLo, xmmMaskHi, &xmmDstLo, &xmmDstHi);
pixMultiply_2x128 (xmmDstLo, xmmDstHi, xmmAlphaLo, xmmAlphaHi, &xmmDstLo, &xmmDstHi);
pixMultiply_2x128 (&xmmSrcLo, &xmmSrcHi, &xmmMaskLo, &xmmMaskHi, &xmmDstLo, &xmmDstHi);
pixMultiply_2x128 (&xmmDstLo, &xmmDstHi, &xmmAlphaLo, &xmmAlphaHi, &xmmDstLo, &xmmDstHi);
save128Aligned( (__m128i*)pd, pack_2x128_128 (xmmDstLo, xmmDstHi));
@ -1704,11 +1709,11 @@ coreCombineOutReverseCsse2 (uint32_t *pd, uint32_t *ps, uint32_t *pm, int w)
expandAlpha_2x128 (xmmSrcLo, xmmSrcHi, &xmmAlphaLo, &xmmAlphaHi);
pixMultiply_2x128 (xmmMaskLo, xmmMaskHi, xmmAlphaLo, xmmAlphaHi, &xmmMaskLo, &xmmMaskHi);
pixMultiply_2x128 (&xmmMaskLo, &xmmMaskHi, &xmmAlphaLo, &xmmAlphaHi, &xmmMaskLo, &xmmMaskHi);
negate_2x128 (xmmMaskLo, xmmMaskHi, &xmmMaskLo, &xmmMaskHi);
pixMultiply_2x128 (xmmDstLo, xmmDstHi, xmmMaskLo, xmmMaskHi, &xmmDstLo, &xmmDstHi);
pixMultiply_2x128 (&xmmDstLo, &xmmDstHi, &xmmMaskLo, &xmmMaskHi, &xmmDstLo, &xmmDstHi);
save128Aligned( (__m128i*)pd, pack_2x128_128 (xmmDstLo, xmmDstHi));
@ -1743,7 +1748,7 @@ coreCombineAtopCPixelsse2 (uint32_t src, uint32_t mask, uint32_t dst)
s = pixMultiply_1x64 (s, m);
m = negate_1x64 (pixMultiply_1x64 (m, sa));
return pack_1x64_32 (pixAddMultiply_1x64 (d, m, s, da));
return pack_1x64_32 (pixAddMultiply_1x64 (&d, &m, &s, &da));
}
static inline void
@ -1795,13 +1800,13 @@ coreCombineAtopCsse2 (uint32_t *pd, uint32_t *ps, uint32_t *pm, int w)
expandAlpha_2x128 (xmmSrcLo, xmmSrcHi, &xmmAlphaSrcLo, &xmmAlphaSrcHi);
expandAlpha_2x128 (xmmDstLo, xmmDstHi, &xmmAlphaDstLo, &xmmAlphaDstHi);
pixMultiply_2x128 (xmmSrcLo, xmmSrcHi, xmmMaskLo, xmmMaskHi, &xmmSrcLo, &xmmSrcHi);
pixMultiply_2x128 (xmmMaskLo, xmmMaskHi, xmmAlphaSrcLo, xmmAlphaSrcHi, &xmmMaskLo, &xmmMaskHi);
pixMultiply_2x128 (&xmmSrcLo, &xmmSrcHi, &xmmMaskLo, &xmmMaskHi, &xmmSrcLo, &xmmSrcHi);
pixMultiply_2x128 (&xmmMaskLo, &xmmMaskHi, &xmmAlphaSrcLo, &xmmAlphaSrcHi, &xmmMaskLo, &xmmMaskHi);
negate_2x128 (xmmMaskLo, xmmMaskHi, &xmmMaskLo, &xmmMaskHi);
pixAddMultiply_2x128 (xmmDstLo, xmmDstHi, xmmMaskLo, xmmMaskHi,
xmmSrcLo, xmmSrcHi, xmmAlphaDstLo, xmmAlphaDstHi,
pixAddMultiply_2x128 (&xmmDstLo, &xmmDstHi, &xmmMaskLo, &xmmMaskHi,
&xmmSrcLo, &xmmSrcHi, &xmmAlphaDstLo, &xmmAlphaDstHi,
&xmmDstLo, &xmmDstHi);
save128Aligned( (__m128i*)pd, pack_2x128_128 (xmmDstLo, xmmDstHi));
@ -1836,7 +1841,7 @@ coreCombineReverseAtopCPixelsse2 (uint32_t src, uint32_t mask, uint32_t dst)
s = pixMultiply_1x64 (s, m);
m = pixMultiply_1x64 (m, sa);
return pack_1x64_32 (pixAddMultiply_1x64 (d, m, s, da));
return pack_1x64_32 (pixAddMultiply_1x64 (&d, &m, &s, &da));
}
static inline void
@ -1888,13 +1893,13 @@ coreCombineReverseAtopCsse2 (uint32_t *pd, uint32_t *ps, uint32_t *pm, int w)
expandAlpha_2x128 (xmmSrcLo, xmmSrcHi, &xmmAlphaSrcLo, &xmmAlphaSrcHi);
expandAlpha_2x128 (xmmDstLo, xmmDstHi, &xmmAlphaDstLo, &xmmAlphaDstHi);
pixMultiply_2x128 (xmmSrcLo, xmmSrcHi, xmmMaskLo, xmmMaskHi, &xmmSrcLo, &xmmSrcHi);
pixMultiply_2x128 (xmmMaskLo, xmmMaskHi, xmmAlphaSrcLo, xmmAlphaSrcHi, &xmmMaskLo, &xmmMaskHi);
pixMultiply_2x128 (&xmmSrcLo, &xmmSrcHi, &xmmMaskLo, &xmmMaskHi, &xmmSrcLo, &xmmSrcHi);
pixMultiply_2x128 (&xmmMaskLo, &xmmMaskHi, &xmmAlphaSrcLo, &xmmAlphaSrcHi, &xmmMaskLo, &xmmMaskHi);
negate_2x128 (xmmAlphaDstLo, xmmAlphaDstHi, &xmmAlphaDstLo, &xmmAlphaDstHi);
pixAddMultiply_2x128 (xmmDstLo, xmmDstHi, xmmMaskLo, xmmMaskHi,
xmmSrcLo, xmmSrcHi, xmmAlphaDstLo, xmmAlphaDstHi,
pixAddMultiply_2x128 (&xmmDstLo, &xmmDstHi, &xmmMaskLo, &xmmMaskHi,
&xmmSrcLo, &xmmSrcHi, &xmmAlphaDstLo, &xmmAlphaDstHi,
&xmmDstLo, &xmmDstHi);
save128Aligned( (__m128i*)pd, pack_2x128_128 (xmmDstLo, xmmDstHi));
@ -1923,10 +1928,14 @@ coreCombineXorCPixelsse2 (uint32_t src, uint32_t mask, uint32_t dst)
__m64 s = unpack_32_1x64 (src);
__m64 d = unpack_32_1x64 (dst);
return pack_1x64_32 (pixAddMultiply_1x64 (d,
negate_1x64 (pixMultiply_1x64 (a, expandAlpha_1x64 (s))),
pixMultiply_1x64 (s, a),
negate_1x64 (expandAlpha_1x64 (d))));
__m64 alphaDst = negate_1x64 (pixMultiply_1x64 (a, expandAlpha_1x64 (s)));
__m64 dest = pixMultiply_1x64 (s, a);
__m64 alphaSrc = negate_1x64 (expandAlpha_1x64 (d));
return pack_1x64_32 (pixAddMultiply_1x64 (&d,
&alphaDst,
&dest,
&alphaSrc));
}
static inline void
@ -1978,14 +1987,14 @@ coreCombineXorCsse2 (uint32_t *pd, uint32_t *ps, uint32_t *pm, int w)
expandAlpha_2x128 (xmmSrcLo, xmmSrcHi, &xmmAlphaSrcLo, &xmmAlphaSrcHi);
expandAlpha_2x128 (xmmDstLo, xmmDstHi, &xmmAlphaDstLo, &xmmAlphaDstHi);
pixMultiply_2x128 (xmmSrcLo, xmmSrcHi, xmmMaskLo, xmmMaskHi, &xmmSrcLo, &xmmSrcHi);
pixMultiply_2x128 (xmmMaskLo, xmmMaskHi, xmmAlphaSrcLo, xmmAlphaSrcHi, &xmmMaskLo, &xmmMaskHi);
pixMultiply_2x128 (&xmmSrcLo, &xmmSrcHi, &xmmMaskLo, &xmmMaskHi, &xmmSrcLo, &xmmSrcHi);
pixMultiply_2x128 (&xmmMaskLo, &xmmMaskHi, &xmmAlphaSrcLo, &xmmAlphaSrcHi, &xmmMaskLo, &xmmMaskHi);
negate_2x128 (xmmAlphaDstLo, xmmAlphaDstHi, &xmmAlphaDstLo, &xmmAlphaDstHi);
negate_2x128 (xmmMaskLo, xmmMaskHi, &xmmMaskLo, &xmmMaskHi);
pixAddMultiply_2x128 (xmmDstLo, xmmDstHi, xmmMaskLo, xmmMaskHi,
xmmSrcLo, xmmSrcHi, xmmAlphaDstLo, xmmAlphaDstHi,
pixAddMultiply_2x128 (&xmmDstLo, &xmmDstHi, &xmmMaskLo, &xmmMaskHi,
&xmmSrcLo, &xmmSrcHi, &xmmAlphaDstLo, &xmmAlphaDstHi,
&xmmDstLo, &xmmDstHi);
save128Aligned( (__m128i*)pd, pack_2x128_128 (xmmDstLo, xmmDstHi));
@ -2053,7 +2062,7 @@ coreCombineAddCsse2 (uint32_t *pd, uint32_t *ps, uint32_t *pm, int w)
unpack_128_2x128 (xmmMaskHi, &xmmMaskLo, &xmmMaskHi);
unpack_128_2x128 (xmmDstHi, &xmmDstLo, &xmmDstHi);
pixMultiply_2x128 (xmmSrcLo, xmmSrcHi, xmmMaskLo, xmmMaskHi, &xmmSrcLo, &xmmSrcHi);
pixMultiply_2x128 (&xmmSrcLo, &xmmSrcHi, &xmmMaskLo, &xmmMaskHi, &xmmSrcLo, &xmmSrcHi);
save128Aligned( (__m128i*)pd, pack_2x128_128 (_mm_adds_epu8 (xmmSrcLo, xmmDstLo),
_mm_adds_epu8 (xmmSrcHi, xmmDstHi)));
@ -2078,7 +2087,7 @@ coreCombineAddCsse2 (uint32_t *pd, uint32_t *ps, uint32_t *pm, int w)
}
/* -------------------------------------------------------------------------------------------------
* fbComposeSetupSSE
* fbComposeSetupSSE2
*/
static inline __m64
createMask_16_64 (uint16_t mask)
@ -2268,7 +2277,7 @@ sse2CombineAddC (uint32_t *dst, uint32_t *src, uint32_t *mask, int width)
}
void
fbComposeSetupSSE(void)
fbComposeSetupSSE2(void)
{
static pixman_bool_t initialized = FALSE;
@ -2276,7 +2285,7 @@ fbComposeSetupSSE(void)
return;
/* check if we have SSE2 support and initialize accordingly */
if (pixman_have_sse())
if (pixman_have_sse2())
{
/* SSE2 constants */
Mask565r = createMask_2x32_128 (0x00f80000, 0x00f80000);
@ -2404,7 +2413,7 @@ fbCompositeSolid_nx8888sse2 (pixman_op_t op,
unpack_128_2x128 (xmmDst, &xmmDstLo, &xmmDstHi);
over_2x128 (xmmSrc, xmmSrc, xmmAlpha, xmmAlpha, &xmmDstLo, &xmmDstHi);
over_2x128 (&xmmSrc, &xmmSrc, &xmmAlpha, &xmmAlpha, &xmmDstLo, &xmmDstHi);
/* rebuid the 4 pixel data and save*/
save128Aligned ((__m128i*)dst, pack_2x128_128 (xmmDstLo, xmmDstHi));
@ -2491,10 +2500,10 @@ fbCompositeSolid_nx0565sse2 (pixman_op_t op,
unpack565_128_4x128 (xmmDst, &xmmDst0, &xmmDst1, &xmmDst2, &xmmDst3);
over_2x128 (xmmSrc, xmmSrc, xmmAlpha, xmmAlpha, &xmmDst0, &xmmDst1);
over_2x128 (xmmSrc, xmmSrc, xmmAlpha, xmmAlpha, &xmmDst2, &xmmDst3);
over_2x128 (&xmmSrc, &xmmSrc, &xmmAlpha, &xmmAlpha, &xmmDst0, &xmmDst1);
over_2x128 (&xmmSrc, &xmmSrc, &xmmAlpha, &xmmAlpha, &xmmDst2, &xmmDst3);
xmmDst = pack565_4x128_128 (xmmDst0, xmmDst1, xmmDst2, xmmDst3);
xmmDst = pack565_4x128_128 (&xmmDst0, &xmmDst1, &xmmDst2, &xmmDst3);
save128Aligned ((__m128i*)dst, xmmDst);
@ -2542,6 +2551,8 @@ fbCompositeSolidMask_nx8888x8888Csse2 (pixman_op_t op,
__m128i xmmDst, xmmDstLo, xmmDstHi;
__m128i xmmMask, xmmMaskLo, xmmMaskHi;
__m64 mmxSrc, mmxAlpha, mmxMask, mmxDst;
fbComposeGetSolid(pSrc, src, pDst->bits.format);
srca = src >> 24;
@ -2553,6 +2564,8 @@ fbCompositeSolidMask_nx8888x8888Csse2 (pixman_op_t op,
xmmSrc = _mm_unpacklo_epi8 (createMask_2x32_128 (src, src), _mm_setzero_si128 ());
xmmAlpha = expandAlpha_1x128 (xmmSrc);
mmxSrc = _mm_movepi64_pi64 (xmmSrc);
mmxAlpha = _mm_movepi64_pi64 (xmmAlpha);
while (height--)
{
@ -2574,11 +2587,13 @@ fbCompositeSolidMask_nx8888x8888Csse2 (pixman_op_t op,
if (m)
{
d = *pd;
mmxMask = unpack_32_1x64 (m);
mmxDst = unpack_32_1x64 (d);
*pd = pack_1x64_32 (inOver_1x64 (_mm_movepi64_pi64 (xmmSrc),
_mm_movepi64_pi64 (xmmAlpha),
unpack_32_1x64 (m),
unpack_32_1x64 (d)));
*pd = pack_1x64_32 (inOver_1x64 (&mmxSrc,
&mmxAlpha,
&mmxMask,
&mmxDst));
}
pd++;
@ -2607,7 +2622,7 @@ fbCompositeSolidMask_nx8888x8888Csse2 (pixman_op_t op,
unpack_128_2x128 (xmmMask, &xmmMaskLo, &xmmMaskHi);
unpack_128_2x128 (xmmDst, &xmmDstLo, &xmmDstHi);
inOver_2x128 (xmmSrc, xmmSrc, xmmAlpha, xmmAlpha, xmmMaskLo, xmmMaskHi, &xmmDstLo, &xmmDstHi);
inOver_2x128 (&xmmSrc, &xmmSrc, &xmmAlpha, &xmmAlpha, &xmmMaskLo, &xmmMaskHi, &xmmDstLo, &xmmDstHi);
save128Aligned ((__m128i*)pd, pack_2x128_128 (xmmDstLo, xmmDstHi));
}
@ -2624,11 +2639,13 @@ fbCompositeSolidMask_nx8888x8888Csse2 (pixman_op_t op,
if (m)
{
d = *pd;
mmxMask = unpack_32_1x64 (m);
mmxDst = unpack_32_1x64 (d);
*pd = pack_1x64_32 (inOver_1x64 (_mm_movepi64_pi64 (xmmSrc),
_mm_movepi64_pi64 (xmmAlpha),
unpack_32_1x64 (m),
unpack_32_1x64 (d)));
*pd = pack_1x64_32 (inOver_1x64 (&mmxSrc,
&mmxAlpha,
&mmxMask,
&mmxDst));
}
pd++;
@ -2693,11 +2710,14 @@ fbCompositeSrc_8888x8x8888sse2 (pixman_op_t op,
uint32_t d = *dst;
__m64 ms = unpack_32_1x64 (s);
__m64 alpha = expandAlpha_1x64 (ms);
__m64 dest = _mm_movepi64_pi64 (xmmMask);
__m64 alphaDst = unpack_32_1x64 (d);
*dst++ = pack_1x64_32 (inOver_1x64 (ms,
expandAlpha_1x64 (ms),
_mm_movepi64_pi64 (xmmMask),
unpack_32_1x64 (d)));
*dst++ = pack_1x64_32 (inOver_1x64 (&ms,
&alpha,
&dest,
&alphaDst));
w--;
}
@ -2719,7 +2739,7 @@ fbCompositeSrc_8888x8x8888sse2 (pixman_op_t op,
unpack_128_2x128 (xmmDst, &xmmDstLo, &xmmDstHi);
expandAlpha_2x128 (xmmSrcLo, xmmSrcHi, &xmmAlphaLo, &xmmAlphaHi);
inOver_2x128 (xmmSrcLo, xmmSrcHi, xmmAlphaLo, xmmAlphaHi, xmmMask, xmmMask, &xmmDstLo, &xmmDstHi);
inOver_2x128 (&xmmSrcLo, &xmmSrcHi, &xmmAlphaLo, &xmmAlphaHi, &xmmMask, &xmmMask, &xmmDstLo, &xmmDstHi);
save128Aligned( (__m128i*)dst, pack_2x128_128 (xmmDstLo, xmmDstHi));
@ -2734,11 +2754,14 @@ fbCompositeSrc_8888x8x8888sse2 (pixman_op_t op,
uint32_t d = *dst;
__m64 ms = unpack_32_1x64 (s);
__m64 alpha = expandAlpha_1x64 (ms);
__m64 mask = _mm_movepi64_pi64 (xmmMask);
__m64 dest = unpack_32_1x64 (d);
*dst++ = pack_1x64_32 (inOver_1x64 (ms,
expandAlpha_1x64 (ms),
_mm_movepi64_pi64 (xmmMask),
unpack_32_1x64 (d)));
*dst++ = pack_1x64_32 (inOver_1x64 (&ms,
&alpha,
&mask,
&dest));
w--;
}
@ -2798,10 +2821,15 @@ fbCompositeSrc_x888xnx8888sse2 (pixman_op_t op,
uint32_t s = (*src++) | 0xff000000;
uint32_t d = *dst;
*dst++ = pack_1x64_32 (inOver_1x64 (unpack_32_1x64 (s),
_mm_movepi64_pi64 (xmmAlpha),
_mm_movepi64_pi64 (xmmMask),
unpack_32_1x64 (d)));
__m64 src = unpack_32_1x64 (s);
__m64 alpha = _mm_movepi64_pi64 (xmmAlpha);
__m64 mask = _mm_movepi64_pi64 (xmmMask);
__m64 dest = unpack_32_1x64 (d);
*dst++ = pack_1x64_32 (inOver_1x64 (&src,
&alpha,
&mask,
&dest));
w--;
}
@ -2822,7 +2850,7 @@ fbCompositeSrc_x888xnx8888sse2 (pixman_op_t op,
unpack_128_2x128 (xmmSrc, &xmmSrcLo, &xmmSrcHi);
unpack_128_2x128 (xmmDst, &xmmDstLo, &xmmDstHi);
inOver_2x128 (xmmSrcLo, xmmSrcHi, xmmAlpha, xmmAlpha, xmmMask, xmmMask, &xmmDstLo, &xmmDstHi);
inOver_2x128 (&xmmSrcLo, &xmmSrcHi, &xmmAlpha, &xmmAlpha, &xmmMask, &xmmMask, &xmmDstLo, &xmmDstHi);
save128Aligned( (__m128i*)dst, pack_2x128_128 (xmmDstLo, xmmDstHi));
@ -2837,10 +2865,15 @@ fbCompositeSrc_x888xnx8888sse2 (pixman_op_t op,
uint32_t s = (*src++) | 0xff000000;
uint32_t d = *dst;
*dst++ = pack_1x64_32 (inOver_1x64 (unpack_32_1x64 (s),
_mm_movepi64_pi64 (xmmAlpha),
_mm_movepi64_pi64 (xmmMask),
unpack_32_1x64 (d)));
__m64 src = unpack_32_1x64 (s);
__m64 alpha = _mm_movepi64_pi64 (xmmAlpha);
__m64 mask = _mm_movepi64_pi64 (xmmMask);
__m64 dest = unpack_32_1x64 (d);
*dst++ = pack_1x64_32 (inOver_1x64 (&src,
&alpha,
&mask,
&dest));
w--;
}
@ -2982,15 +3015,15 @@ fbCompositeSrc_8888x0565sse2 (pixman_op_t op,
/* I'm loading next 4 pixels from memory before to optimze the memory read. */
xmmSrc = load128Unaligned ((__m128i*) (src+4));
over_2x128 (xmmSrcLo, xmmSrcHi, xmmAlphaLo, xmmAlphaHi, &xmmDst0, &xmmDst1);
over_2x128 (&xmmSrcLo, &xmmSrcHi, &xmmAlphaLo, &xmmAlphaHi, &xmmDst0, &xmmDst1);
/* Unpacking */
unpack_128_2x128 (xmmSrc, &xmmSrcLo, &xmmSrcHi);
expandAlpha_2x128 (xmmSrcLo, xmmSrcHi, &xmmAlphaLo, &xmmAlphaHi);
over_2x128 (xmmSrcLo, xmmSrcHi, xmmAlphaLo, xmmAlphaHi, &xmmDst2, &xmmDst3);
over_2x128 (&xmmSrcLo, &xmmSrcHi, &xmmAlphaLo, &xmmAlphaHi, &xmmDst2, &xmmDst3);
save128Aligned ((__m128i*)dst, pack565_4x128_128 (xmmDst0, xmmDst1, xmmDst2, xmmDst3));
save128Aligned ((__m128i*)dst, pack565_4x128_128 (&xmmDst0, &xmmDst1, &xmmDst2, &xmmDst3));
w -= 8;
dst += 8;
@ -3038,6 +3071,8 @@ fbCompositeSolidMask_nx8x8888sse2 (pixman_op_t op,
__m128i xmmDst, xmmDstLo, xmmDstHi;
__m128i xmmMask, xmmMaskLo, xmmMaskHi;
__m64 mmxSrc, mmxAlpha, mmxMask, mmxDest;
fbComposeGetSolid(pSrc, src, pDst->bits.format);
srca = src >> 24;
@ -3050,6 +3085,8 @@ fbCompositeSolidMask_nx8x8888sse2 (pixman_op_t op,
xmmDef = createMask_2x32_128 (src, src);
xmmSrc = expandPixel_32_1x128 (src);
xmmAlpha = expandAlpha_1x128 (xmmSrc);
mmxSrc = _mm_movepi64_pi64 (xmmSrc);
mmxAlpha = _mm_movepi64_pi64 (xmmAlpha);
while (height--)
{
@ -3070,11 +3107,13 @@ fbCompositeSolidMask_nx8x8888sse2 (pixman_op_t op,
if (m)
{
d = *dst;
mmxMask = expandPixel_8_1x64 (m);
mmxDest = unpack_32_1x64 (d);
*dst = pack_1x64_32 (inOver_1x64 (_mm_movepi64_pi64 (xmmSrc),
_mm_movepi64_pi64 (xmmAlpha),
expandPixel_8_1x64 (m),
unpack_32_1x64 (d)));
*dst = pack_1x64_32 (inOver_1x64 (&mmxSrc,
&mmxAlpha,
&mmxMask,
&mmxDest));
}
w--;
@ -3109,7 +3148,7 @@ fbCompositeSolidMask_nx8x8888sse2 (pixman_op_t op,
expandAlphaRev_2x128 (xmmMaskLo, xmmMaskHi, &xmmMaskLo, &xmmMaskHi);
inOver_2x128 (xmmSrc, xmmSrc, xmmAlpha, xmmAlpha, xmmMaskLo, xmmMaskHi, &xmmDstLo, &xmmDstHi);
inOver_2x128 (&xmmSrc, &xmmSrc, &xmmAlpha, &xmmAlpha, &xmmMaskLo, &xmmMaskHi, &xmmDstLo, &xmmDstHi);
save128Aligned ((__m128i*)dst, pack_2x128_128 (xmmDstLo, xmmDstHi));
}
@ -3126,11 +3165,13 @@ fbCompositeSolidMask_nx8x8888sse2 (pixman_op_t op,
if (m)
{
d = *dst;
mmxMask = expandPixel_8_1x64 (m);
mmxDest = unpack_32_1x64 (d);
*dst = pack_1x64_32 (inOver_1x64 (_mm_movepi64_pi64 (xmmSrc),
_mm_movepi64_pi64 (xmmAlpha),
expandPixel_8_1x64 (m),
unpack_32_1x64 (d)));
*dst = pack_1x64_32 (inOver_1x64 (&mmxSrc,
&mmxAlpha,
&mmxMask,
&mmxDest));
}
w--;
@ -3378,7 +3419,7 @@ fbCompositeSolidMaskSrc_nx8x8888sse2 (pixman_op_t op,
expandAlphaRev_2x128 (xmmMaskLo, xmmMaskHi, &xmmMaskLo, &xmmMaskHi);
pixMultiply_2x128 (xmmSrc, xmmSrc, xmmMaskLo, xmmMaskHi, &xmmMaskLo, &xmmMaskHi);
pixMultiply_2x128 (&xmmSrc, &xmmSrc, &xmmMaskLo, &xmmMaskHi, &xmmMaskLo, &xmmMaskHi);
save128Aligned ((__m128i*)dst, pack_2x128_128 (xmmMaskLo, xmmMaskHi));
}
@ -3437,6 +3478,7 @@ fbCompositeSolidMask_nx8x0565sse2 (pixman_op_t op,
int dstStride, maskStride;
uint16_t w;
uint32_t m;
__m64 mmxSrc, mmxAlpha, mmxMask, mmxDest;
__m128i xmmSrc, xmmAlpha;
__m128i xmmMask, xmmMaskLo, xmmMaskHi;
@ -3453,6 +3495,8 @@ fbCompositeSolidMask_nx8x0565sse2 (pixman_op_t op,
xmmSrc = expandPixel_32_1x128 (src);
xmmAlpha = expandAlpha_1x128 (xmmSrc);
mmxSrc = _mm_movepi64_pi64 (xmmSrc);
mmxAlpha = _mm_movepi64_pi64 (xmmAlpha);
while (height--)
{
@ -3473,11 +3517,13 @@ fbCompositeSolidMask_nx8x0565sse2 (pixman_op_t op,
if (m)
{
d = *dst;
mmxMask = expandAlphaRev_1x64 (unpack_32_1x64 (m));
mmxDest = expand565_16_1x64 (d);
*dst = pack565_32_16 (pack_1x64_32 (inOver_1x64 (_mm_movepi64_pi64 (xmmSrc),
_mm_movepi64_pi64 (xmmAlpha),
expandAlphaRev_1x64 (unpack_32_1x64 (m)),
expand565_16_1x64 (d))));
*dst = pack565_32_16 (pack_1x64_32 (inOver_1x64 (&mmxSrc,
&mmxAlpha,
&mmxMask,
&mmxDest)));
}
w--;
@ -3509,7 +3555,7 @@ fbCompositeSolidMask_nx8x0565sse2 (pixman_op_t op,
unpack_128_2x128 (xmmMask, &xmmMaskLo, &xmmMaskHi);
expandAlphaRev_2x128 (xmmMaskLo, xmmMaskHi, &xmmMaskLo, &xmmMaskHi);
inOver_2x128 (xmmSrc, xmmSrc, xmmAlpha, xmmAlpha, xmmMaskLo, xmmMaskHi, &xmmDst0, &xmmDst1);
inOver_2x128 (&xmmSrc, &xmmSrc, &xmmAlpha, &xmmAlpha, &xmmMaskLo, &xmmMaskHi, &xmmDst0, &xmmDst1);
}
m = *((uint32_t*)mask);
@ -3524,10 +3570,10 @@ fbCompositeSolidMask_nx8x0565sse2 (pixman_op_t op,
unpack_128_2x128 (xmmMask, &xmmMaskLo, &xmmMaskHi);
expandAlphaRev_2x128 (xmmMaskLo, xmmMaskHi, &xmmMaskLo, &xmmMaskHi);
inOver_2x128 (xmmSrc, xmmSrc, xmmAlpha, xmmAlpha, xmmMaskLo, xmmMaskHi, &xmmDst2, &xmmDst3);
inOver_2x128 (&xmmSrc, &xmmSrc, &xmmAlpha, &xmmAlpha, &xmmMaskLo, &xmmMaskHi, &xmmDst2, &xmmDst3);
}
save128Aligned ((__m128i*)dst, pack565_4x128_128 (xmmDst0, xmmDst1, xmmDst2, xmmDst3));
save128Aligned ((__m128i*)dst, pack565_4x128_128 (&xmmDst0, &xmmDst1, &xmmDst2, &xmmDst3));
w -= 8;
dst += 8;
@ -3540,11 +3586,13 @@ fbCompositeSolidMask_nx8x0565sse2 (pixman_op_t op,
if (m)
{
d = *dst;
mmxMask = expandAlphaRev_1x64 (unpack_32_1x64 (m));
mmxDest = expand565_16_1x64 (d);
*dst = pack565_32_16 (pack_1x64_32 (inOver_1x64 (_mm_movepi64_pi64 (xmmSrc),
_mm_movepi64_pi64 (xmmAlpha),
expandAlphaRev_1x64 (unpack_32_1x64 (m)),
expand565_16_1x64 (d))));
*dst = pack565_32_16 (pack_1x64_32 (inOver_1x64 (&mmxSrc,
&mmxAlpha,
&mmxMask,
&mmxDest)));
}
w--;
@ -3664,7 +3712,7 @@ fbCompositeSrc_8888RevNPx0565sse2 (pixman_op_t op,
overRevNonPre_2x128 (xmmSrcLo, xmmSrcHi, &xmmDst2, &xmmDst3);
}
save128Aligned ((__m128i*)dst, pack565_4x128_128 (xmmDst0, xmmDst1, xmmDst2, xmmDst3));
save128Aligned ((__m128i*)dst, pack565_4x128_128 (&xmmDst0, &xmmDst1, &xmmDst2, &xmmDst3));
w -= 8;
src += 8;
@ -3830,6 +3878,8 @@ fbCompositeSolidMask_nx8888x0565Csse2 (pixman_op_t op,
__m128i xmmMask, xmmMaskLo, xmmMaskHi;
__m128i xmmDst, xmmDst0, xmmDst1, xmmDst2, xmmDst3;
__m64 mmxSrc, mmxAlpha, mmxMask, mmxDest;
fbComposeGetSolid(pSrc, src, pDst->bits.format);
srca = src >> 24;
@ -3841,6 +3891,8 @@ fbCompositeSolidMask_nx8888x0565Csse2 (pixman_op_t op,
xmmSrc = expandPixel_32_1x128 (src);
xmmAlpha = expandAlpha_1x128 (xmmSrc);
mmxSrc = _mm_movepi64_pi64 (xmmSrc);
mmxAlpha = _mm_movepi64_pi64 (xmmAlpha);
while (height--)
{
@ -3861,11 +3913,13 @@ fbCompositeSolidMask_nx8888x0565Csse2 (pixman_op_t op,
if (m)
{
d = *dst;
mmxMask = unpack_32_1x64 (m);
mmxDest = expand565_16_1x64 (d);
*dst = pack565_32_16 (pack_1x64_32 (inOver_1x64 (_mm_movepi64_pi64 (xmmSrc),
_mm_movepi64_pi64 (xmmAlpha),
unpack_32_1x64 (m),
expand565_16_1x64 (d))));
*dst = pack565_32_16 (pack_1x64_32 (inOver_1x64 (&mmxSrc,
&mmxAlpha,
&mmxMask,
&mmxDest)));
}
w--;
@ -3898,7 +3952,7 @@ fbCompositeSolidMask_nx8888x0565Csse2 (pixman_op_t op,
if (packCmp != 0xffff)
{
inOver_2x128(xmmSrc, xmmSrc, xmmAlpha, xmmAlpha, xmmMaskLo, xmmMaskHi, &xmmDst0, &xmmDst1);
inOver_2x128(&xmmSrc, &xmmSrc, &xmmAlpha, &xmmAlpha, &xmmMaskLo, &xmmMaskHi, &xmmDst0, &xmmDst1);
}
/* Second round */
@ -3908,10 +3962,10 @@ fbCompositeSolidMask_nx8888x0565Csse2 (pixman_op_t op,
if (packCmp != 0xffff)
{
inOver_2x128(xmmSrc, xmmSrc, xmmAlpha, xmmAlpha, xmmMaskLo, xmmMaskHi, &xmmDst2, &xmmDst3);
inOver_2x128(&xmmSrc, &xmmSrc, &xmmAlpha, &xmmAlpha, &xmmMaskLo, &xmmMaskHi, &xmmDst2, &xmmDst3);
}
save128Aligned ((__m128i*)dst, pack565_4x128_128 (xmmDst0, xmmDst1, xmmDst2, xmmDst3));
save128Aligned ((__m128i*)dst, pack565_4x128_128 (&xmmDst0, &xmmDst1, &xmmDst2, &xmmDst3));
w -= 8;
dst += 8;
@ -3925,11 +3979,13 @@ fbCompositeSolidMask_nx8888x0565Csse2 (pixman_op_t op,
if (m)
{
d = *dst;
mmxMask = unpack_32_1x64 (m);
mmxDest = expand565_16_1x64 (d);
*dst = pack565_32_16 (pack_1x64_32 (inOver_1x64 (_mm_movepi64_pi64 (xmmSrc),
_mm_movepi64_pi64 (xmmAlpha),
unpack_32_1x64 (m),
expand565_16_1x64 (d))));
*dst = pack565_32_16 (pack_1x64_32 (inOver_1x64 (&mmxSrc,
&mmxAlpha,
&mmxMask,
&mmxDest)));
}
w--;
@ -4019,8 +4075,8 @@ fbCompositeIn_nx8x8sse2 (pixman_op_t op,
unpack_128_2x128 (xmmMask, &xmmMaskLo, &xmmMaskHi);
unpack_128_2x128 (xmmDst, &xmmDstLo, &xmmDstHi);
pixMultiply_2x128 (xmmAlpha, xmmAlpha, xmmMaskLo, xmmMaskHi, &xmmMaskLo, &xmmMaskHi);
pixMultiply_2x128 (xmmMaskLo, xmmMaskHi, xmmDstLo, xmmDstHi, &xmmDstLo, &xmmDstHi);
pixMultiply_2x128 (&xmmAlpha, &xmmAlpha, &xmmMaskLo, &xmmMaskHi, &xmmMaskLo, &xmmMaskHi);
pixMultiply_2x128 (&xmmMaskLo, &xmmMaskHi, &xmmDstLo, &xmmDstHi, &xmmDstLo, &xmmDstHi);
save128Aligned ((__m128i*)dst, pack_2x128_128 (xmmDstLo, xmmDstHi));
@ -4110,7 +4166,7 @@ fbCompositeIn_8x8sse2 (pixman_op_t op,
unpack_128_2x128 (xmmSrc, &xmmSrcLo, &xmmSrcHi);
unpack_128_2x128 (xmmDst, &xmmDstLo, &xmmDstHi);
pixMultiply_2x128 (xmmSrcLo, xmmSrcHi, xmmDstLo, xmmDstHi, &xmmDstLo, &xmmDstHi);
pixMultiply_2x128 (&xmmSrcLo, &xmmSrcHi, &xmmDstLo, &xmmDstHi, &xmmDstLo, &xmmDstHi);
save128Aligned ((__m128i*)dst, pack_2x128_128 (xmmDstLo, xmmDstHi));
@ -4211,7 +4267,7 @@ fbCompositeSrcAdd_8888x8x8sse2 (pixman_op_t op,
unpack_128_2x128 (xmmMask, &xmmMaskLo, &xmmMaskHi);
unpack_128_2x128 (xmmDst, &xmmDstLo, &xmmDstHi);
pixMultiply_2x128 (xmmAlpha, xmmAlpha, xmmMaskLo, xmmMaskHi, &xmmMaskLo, &xmmMaskHi);
pixMultiply_2x128 (&xmmAlpha, &xmmAlpha, &xmmMaskLo, &xmmMaskHi, &xmmMaskLo, &xmmMaskHi);
xmmDstLo = _mm_adds_epu16 (xmmMaskLo, xmmDstLo);
xmmDstHi = _mm_adds_epu16 (xmmMaskHi, xmmDstHi);

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

@ -38,18 +38,18 @@
#ifdef USE_SSE2
#if !defined(__amd64__) && !defined(__x86_64__)
pixman_bool_t pixman_have_sse(void);
pixman_bool_t pixman_have_sse2(void);
#else
#define pixman_have_sse() TRUE
#define pixman_have_sse2() TRUE
#endif
#else
#define pixman_have_sse() FALSE
#define pixman_have_sse2() FALSE
#endif
#ifdef USE_SSE2
void fbComposeSetupSSE(void);
void fbComposeSetupSSE2(void);
pixman_bool_t
pixmanFillsse2 (uint32_t *bits,

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

@ -537,6 +537,8 @@ pixman_format_supported_source (pixman_format_code_t format)
{
switch (format) {
/* 32 bpp formats */
case PIXMAN_a2b10g10r10:
case PIXMAN_x2b10g10r10:
case PIXMAN_a8r8g8b8:
case PIXMAN_x8r8g8b8:
case PIXMAN_a8b8g8r8:

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

@ -33,9 +33,9 @@
#define PIXMAN_VERSION_MAJOR 0
#define PIXMAN_VERSION_MINOR 11
#define PIXMAN_VERSION_MICRO 7
#define PIXMAN_VERSION_MICRO 9
#define PIXMAN_VERSION_STRING "0.11.7"
#define PIXMAN_VERSION_STRING "0.11.9"
#define PIXMAN_VERSION_ENCODE(major, minor, micro) ( \
((major) * 10000) \

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

@ -85,6 +85,8 @@ typedef __int32 int32_t;
typedef unsigned __int32 uint32_t;
typedef __int64 int64_t;
typedef unsigned __int64 uint64_t;
#elif defined (_AIX)
# include <sys/inttypes.h>
#else
# include <stdint.h>
#endif