зеркало из https://github.com/mozilla/gecko-dev.git
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:
Родитель
edf086ccfa
Коммит
fb36f5d923
|
@ -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, ®ion);
|
||||
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, ®ion, 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,
|
||||
* &glyphs, &num_glyphs,
|
||||
* &clusters, &num_clusters,
|
||||
* &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,
|
||||
* &glyphs, &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,
|
||||
* &glyphs, &num_glyphs,
|
||||
* &clusters, &num_clusters,
|
||||
* &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
|
||||
|
|
Загрузка…
Ссылка в новой задаче