зеркало из https://github.com/mozilla/gecko-dev.git
b=354388, Update cairo to cairo 2006-09-26 trunk, r=me
This commit is contained in:
Родитель
fe0ff2999b
Коммит
aa06e7a53f
|
@ -1,312 +0,0 @@
|
|||
Index: gfx/cairo/cairo/src/cairo.h
|
||||
===================================================================
|
||||
RCS file: /home/rocallahan/mozilla-cvs-mirror/mozilla/gfx/cairo/cairo/src/cairo.h,v
|
||||
retrieving revision 1.9
|
||||
diff -u -t -p -1 -2 -r1.9 cairo.h
|
||||
--- gfx/cairo/cairo/src/cairo.h 10 Feb 2006 02:20:34 -0000 1.9
|
||||
+++ gfx/cairo/cairo/src/cairo.h 21 Feb 2006 23:17:08 -0000
|
||||
@@ -1129,24 +1129,42 @@ cairo_public cairo_path_t *
|
||||
cairo_copy_path (cairo_t *cr);
|
||||
|
||||
cairo_public cairo_path_t *
|
||||
cairo_copy_path_flat (cairo_t *cr);
|
||||
|
||||
cairo_public void
|
||||
cairo_append_path (cairo_t *cr,
|
||||
cairo_path_t *path);
|
||||
|
||||
cairo_public void
|
||||
cairo_path_destroy (cairo_path_t *path);
|
||||
|
||||
+/**
|
||||
+ * cairo_clip_rect_t:
|
||||
+ *
|
||||
+ * A data structure for holding clip rectangles.
|
||||
+ */
|
||||
+typedef struct _cairo_clip_rect {
|
||||
+ double x, y, width, height;
|
||||
+} cairo_clip_rect_t;
|
||||
+
|
||||
+cairo_public cairo_bool_t
|
||||
+cairo_has_clip (cairo_t *cr);
|
||||
+
|
||||
+cairo_public cairo_bool_t
|
||||
+cairo_extract_clip_rectangles (cairo_t *cr,
|
||||
+ int max_rectangles,
|
||||
+ cairo_clip_rect_t *rectangles_out,
|
||||
+ int *num_rectangles_out);
|
||||
+
|
||||
/* Error status queries */
|
||||
|
||||
cairo_public cairo_status_t
|
||||
cairo_status (cairo_t *cr);
|
||||
|
||||
cairo_public const char *
|
||||
cairo_status_to_string (cairo_status_t status);
|
||||
|
||||
/* Surface manipulation */
|
||||
|
||||
cairo_public cairo_surface_t *
|
||||
cairo_surface_create_similar (cairo_surface_t *other,
|
||||
Index: gfx/cairo/cairo/src/cairoint.h
|
||||
===================================================================
|
||||
RCS file: /home/rocallahan/mozilla-cvs-mirror/mozilla/gfx/cairo/cairo/src/cairoint.h,v
|
||||
retrieving revision 1.19
|
||||
diff -u -t -p -1 -2 -r1.19 cairoint.h
|
||||
--- gfx/cairo/cairo/src/cairoint.h 10 Feb 2006 02:51:12 -0000 1.19
|
||||
+++ gfx/cairo/cairo/src/cairoint.h 21 Feb 2006 23:18:00 -0000
|
||||
@@ -1229,24 +1229,33 @@ cairo_private cairo_status_t
|
||||
_cairo_gstate_in_fill (cairo_gstate_t *gstate,
|
||||
cairo_path_fixed_t *path,
|
||||
double x,
|
||||
double y,
|
||||
cairo_bool_t *inside_ret);
|
||||
|
||||
cairo_private cairo_status_t
|
||||
_cairo_gstate_clip (cairo_gstate_t *gstate, cairo_path_fixed_t *path);
|
||||
|
||||
cairo_private cairo_status_t
|
||||
_cairo_gstate_reset_clip (cairo_gstate_t *gstate);
|
||||
|
||||
+cairo_private cairo_bool_t
|
||||
+_cairo_gstate_has_clip (cairo_gstate_t *gstate);
|
||||
+
|
||||
+cairo_private cairo_bool_t
|
||||
+_cairo_gstate_extract_clip_rectangles (cairo_gstate_t *gstate,
|
||||
+ int max_rectangles,
|
||||
+ cairo_clip_rect_t *rectangles_out,
|
||||
+ int *num_rectangles_out);
|
||||
+
|
||||
cairo_private cairo_status_t
|
||||
_cairo_gstate_show_surface (cairo_gstate_t *gstate,
|
||||
cairo_surface_t *surface,
|
||||
double x,
|
||||
double y,
|
||||
double width,
|
||||
double height);
|
||||
|
||||
cairo_private cairo_status_t
|
||||
_cairo_gstate_select_font_face (cairo_gstate_t *gstate,
|
||||
const char *family,
|
||||
cairo_font_slant_t slant,
|
||||
Index: gfx/cairo/cairo/src/cairo-clip-private.h
|
||||
===================================================================
|
||||
RCS file: /home/rocallahan/mozilla-cvs-mirror/mozilla/gfx/cairo/cairo/src/cairo-clip-private.h,v
|
||||
retrieving revision 1.2
|
||||
diff -u -t -p -1 -2 -r1.2 cairo-clip-private.h
|
||||
--- gfx/cairo/cairo/src/cairo-clip-private.h 10 Jan 2006 22:56:38 -0000 1.2
|
||||
+++ gfx/cairo/cairo/src/cairo-clip-private.h 7 Feb 2006 22:44:42 -0000
|
||||
@@ -105,13 +105,22 @@ _cairo_clip_intersect_to_rectangle (cair
|
||||
cairo_private cairo_status_t
|
||||
_cairo_clip_intersect_to_region (cairo_clip_t *clip,
|
||||
pixman_region16_t *region);
|
||||
|
||||
cairo_private cairo_status_t
|
||||
_cairo_clip_combine_to_surface (cairo_clip_t *clip,
|
||||
cairo_operator_t op,
|
||||
cairo_surface_t *dst,
|
||||
int dst_x,
|
||||
int dst_y,
|
||||
const cairo_rectangle_t *extents);
|
||||
|
||||
+cairo_private cairo_bool_t
|
||||
+_cairo_clip_has_clip (cairo_clip_t *clip);
|
||||
+
|
||||
+cairo_private cairo_bool_t
|
||||
+_cairo_clip_extract_rectangles (cairo_clip_t *clip,
|
||||
+ int max_rectangles,
|
||||
+ cairo_clip_rect_t *rectangles_out,
|
||||
+ int *num_rectangles_out);
|
||||
+
|
||||
#endif /* CAIRO_CLIP_PRIVATE_H */
|
||||
Index: gfx/cairo/cairo/src/cairo-clip.c
|
||||
===================================================================
|
||||
RCS file: /home/rocallahan/mozilla-cvs-mirror/mozilla/gfx/cairo/cairo/src/cairo-clip.c,v
|
||||
retrieving revision 1.3
|
||||
diff -u -t -p -1 -2 -r1.3 cairo-clip.c
|
||||
--- gfx/cairo/cairo/src/cairo-clip.c 10 Jan 2006 22:56:38 -0000 1.3
|
||||
+++ gfx/cairo/cairo/src/cairo-clip.c 21 Feb 2006 23:19:34 -0000
|
||||
@@ -450,12 +450,62 @@ _cairo_clip_clip (cairo_clip_t *cl
|
||||
|
||||
status = _cairo_clip_intersect_region (clip, &traps, target);
|
||||
if (status != CAIRO_INT_STATUS_UNSUPPORTED)
|
||||
goto bail;
|
||||
|
||||
status = _cairo_clip_intersect_mask (clip, &traps, antialias, target);
|
||||
|
||||
bail:
|
||||
_cairo_traps_fini (&traps);
|
||||
|
||||
return status;
|
||||
}
|
||||
+
|
||||
+cairo_bool_t
|
||||
+_cairo_clip_has_clip (cairo_clip_t *clip)
|
||||
+{
|
||||
+ return clip->region != NULL || clip->surface != NULL || clip->path != NULL;
|
||||
+}
|
||||
+
|
||||
+static cairo_bool_t
|
||||
+_cairo_region_to_clip_rectangles (pixman_region16_t *region,
|
||||
+ int max_rectangles,
|
||||
+ cairo_clip_rect_t *rectangles_out,
|
||||
+ int *num_rectangles_out)
|
||||
+{
|
||||
+ int n_boxes, i;
|
||||
+ pixman_box16_t *boxes;
|
||||
+
|
||||
+ /* no region -> we can't represent it as rectangles */
|
||||
+ if (region == NULL)
|
||||
+ return FALSE;
|
||||
+
|
||||
+ n_boxes = pixman_region_num_rects (region);
|
||||
+ *num_rectangles_out = n_boxes;
|
||||
+ if (n_boxes > max_rectangles)
|
||||
+ return FALSE;
|
||||
+
|
||||
+ boxes = pixman_region_rects (region);
|
||||
+
|
||||
+ for (i = 0; i < n_boxes; i++) {
|
||||
+ rectangles_out[i].x = boxes[i].x1;
|
||||
+ rectangles_out[i].y = boxes[i].y1;
|
||||
+ rectangles_out[i].width = boxes[i].x2 - boxes[i].x1;
|
||||
+ rectangles_out[i].height = boxes[i].y2 - boxes[i].y1;
|
||||
+ }
|
||||
+
|
||||
+ return TRUE;
|
||||
+}
|
||||
+
|
||||
+cairo_bool_t
|
||||
+_cairo_clip_extract_rectangles (cairo_clip_t *clip,
|
||||
+ int max_rectangles,
|
||||
+ cairo_clip_rect_t *rectangles_out,
|
||||
+ int *num_rectangles_out)
|
||||
+{
|
||||
+ /* can't handle paths or surfaces for now */
|
||||
+ if (clip->path != NULL || clip->surface != NULL)
|
||||
+ return FALSE;
|
||||
+
|
||||
+ return _cairo_region_to_clip_rectangles (clip->region,
|
||||
+ max_rectangles, rectangles_out, num_rectangles_out);
|
||||
+}
|
||||
Index: gfx/cairo/cairo/src/cairo-gstate.c
|
||||
===================================================================
|
||||
RCS file: /home/rocallahan/mozilla-cvs-mirror/mozilla/gfx/cairo/cairo/src/cairo-gstate.c,v
|
||||
retrieving revision 1.4
|
||||
diff -u -t -p -1 -2 -r1.4 cairo-gstate.c
|
||||
--- gfx/cairo/cairo/src/cairo-gstate.c 10 Jan 2006 22:56:38 -0000 1.4
|
||||
+++ gfx/cairo/cairo/src/cairo-gstate.c 21 Feb 2006 23:18:13 -0000
|
||||
@@ -1174,24 +1174,42 @@ _cairo_gstate_reset_clip (cairo_gstate_t
|
||||
{
|
||||
return _cairo_clip_reset (&gstate->clip);
|
||||
}
|
||||
|
||||
cairo_status_t
|
||||
_cairo_gstate_clip (cairo_gstate_t *gstate, cairo_path_fixed_t *path)
|
||||
{
|
||||
return _cairo_clip_clip (&gstate->clip,
|
||||
path, gstate->fill_rule, gstate->tolerance,
|
||||
gstate->antialias, gstate->target);
|
||||
}
|
||||
|
||||
+cairo_bool_t
|
||||
+_cairo_gstate_has_clip (cairo_gstate_t *gstate)
|
||||
+{
|
||||
+ return _cairo_clip_has_clip (&gstate->clip);
|
||||
+}
|
||||
+
|
||||
+cairo_bool_t
|
||||
+_cairo_gstate_extract_clip_rectangles (cairo_gstate_t *gstate,
|
||||
+ int max_rectangles,
|
||||
+ cairo_clip_rect_t *rectangles_out,
|
||||
+ int *num_rectangles_out)
|
||||
+{
|
||||
+ return _cairo_clip_extract_rectangles (&gstate->clip,
|
||||
+ max_rectangles,
|
||||
+ rectangles_out,
|
||||
+ num_rectangles_out);
|
||||
+}
|
||||
+
|
||||
static void
|
||||
_cairo_gstate_unset_scaled_font (cairo_gstate_t *gstate)
|
||||
{
|
||||
if (gstate->scaled_font) {
|
||||
cairo_scaled_font_destroy (gstate->scaled_font);
|
||||
gstate->scaled_font = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
cairo_status_t
|
||||
_cairo_gstate_select_font_face (cairo_gstate_t *gstate,
|
||||
const char *family,
|
||||
Index: gfx/cairo/cairo/src/cairo.c
|
||||
===================================================================
|
||||
RCS file: /home/rocallahan/mozilla-cvs-mirror/mozilla/gfx/cairo/cairo/src/cairo.c,v
|
||||
retrieving revision 1.11
|
||||
diff -u -t -p -1 -2 -r1.11 cairo.c
|
||||
--- gfx/cairo/cairo/src/cairo.c 10 Feb 2006 02:56:14 -0000 1.11
|
||||
+++ gfx/cairo/cairo/src/cairo.c 21 Feb 2006 23:17:34 -0000
|
||||
@@ -2575,24 +2575,63 @@ cairo_get_group_target (cairo_t *cr)
|
||||
* with it.
|
||||
**/
|
||||
cairo_path_t *
|
||||
cairo_copy_path (cairo_t *cr)
|
||||
{
|
||||
if (cr->status)
|
||||
return (cairo_path_t*) &_cairo_path_nil;
|
||||
|
||||
return _cairo_path_data_create (&cr->path, cr->gstate);
|
||||
}
|
||||
|
||||
/**
|
||||
+ * cairo_has_clip
|
||||
+ * @cr: a cairo context
|
||||
+ *
|
||||
+ * Returns TRUE if the cairo context has any clipping active, otherwise
|
||||
+ * FALSE.
|
||||
+ */
|
||||
+cairo_bool_t
|
||||
+cairo_has_clip (cairo_t *cr)
|
||||
+{
|
||||
+ if (cr->status)
|
||||
+ return FALSE;
|
||||
+ return _cairo_gstate_has_clip (cr->gstate);
|
||||
+}
|
||||
+
|
||||
+/**
|
||||
+ * cairo_extract_clip_rectangles
|
||||
+ * @cr: a cairo context
|
||||
+ * @max_rectangles: the maximum number of rectangles to be returned
|
||||
+ * @rectangles_out: the output buffer for the rectangles
|
||||
+ * @num_rectangles_out: the number of rectangles returned
|
||||
+ *
|
||||
+ * If the current clip can be expressed as the union of at most
|
||||
+ * 'max_rectangles' device-coordinate rectangles, then we fill in the array
|
||||
+ * with the rectangles, and return True. Otherwise we return False. When there
|
||||
+ * is no clipping active, we return False.
|
||||
+ */
|
||||
+cairo_bool_t
|
||||
+cairo_extract_clip_rectangles (cairo_t *cr,
|
||||
+ int max_rectangles,
|
||||
+ cairo_clip_rect_t *rectangles_out,
|
||||
+ int *num_rectangles_out)
|
||||
+{
|
||||
+ if (cr->status)
|
||||
+ return FALSE;
|
||||
+ return _cairo_gstate_extract_clip_rectangles (cr->gstate, max_rectangles,
|
||||
+ rectangles_out, num_rectangles_out);
|
||||
+}
|
||||
+
|
||||
+/**
|
||||
* cairo_copy_path_flat:
|
||||
* @cr: a cairo context
|
||||
*
|
||||
* Gets a flattened copy of the current path and returns it to the
|
||||
* user as a #cairo_path_t. See #cairo_path_data_t for hints on
|
||||
* how to iterate over the returned data structure.
|
||||
*
|
||||
* This function is like cairo_copy_path() except that any curves
|
||||
* in the path will be approximated with piecewise-linear
|
||||
* approximations, (accurate to within the current tolerance
|
||||
* value). That is, the result is guaranteed to not have any elements
|
||||
* of type %CAIRO_PATH_CURVE_TO which will instead be replaced by a
|
|
@ -1,245 +0,0 @@
|
|||
Index: src/cairo-debug.c
|
||||
===================================================================
|
||||
--- src/cairo-debug.c.orig
|
||||
+++ src/cairo-debug.c
|
||||
@@ -35,6 +35,8 @@
|
||||
|
||||
#include "cairoint.h"
|
||||
|
||||
+#include "cairo-clip-private.h"
|
||||
+
|
||||
/**
|
||||
* cairo_debug_reset_static_data:
|
||||
*
|
||||
@@ -70,3 +72,192 @@ cairo_debug_reset_static_data (void)
|
||||
#endif
|
||||
}
|
||||
|
||||
+/*
|
||||
+ * clip dumper
|
||||
+ */
|
||||
+void
|
||||
+cairo_debug_dump_clip (struct _cairo_clip *clip,
|
||||
+ FILE *fp)
|
||||
+{
|
||||
+ fprintf (fp, "clip %p: %s ", (clip->mode == CAIRO_CLIP_MODE_PATH ? "PATH" :
|
||||
+ clip->mode == CAIRO_CLIP_MODE_REGION ? "REGION" :
|
||||
+ clip->mode == CAIRO_CLIP_MODE_MASK ? "MASK" :
|
||||
+ "INVALID?!"));
|
||||
+ if (clip->mode == CAIRO_CLIP_MODE_PATH) {
|
||||
+ fprintf (fp, "\n=== clip path ===\n");
|
||||
+ } else if (clip->mode == CAIRO_CLIP_MODE_REGION) {
|
||||
+ if (!clip->region) {
|
||||
+ fprintf (fp, "region = NULL");
|
||||
+ } else if (pixman_region_num_rects (clip->region) == 1) {
|
||||
+ pixman_box16_t *rects = pixman_region_rects (clip->region);
|
||||
+ fprintf (fp, "region [%d %d %d %d]",
|
||||
+ rects[0].x1, rects[0].y1,
|
||||
+ rects[0].x2, rects[0].y2);
|
||||
+ } else {
|
||||
+ pixman_box16_t *rects = pixman_region_rects (clip->region);
|
||||
+ int i, nr = pixman_region_num_rects(clip->region);
|
||||
+ fprintf (fp, "region (%d rects)\n", nr);
|
||||
+ for (i = 0; i < nr; i++) {
|
||||
+ fprintf (fp, "rect %d: [%d %d %d %d]", i,
|
||||
+ rects[nr].x1, rects[nr].y1,
|
||||
+ rects[nr].x2, rects[nr].y2);
|
||||
+ }
|
||||
+ }
|
||||
+ } else if (clip->mode == CAIRO_CLIP_MODE_MASK) {
|
||||
+ fprintf (fp, "mask, surface: %p rect: [%d %d %d %d]", clip->surface,
|
||||
+ clip->surface_rect.x, clip->surface_rect.y, clip->surface_rect.width, clip->surface_rect.height);
|
||||
+ }
|
||||
+
|
||||
+ fprintf (fp, "\n");
|
||||
+}
|
||||
+
|
||||
+/*
|
||||
+ * path dumper
|
||||
+ */
|
||||
+
|
||||
+typedef struct _cairo_debug_path_dump_closure {
|
||||
+ unsigned int op_count;
|
||||
+ FILE *fp;
|
||||
+} cairo_debug_path_dump_closure_t;
|
||||
+
|
||||
+static cairo_status_t
|
||||
+_cairo_debug_path_move_to (void *closure,
|
||||
+ cairo_point_t *point)
|
||||
+{
|
||||
+ cairo_debug_path_dump_closure_t *fdc =
|
||||
+ (cairo_debug_path_dump_closure_t*) closure;
|
||||
+ fprintf (fdc->fp, "%d: moveto (%f, %f)\n",
|
||||
+ fdc->op_count++,
|
||||
+ _cairo_fixed_to_double(point->x),
|
||||
+ _cairo_fixed_to_double(point->y));
|
||||
+ return CAIRO_STATUS_SUCCESS;
|
||||
+}
|
||||
+
|
||||
+static cairo_status_t
|
||||
+_cairo_debug_path_line_to (void *closure,
|
||||
+ cairo_point_t *point)
|
||||
+{
|
||||
+ cairo_debug_path_dump_closure_t *fdc =
|
||||
+ (cairo_debug_path_dump_closure_t*) closure;
|
||||
+ fprintf (fdc->fp, "%d: lineto (%f, %f)\n",
|
||||
+ fdc->op_count++,
|
||||
+ _cairo_fixed_to_double(point->x),
|
||||
+ _cairo_fixed_to_double(point->y));
|
||||
+ return CAIRO_STATUS_SUCCESS;
|
||||
+}
|
||||
+
|
||||
+static cairo_status_t
|
||||
+_cairo_debug_path_curve_to (void *closure,
|
||||
+ cairo_point_t *p0,
|
||||
+ cairo_point_t *p1,
|
||||
+ cairo_point_t *p2)
|
||||
+{
|
||||
+ cairo_debug_path_dump_closure_t *fdc =
|
||||
+ (cairo_debug_path_dump_closure_t*) closure;
|
||||
+ fprintf (fdc->fp, "%d: curveto (%f, %f) (%f, %f) (%f, %f)\n",
|
||||
+ fdc->op_count++,
|
||||
+ _cairo_fixed_to_double(p0->x),
|
||||
+ _cairo_fixed_to_double(p0->y),
|
||||
+ _cairo_fixed_to_double(p1->x),
|
||||
+ _cairo_fixed_to_double(p1->y),
|
||||
+ _cairo_fixed_to_double(p2->x),
|
||||
+ _cairo_fixed_to_double(p2->y));
|
||||
+ return CAIRO_STATUS_SUCCESS;
|
||||
+}
|
||||
+
|
||||
+static cairo_status_t
|
||||
+_cairo_debug_path_close_path (void *closure)
|
||||
+{
|
||||
+ cairo_debug_path_dump_closure_t *fdc =
|
||||
+ (cairo_debug_path_dump_closure_t*) closure;
|
||||
+ fprintf (fdc->fp, "%d: close\n",
|
||||
+ fdc->op_count++);
|
||||
+ return CAIRO_STATUS_SUCCESS;
|
||||
+}
|
||||
+
|
||||
+/**
|
||||
+ * cairo_debug_dump_path
|
||||
+ * @path: a #cairo_path_fixed_t
|
||||
+ * @fp: the file pointer where to dump the given path
|
||||
+ *
|
||||
+ * Dumps @path in human-readable form to @fp.
|
||||
+ */
|
||||
+void
|
||||
+cairo_debug_dump_path (cairo_path_fixed_t *path,
|
||||
+ FILE *fp)
|
||||
+{
|
||||
+ cairo_debug_path_dump_closure_t fdc;
|
||||
+ fdc.fp = fp;
|
||||
+ fdc.op_count = 0;
|
||||
+
|
||||
+ fprintf (fp, "=== path %p ===\n", path);
|
||||
+ _cairo_path_fixed_interpret (path,
|
||||
+ CAIRO_DIRECTION_FORWARD,
|
||||
+ _cairo_debug_path_move_to,
|
||||
+ _cairo_debug_path_line_to,
|
||||
+ _cairo_debug_path_curve_to,
|
||||
+ _cairo_debug_path_close_path,
|
||||
+ &fdc);
|
||||
+ fprintf (fp, "======================\n");
|
||||
+}
|
||||
+
|
||||
+/*
|
||||
+ * traps dumping
|
||||
+ */
|
||||
+
|
||||
+/**
|
||||
+ * cairo_debug_dump_traps
|
||||
+ * @traps: a #cairo_traps_t
|
||||
+ * @fp: the file pointer where to dump the traps
|
||||
+ *
|
||||
+ * Dumps @traps in human-readable form to @fp.
|
||||
+ */
|
||||
+void
|
||||
+cairo_debug_dump_traps (cairo_traps_t *traps,
|
||||
+ FILE *fp)
|
||||
+{
|
||||
+ fprintf (fp, "=== traps %p ===\n", traps);
|
||||
+ fprintf (fp, "extents: (%f, %f) (%f, %f)\n",
|
||||
+ _cairo_fixed_to_double (traps->extents.p1.x),
|
||||
+ _cairo_fixed_to_double (traps->extents.p1.y),
|
||||
+ _cairo_fixed_to_double (traps->extents.p2.x),
|
||||
+ _cairo_fixed_to_double (traps->extents.p2.y));
|
||||
+
|
||||
+ cairo_debug_dump_trapezoid_array (traps->traps,
|
||||
+ traps->num_traps,
|
||||
+ fp);
|
||||
+
|
||||
+ fprintf (fp, "=======================\n");
|
||||
+}
|
||||
+
|
||||
+/**
|
||||
+ * cairo_debug_dump_trapezoid_array
|
||||
+ * @traps: a #cairo_trapezoid_t pointer
|
||||
+ * @num_traps: the number of trapezoids in @traps
|
||||
+ * @fp: the file pointer where to dump the traps
|
||||
+ *
|
||||
+ * Dumps num_traps in the @traps array in human-readable form to @fp.
|
||||
+ */
|
||||
+void
|
||||
+cairo_debug_dump_trapezoid_array (cairo_trapezoid_t *traps,
|
||||
+ int num_traps,
|
||||
+ FILE *fp)
|
||||
+{
|
||||
+ int i;
|
||||
+
|
||||
+ for (i = 0; i < num_traps; i++) {
|
||||
+ fprintf (fp, "% 3d: t: %f b: %f l: (%f,%f)->(%f,%f) r: (%f,%f)->(%f,%f)\n",
|
||||
+ i,
|
||||
+ _cairo_fixed_to_double (traps[i].top),
|
||||
+ _cairo_fixed_to_double (traps[i].bottom),
|
||||
+ _cairo_fixed_to_double (traps[i].left.p1.x),
|
||||
+ _cairo_fixed_to_double (traps[i].left.p1.y),
|
||||
+ _cairo_fixed_to_double (traps[i].left.p2.x),
|
||||
+ _cairo_fixed_to_double (traps[i].left.p2.y),
|
||||
+ _cairo_fixed_to_double (traps[i].right.p1.x),
|
||||
+ _cairo_fixed_to_double (traps[i].right.p1.y),
|
||||
+ _cairo_fixed_to_double (traps[i].right.p2.x),
|
||||
+ _cairo_fixed_to_double (traps[i].right.p2.y));
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
Index: src/cairo-debug.h
|
||||
===================================================================
|
||||
--- src/cairo-debug.h.orig
|
||||
+++ src/cairo-debug.h
|
||||
@@ -37,12 +37,34 @@
|
||||
#define CAIRO_DEBUG_H
|
||||
|
||||
#include <cairo-features.h>
|
||||
+#include <stdio.h>
|
||||
|
||||
CAIRO_BEGIN_DECLS
|
||||
|
||||
+struct _cairo_path_fixed;
|
||||
+struct _cairo_traps;
|
||||
+struct _cairo_trapezoid;
|
||||
+struct _cairo_clip;
|
||||
+
|
||||
void
|
||||
cairo_debug_reset_static_data (void);
|
||||
|
||||
+void
|
||||
+cairo_debug_dump_clip (struct _cairo_clip *clip,
|
||||
+ FILE *fp);
|
||||
+void
|
||||
+cairo_debug_dump_path (struct _cairo_path_fixed *path,
|
||||
+ FILE *fp);
|
||||
+
|
||||
+void
|
||||
+cairo_debug_dump_traps (struct _cairo_traps *traps,
|
||||
+ FILE *fp);
|
||||
+
|
||||
+void
|
||||
+cairo_debug_dump_trapezoid_array (struct _cairo_trapezoid *traps,
|
||||
+ int num_traps,
|
||||
+ FILE *fp);
|
||||
+
|
||||
CAIRO_END_DECLS
|
||||
|
||||
#endif /* CAIRO_H */
|
|
@ -102,7 +102,7 @@ CSRCS = \
|
|||
cairo-wideint.c \
|
||||
$(NULL)
|
||||
|
||||
EXPORTS = cairo.h cairo-features.h cairo-platform.h cairo-rename.h
|
||||
EXPORTS = cairo.h cairo-features.h cairo-platform.h cairo-deprecated.h cairo-rename.h
|
||||
|
||||
|
||||
ifeq ($(MOZ_WIDGET_TOOLKIT),windows)
|
||||
|
@ -132,11 +132,12 @@ EXPORTS += cairo-beos.h
|
|||
endif
|
||||
|
||||
ifeq ($(MOZ_WIDGET_TOOLKIT),gtk2)
|
||||
CSRCS += cairo-font-subset.c \
|
||||
cairo-base85-stream.c \
|
||||
CSRCS += cairo-base85-stream.c \
|
||||
cairo-pdf-surface.c \
|
||||
cairo-ps-surface.c \
|
||||
cairo-type1-subset.c
|
||||
cairo-type1-subset.c \
|
||||
cairo-type1-fallback.c \
|
||||
cairo-truetype-subset.c
|
||||
EXPORTS += cairo-ps.h cairo-pdf.h
|
||||
endif
|
||||
|
||||
|
@ -172,3 +173,9 @@ FORCE_STATIC_LIB = 1
|
|||
FORCE_USE_PIC = 1
|
||||
|
||||
include $(topsrcdir)/config/rules.mk
|
||||
|
||||
DEFINES += -DPACKAGE_VERSION="\"moz\"" -DPACKAGE_BUGREPORT="\"http://bugzilla.mozilla.org/\""
|
||||
|
||||
ifeq ($(MOZ_WIDGET_TOOLKIT),windows)
|
||||
DEFINES += -DCAIRO_WIN32_STATIC_BUILD
|
||||
endif
|
||||
|
|
|
@ -231,7 +231,7 @@ _cairo_arc_in_direction (cairo_t *cr,
|
|||
}
|
||||
|
||||
/**
|
||||
* _cairo_arc_path_negative:
|
||||
* _cairo_arc_path
|
||||
* @cr: a cairo context
|
||||
* @xc: X position of the center of the arc
|
||||
* @yc: Y position of the center of the arc
|
||||
|
@ -266,7 +266,7 @@ _cairo_arc_path (cairo_t *cr,
|
|||
* @angle2: the end angle, in radians
|
||||
* @ctm: the current transformation matrix
|
||||
* @tolerance: the current tolerance value
|
||||
* @path: the path onto which th earc will be appended
|
||||
* @path: the path onto which the arc will be appended
|
||||
*
|
||||
* Compute a path for the given arc (defined in the negative
|
||||
* direction) and append it onto the current path within @cr. The arc
|
||||
|
|
|
@ -159,7 +159,7 @@ _cairo_array_grow_by (cairo_array_t *array, int additional)
|
|||
* beyond @num_elements are simply "forgotten".
|
||||
**/
|
||||
void
|
||||
_cairo_array_truncate (cairo_array_t *array, int num_elements)
|
||||
_cairo_array_truncate (cairo_array_t *array, unsigned int num_elements)
|
||||
{
|
||||
assert (! array->is_snapshot);
|
||||
|
||||
|
@ -187,7 +187,7 @@ _cairo_array_truncate (cairo_array_t *array, int num_elements)
|
|||
* ... use values[i] here ...
|
||||
**/
|
||||
void *
|
||||
_cairo_array_index (cairo_array_t *array, int index)
|
||||
_cairo_array_index (cairo_array_t *array, unsigned int index)
|
||||
{
|
||||
/* We allow an index of 0 for the no-elements case.
|
||||
* This makes for cleaner calling code which will often look like:
|
||||
|
@ -203,7 +203,7 @@ _cairo_array_index (cairo_array_t *array, int index)
|
|||
if (index == 0 && array->num_elements == 0)
|
||||
return NULL;
|
||||
|
||||
assert (0 <= index && index < array->num_elements);
|
||||
assert (index < array->num_elements);
|
||||
|
||||
return (void *) &(*array->elements)[index * array->element_size];
|
||||
}
|
||||
|
@ -287,7 +287,7 @@ _cairo_array_append_multiple (cairo_array_t *array,
|
|||
**/
|
||||
cairo_status_t
|
||||
_cairo_array_allocate (cairo_array_t *array,
|
||||
int num_elements,
|
||||
unsigned int num_elements,
|
||||
void **elements)
|
||||
{
|
||||
cairo_status_t status;
|
||||
|
@ -318,6 +318,18 @@ _cairo_array_num_elements (cairo_array_t *array)
|
|||
return array->num_elements;
|
||||
}
|
||||
|
||||
/**
|
||||
* _cairo_array_size:
|
||||
*
|
||||
* Return value: The number of elements for which there is currently
|
||||
* space allocated in array.
|
||||
**/
|
||||
int
|
||||
_cairo_array_size (cairo_array_t *array)
|
||||
{
|
||||
return array->size;
|
||||
}
|
||||
|
||||
/* cairo_user_data_array_t */
|
||||
|
||||
typedef struct {
|
||||
|
|
|
@ -227,22 +227,30 @@ _cairo_atsui_font_create_scaled (cairo_font_face_t *font_face,
|
|||
|
||||
font->style = CreateSizedCopyOfStyle(style, &font->base.scale);
|
||||
|
||||
Fixed theSize = FloatToFixed(1.0);
|
||||
const ATSUAttributeTag theFontStyleTags[] = { kATSUSizeTag };
|
||||
const ByteCount theFontStyleSizes[] = { sizeof(Fixed) };
|
||||
ATSUAttributeValuePtr theFontStyleValues[] = { &theSize };
|
||||
err = ATSUSetAttributes(style,
|
||||
sizeof(theFontStyleTags) /
|
||||
sizeof(ATSUAttributeTag), theFontStyleTags,
|
||||
theFontStyleSizes, theFontStyleValues);
|
||||
{
|
||||
Fixed theSize = FloatToFixed(1.0);
|
||||
const ATSUAttributeTag theFontStyleTags[] = { kATSUSizeTag };
|
||||
const ByteCount theFontStyleSizes[] = { sizeof(Fixed) };
|
||||
ATSUAttributeValuePtr theFontStyleValues[] = { &theSize };
|
||||
|
||||
err = ATSUSetAttributes(style,
|
||||
sizeof(theFontStyleTags) /
|
||||
sizeof(ATSUAttributeTag), theFontStyleTags,
|
||||
theFontStyleSizes, theFontStyleValues);
|
||||
if (err != noErr) {
|
||||
status = CAIRO_STATUS_NO_MEMORY;
|
||||
goto FAIL;
|
||||
}
|
||||
}
|
||||
|
||||
font->unscaled_style = style;
|
||||
|
||||
font->fontID = font_id;
|
||||
|
||||
*font_out = &font->base;
|
||||
|
||||
status = _cairo_atsui_font_set_metrics (font);
|
||||
|
||||
FAIL:
|
||||
if (status) {
|
||||
cairo_scaled_font_destroy (&font->base);
|
||||
return status;
|
||||
|
@ -318,15 +326,17 @@ _cairo_atsui_font_create_toy(cairo_toy_font_face_t *toy_face,
|
|||
kFontNoLanguageCode, &fontID);
|
||||
}
|
||||
|
||||
ATSUAttributeTag styleTags[] =
|
||||
{ kATSUQDItalicTag, kATSUQDBoldfaceTag, kATSUFontTag };
|
||||
ATSUAttributeValuePtr styleValues[] = { &isItalic, &isBold, &fontID };
|
||||
ByteCount styleSizes[] =
|
||||
{ sizeof(Boolean), sizeof(Boolean), sizeof(ATSUFontID) };
|
||||
{
|
||||
ATSUAttributeTag styleTags[] =
|
||||
{ kATSUQDItalicTag, kATSUQDBoldfaceTag, kATSUFontTag };
|
||||
ATSUAttributeValuePtr styleValues[] = { &isItalic, &isBold, &fontID };
|
||||
ByteCount styleSizes[] =
|
||||
{ sizeof(Boolean), sizeof(Boolean), sizeof(ATSUFontID) };
|
||||
|
||||
err = ATSUSetAttributes(style,
|
||||
sizeof(styleTags) / sizeof(styleTags[0]),
|
||||
styleTags, styleSizes, styleValues);
|
||||
err = ATSUSetAttributes(style,
|
||||
sizeof(styleTags) / sizeof(styleTags[0]),
|
||||
styleTags, styleSizes, styleValues);
|
||||
}
|
||||
|
||||
return _cairo_atsui_font_create_scaled (&toy_face->base, fontID, style,
|
||||
font_matrix, ctm, options, font_out);
|
||||
|
@ -580,6 +590,10 @@ _cairo_atsui_font_old_show_glyphs (void *abstract_font,
|
|||
cairo_bool_t can_draw_directly;
|
||||
cairo_rectangle_int16_t rect;
|
||||
|
||||
ATSFontRef atsFont;
|
||||
CGFontRef cgFont;
|
||||
CGAffineTransform textTransform;
|
||||
|
||||
/* Check if we can draw directly to the destination surface */
|
||||
can_draw_directly = _cairo_surface_is_quartz (generic_surface) &&
|
||||
_cairo_pattern_is_opaque_solid (pattern) &&
|
||||
|
@ -637,14 +651,12 @@ _cairo_atsui_font_old_show_glyphs (void *abstract_font,
|
|||
CGContextSaveGState (drawingContext);
|
||||
}
|
||||
|
||||
ATSFontRef atsFont = FMGetATSFontRefFromFont(font->fontID);
|
||||
CGFontRef cgFont = CGFontCreateWithPlatformFont(&atsFont);
|
||||
atsFont = FMGetATSFontRefFromFont(font->fontID);
|
||||
cgFont = CGFontCreateWithPlatformFont(&atsFont);
|
||||
|
||||
CGContextSetFont(drawingContext, cgFont);
|
||||
|
||||
CGAffineTransform textTransform =
|
||||
CGAffineTransformMakeWithCairoFontScale(&font->base.scale);
|
||||
|
||||
textTransform = CGAffineTransformMakeWithCairoFontScale(&font->base.scale);
|
||||
textTransform = CGAffineTransformScale(textTransform, 1.0f, -1.0f);
|
||||
|
||||
CGContextSetFontSize(drawingContext, 1.0);
|
||||
|
|
|
@ -38,6 +38,8 @@
|
|||
|
||||
#include "cairo-path-fixed-private.h"
|
||||
|
||||
extern cairo_private const cairo_rectangle_list_t _cairo_rectangles_nil;
|
||||
|
||||
struct _cairo_clip_path {
|
||||
unsigned int ref_count;
|
||||
cairo_path_fixed_t path;
|
||||
|
@ -124,13 +126,7 @@ _cairo_clip_translate (cairo_clip_t *clip,
|
|||
cairo_fixed_t tx,
|
||||
cairo_fixed_t ty);
|
||||
|
||||
cairo_private cairo_bool_t
|
||||
_cairo_clip_has_clip (cairo_clip_t *clip);
|
||||
|
||||
cairo_private cairo_bool_t
|
||||
_cairo_clip_extract_rectangles (cairo_clip_t *clip,
|
||||
int max_rectangles,
|
||||
cairo_clip_rect_t *rectangles_out,
|
||||
int *num_rectangles_out);
|
||||
cairo_private cairo_rectangle_list_t*
|
||||
_cairo_clip_copy_rectangles (cairo_clip_t *clip, cairo_gstate_t *gstate);
|
||||
|
||||
#endif /* CAIRO_CLIP_PRIVATE_H */
|
||||
|
|
|
@ -118,6 +118,39 @@ _cairo_clip_reset (cairo_clip_t *clip)
|
|||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
static cairo_status_t
|
||||
_cairo_clip_path_intersect_to_rectangle (cairo_clip_path_t *clip_path,
|
||||
cairo_rectangle_int16_t *rectangle)
|
||||
{
|
||||
while (clip_path) {
|
||||
cairo_status_t status;
|
||||
cairo_traps_t traps;
|
||||
cairo_box_t extents;
|
||||
cairo_rectangle_int16_t extents_rect;
|
||||
|
||||
_cairo_traps_init (&traps);
|
||||
|
||||
status = _cairo_path_fixed_fill_to_traps (&clip_path->path,
|
||||
clip_path->fill_rule,
|
||||
clip_path->tolerance,
|
||||
&traps);
|
||||
if (status) {
|
||||
_cairo_traps_fini (&traps);
|
||||
return status;
|
||||
}
|
||||
|
||||
_cairo_traps_extents (&traps, &extents);
|
||||
_cairo_box_round_to_rectangle (&extents, &extents_rect);
|
||||
_cairo_rectangle_intersect (rectangle, &extents_rect);
|
||||
|
||||
_cairo_traps_fini (&traps);
|
||||
|
||||
clip_path = clip_path->prev;
|
||||
}
|
||||
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
cairo_status_t
|
||||
_cairo_clip_intersect_to_rectangle (cairo_clip_t *clip,
|
||||
cairo_rectangle_int16_t *rectangle)
|
||||
|
@ -126,7 +159,12 @@ _cairo_clip_intersect_to_rectangle (cairo_clip_t *clip,
|
|||
return CAIRO_STATUS_SUCCESS;
|
||||
|
||||
if (clip->path) {
|
||||
/* Intersect path extents here. */
|
||||
cairo_status_t status;
|
||||
|
||||
status = _cairo_clip_path_intersect_to_rectangle (clip->path,
|
||||
rectangle);
|
||||
if (status)
|
||||
return status;
|
||||
}
|
||||
|
||||
if (clip->region) {
|
||||
|
@ -535,52 +573,89 @@ _cairo_clip_init_deep_copy (cairo_clip_t *clip,
|
|||
}
|
||||
}
|
||||
|
||||
cairo_bool_t
|
||||
_cairo_clip_has_clip (cairo_clip_t *clip)
|
||||
{
|
||||
return clip->region != NULL || clip->surface != NULL || clip->path != NULL;
|
||||
}
|
||||
const cairo_rectangle_list_t _cairo_rectangles_nil =
|
||||
{ CAIRO_STATUS_NO_MEMORY, NULL, 0 };
|
||||
static const cairo_rectangle_list_t _cairo_rectangles_not_representable =
|
||||
{ CAIRO_STATUS_CLIP_NOT_REPRESENTABLE, NULL, 0 };
|
||||
|
||||
static cairo_bool_t
|
||||
_cairo_region_to_clip_rectangles (pixman_region16_t *region,
|
||||
int max_rectangles,
|
||||
cairo_clip_rect_t *rectangles_out,
|
||||
int *num_rectangles_out)
|
||||
_cairo_clip_rect_to_user (cairo_gstate_t *gstate,
|
||||
double x, double y, double width, double height,
|
||||
cairo_rectangle_t *rectangle)
|
||||
{
|
||||
int n_boxes, i;
|
||||
pixman_box16_t *boxes;
|
||||
double x2 = x + width;
|
||||
double y2 = y + height;
|
||||
cairo_bool_t is_tight;
|
||||
|
||||
/* no region -> we can't represent it as rectangles */
|
||||
if (region == NULL)
|
||||
return FALSE;
|
||||
_cairo_gstate_backend_to_user_rectangle (gstate, &x, &y, &x2, &y2, &is_tight);
|
||||
rectangle->x = x;
|
||||
rectangle->y = y;
|
||||
rectangle->width = x2 - x;
|
||||
rectangle->height = y2 - y;
|
||||
return is_tight;
|
||||
}
|
||||
|
||||
n_boxes = pixman_region_num_rects (region);
|
||||
*num_rectangles_out = n_boxes;
|
||||
if (n_boxes > max_rectangles)
|
||||
return FALSE;
|
||||
cairo_private cairo_rectangle_list_t*
|
||||
_cairo_clip_copy_rectangles (cairo_clip_t *clip, cairo_gstate_t *gstate)
|
||||
{
|
||||
cairo_rectangle_list_t *list;
|
||||
cairo_rectangle_t *rectangles;
|
||||
int n_boxes;
|
||||
|
||||
boxes = pixman_region_rects (region);
|
||||
|
||||
for (i = 0; i < n_boxes; i++) {
|
||||
rectangles_out[i].x = boxes[i].x1;
|
||||
rectangles_out[i].y = boxes[i].y1;
|
||||
rectangles_out[i].width = boxes[i].x2 - boxes[i].x1;
|
||||
rectangles_out[i].height = boxes[i].y2 - boxes[i].y1;
|
||||
if (clip->path || clip->surface)
|
||||
return (cairo_rectangle_list_t*) &_cairo_rectangles_not_representable;
|
||||
|
||||
n_boxes = clip->region ? pixman_region_num_rects (clip->region) : 1;
|
||||
rectangles = malloc (sizeof (cairo_rectangle_t)*n_boxes);
|
||||
if (rectangles == NULL)
|
||||
return (cairo_rectangle_list_t*) &_cairo_rectangles_nil;
|
||||
|
||||
if (clip->region) {
|
||||
pixman_box16_t *boxes;
|
||||
int i;
|
||||
|
||||
boxes = pixman_region_rects (clip->region);
|
||||
for (i = 0; i < n_boxes; ++i) {
|
||||
if (!_cairo_clip_rect_to_user(gstate, boxes[i].x1, boxes[i].y1,
|
||||
boxes[i].x2 - boxes[i].x1,
|
||||
boxes[i].y2 - boxes[i].y1,
|
||||
&rectangles[i])) {
|
||||
free (rectangles);
|
||||
return (cairo_rectangle_list_t*)
|
||||
&_cairo_rectangles_not_representable;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
cairo_rectangle_int16_t extents;
|
||||
_cairo_surface_get_extents (_cairo_gstate_get_target (gstate), &extents);
|
||||
if (!_cairo_clip_rect_to_user(gstate, extents.x, extents.y,
|
||||
extents.width, extents.height,
|
||||
rectangles)) {
|
||||
free (rectangles);
|
||||
return (cairo_rectangle_list_t*)
|
||||
&_cairo_rectangles_not_representable;
|
||||
}
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
list = malloc (sizeof (cairo_rectangle_list_t));
|
||||
if (list == NULL) {
|
||||
free (rectangles);
|
||||
return (cairo_rectangle_list_t*) &_cairo_rectangles_nil;
|
||||
}
|
||||
|
||||
list->status = CAIRO_STATUS_SUCCESS;
|
||||
list->rectangles = rectangles;
|
||||
list->num_rectangles = n_boxes;
|
||||
return list;
|
||||
}
|
||||
|
||||
cairo_bool_t
|
||||
_cairo_clip_extract_rectangles (cairo_clip_t *clip,
|
||||
int max_rectangles,
|
||||
cairo_clip_rect_t *rectangles_out,
|
||||
int *num_rectangles_out)
|
||||
void
|
||||
cairo_rectangle_list_destroy (cairo_rectangle_list_t *rectangle_list)
|
||||
{
|
||||
/* can't handle paths or surfaces for now */
|
||||
if (clip->path != NULL || clip->surface != NULL)
|
||||
return FALSE;
|
||||
|
||||
return _cairo_region_to_clip_rectangles (clip->region,
|
||||
max_rectangles, rectangles_out, num_rectangles_out);
|
||||
if (rectangle_list == NULL || rectangle_list == &_cairo_rectangles_nil ||
|
||||
rectangle_list == &_cairo_rectangles_not_representable)
|
||||
return;
|
||||
|
||||
free (rectangle_list->rectangles);
|
||||
free (rectangle_list);
|
||||
}
|
||||
|
|
|
@ -0,0 +1,139 @@
|
|||
/* cairo - a vector graphics library with display and print output
|
||||
*
|
||||
* Copyright © 2006 Red Hat, Inc.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it either under the terms of the GNU Lesser General Public
|
||||
* License version 2.1 as published by the Free Software Foundation
|
||||
* (the "LGPL") or, at your option, under the terms of the Mozilla
|
||||
* Public License Version 1.1 (the "MPL"). If you do not alter this
|
||||
* notice, a recipient may use your version of this file under either
|
||||
* the MPL or the LGPL.
|
||||
*
|
||||
* You should have received a copy of the LGPL along with this library
|
||||
* in the file COPYING-LGPL-2.1; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
* You should have received a copy of the MPL along with this library
|
||||
* in the file COPYING-MPL-1.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License
|
||||
* Version 1.1 (the "License"); you may not use this file except in
|
||||
* compliance with the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY
|
||||
* OF ANY KIND, either express or implied. See the LGPL or the MPL for
|
||||
* the specific language governing rights and limitations.
|
||||
*
|
||||
* The Original Code is the cairo graphics library.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Red Hat, Inc.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Carl D. Worth <cworth@cworth.org>
|
||||
*/
|
||||
|
||||
#ifndef CAIRO_DEPRECATED_H
|
||||
#define CAIRO_DEPRECATED_H
|
||||
|
||||
/* The CAIRO_FORMAT_RGB16_565 value was added in cairo 1.2.0 as part
|
||||
* of fixing cairo's xlib backend to work with X servers advertising a
|
||||
* 16-bit, 565 visual. But as it turned out, adding this format to
|
||||
* #cairo_format_t was not necessary, and was a mistake, (cairo's xlib
|
||||
* backend can work fine with 16-bit visuals in the same way it works
|
||||
* with BGR visuals without any BGR formats in
|
||||
* #cairo_format_t).
|
||||
*
|
||||
* Additionally, the support for the RGB16_565 format was never
|
||||
* completely implemented. So while this format value is currently
|
||||
* deprecated, it may eventually acquire complete support in the future.
|
||||
*/
|
||||
#define CAIRO_FORMAT_RGB16_565 4
|
||||
|
||||
#ifndef _CAIROINT_H_
|
||||
|
||||
/* Obsolete functions. These definitions exist to coerce the compiler
|
||||
* into providing a little bit of guidance with its error
|
||||
* messages. The idea is to help users port their old code without
|
||||
* having to dig through lots of documentation.
|
||||
*
|
||||
* The first set of REPLACED_BY functions is for functions whose names
|
||||
* have just been changed. So fixing these up is mechanical, (and
|
||||
* automated by means of the cairo/util/cairo-api-update script.
|
||||
*
|
||||
* The second set of DEPRECATED_BY functions is for functions where
|
||||
* the replacement is used in a different way, (ie. different
|
||||
* arguments, multiple functions instead of one, etc). Fixing these up
|
||||
* will require a bit more work on the user's part, (and hopefully we
|
||||
* can get cairo-api-update to find these and print some guiding
|
||||
* information).
|
||||
*/
|
||||
#define cairo_current_font_extents cairo_current_font_extents_REPLACED_BY_cairo_font_extents
|
||||
#define cairo_get_font_extents cairo_get_font_extents_REPLACED_BY_cairo_font_extents
|
||||
#define cairo_current_operator cairo_current_operator_REPLACED_BY_cairo_get_operator
|
||||
#define cairo_current_tolerance cairo_current_tolerance_REPLACED_BY_cairo_get_tolerance
|
||||
#define cairo_current_point cairo_current_point_REPLACED_BY_cairo_get_current_point
|
||||
#define cairo_current_fill_rule cairo_current_fill_rule_REPLACED_BY_cairo_get_fill_rule
|
||||
#define cairo_current_line_width cairo_current_line_width_REPLACED_BY_cairo_get_line_width
|
||||
#define cairo_current_line_cap cairo_current_line_cap_REPLACED_BY_cairo_get_line_cap
|
||||
#define cairo_current_line_join cairo_current_line_join_REPLACED_BY_cairo_get_line_join
|
||||
#define cairo_current_miter_limit cairo_current_miter_limit_REPLACED_BY_cairo_get_miter_limit
|
||||
#define cairo_current_matrix cairo_current_matrix_REPLACED_BY_cairo_get_matrix
|
||||
#define cairo_current_target_surface cairo_current_target_surface_REPLACED_BY_cairo_get_target
|
||||
#define cairo_get_status cairo_get_status_REPLACED_BY_cairo_status
|
||||
#define cairo_concat_matrix cairo_concat_matrix_REPLACED_BY_cairo_transform
|
||||
#define cairo_scale_font cairo_scale_font_REPLACED_BY_cairo_set_font_size
|
||||
#define cairo_select_font cairo_select_font_REPLACED_BY_cairo_select_font_face
|
||||
#define cairo_transform_font cairo_transform_font_REPLACED_BY_cairo_set_font_matrix
|
||||
#define cairo_transform_point cairo_transform_point_REPLACED_BY_cairo_user_to_device
|
||||
#define cairo_transform_distance cairo_transform_distance_REPLACED_BY_cairo_user_to_device_distance
|
||||
#define cairo_inverse_transform_point cairo_inverse_transform_point_REPLACED_BY_cairo_device_to_user
|
||||
#define cairo_inverse_transform_distance cairo_inverse_transform_distance_REPLACED_BY_cairo_device_to_user_distance
|
||||
#define cairo_init_clip cairo_init_clip_REPLACED_BY_cairo_reset_clip
|
||||
#define cairo_surface_create_for_image cairo_surface_create_for_image_REPLACED_BY_cairo_image_surface_create_for_data
|
||||
#define cairo_default_matrix cairo_default_matrix_REPLACED_BY_cairo_identity_matrix
|
||||
#define cairo_matrix_set_affine cairo_matrix_set_affine_REPLACED_BY_cairo_matrix_init
|
||||
#define cairo_matrix_set_identity cairo_matrix_set_identity_REPLACED_BY_cairo_matrix_init_identity
|
||||
#define cairo_pattern_add_color_stop cairo_pattern_add_color_stop_REPLACED_BY_cairo_pattern_add_color_stop_rgba
|
||||
#define cairo_set_rgb_color cairo_set_rgb_color_REPLACED_BY_cairo_set_source_rgb
|
||||
#define cairo_set_pattern cairo_set_pattern_REPLACED_BY_cairo_set_source
|
||||
#define cairo_xlib_surface_create_for_pixmap_with_visual cairo_xlib_surface_create_for_pixmap_with_visual_REPLACED_BY_cairo_xlib_surface_create
|
||||
#define cairo_xlib_surface_create_for_window_with_visual cairo_xlib_surface_create_for_window_with_visual_REPLACED_BY_cairo_xlib_surface_create
|
||||
#define cairo_xcb_surface_create_for_pixmap_with_visual cairo_xcb_surface_create_for_pixmap_with_visual_REPLACED_BY_cairo_xcb_surface_create
|
||||
#define cairo_xcb_surface_create_for_window_with_visual cairo_xcb_surface_create_for_window_with_visual_REPLACED_BY_cairo_xcb_surface_create
|
||||
#define cairo_ps_surface_set_dpi cairo_ps_surface_set_dpi_REPLACED_BY_cairo_surface_set_fallback_resolution
|
||||
#define cairo_pdf_surface_set_dpi cairo_pdf_surface_set_dpi_REPLACED_BY_cairo_surface_set_fallback_resolution
|
||||
#define cairo_svg_surface_set_dpi cairo_svg_surface_set_dpi_REPLACED_BY_cairo_surface_set_fallback_resolution
|
||||
|
||||
#define cairo_current_path cairo_current_path_DEPRECATED_BY_cairo_copy_path
|
||||
#define cairo_current_path_flat cairo_current_path_flat_DEPRECATED_BY_cairo_copy_path_flat
|
||||
#define cairo_get_path cairo_get_path_DEPRECATED_BY_cairo_copy_path
|
||||
#define cairo_get_path_flat cairo_get_path_flat_DEPRECATED_BY_cairo_get_path_flat
|
||||
#define cairo_set_alpha cairo_set_alpha_DEPRECATED_BY_cairo_set_source_rgba_OR_cairo_paint_with_alpha
|
||||
#define cairo_show_surface cairo_show_surface_DEPRECATED_BY_cairo_set_source_surface_AND_cairo_paint
|
||||
#define cairo_copy cairo_copy_DEPRECATED_BY_cairo_create_AND_MANY_INDIVIDUAL_FUNCTIONS
|
||||
#define cairo_surface_set_repeat cairo_surface_set_repeat_DEPRECATED_BY_cairo_pattern_set_extend
|
||||
#define cairo_surface_set_matrix cairo_surface_set_matrix_DEPRECATED_BY_cairo_pattern_set_matrix
|
||||
#define cairo_surface_get_matrix cairo_surface_get_matrix_DEPRECATED_BY_cairo_pattern_get_matrix
|
||||
#define cairo_surface_set_filter cairo_surface_set_filter_DEPRECATED_BY_cairo_pattern_set_filter
|
||||
#define cairo_surface_get_filter cairo_surface_get_filter_DEPRECATED_BY_cairo_pattern_get_filter
|
||||
#define cairo_matrix_create cairo_matrix_create_DEPRECATED_BY_cairo_matrix_t
|
||||
#define cairo_matrix_destroy cairo_matrix_destroy_DEPRECATED_BY_cairo_matrix_t
|
||||
#define cairo_matrix_copy cairo_matrix_copy_DEPRECATED_BY_cairo_matrix_t
|
||||
#define cairo_matrix_get_affine cairo_matrix_get_affine_DEPRECATED_BY_cairo_matrix_t
|
||||
#define cairo_set_target_surface cairo_set_target_surface_DEPRECATED_BY_cairo_create
|
||||
#define cairo_set_target_glitz cairo_set_target_glitz_DEPRECATED_BY_cairo_glitz_surface_create
|
||||
#define cairo_set_target_image cairo_set_target_image_DEPRECATED_BY_cairo_image_surface_create_for_data
|
||||
#define cairo_set_target_pdf cairo_set_target_pdf_DEPRECATED_BY_cairo_pdf_surface_create
|
||||
#define cairo_set_target_png cairo_set_target_png_DEPRECATED_BY_cairo_surface_write_to_png
|
||||
#define cairo_set_target_ps cairo_set_target_ps_DEPRECATED_BY_cairo_ps_surface_create
|
||||
#define cairo_set_target_quartz cairo_set_target_quartz_DEPRECATED_BY_cairo_quartz_surface_create
|
||||
#define cairo_set_target_win32 cairo_set_target_win32_DEPRECATED_BY_cairo_win32_surface_create
|
||||
#define cairo_set_target_xcb cairo_set_target_xcb_DEPRECATED_BY_cairo_xcb_surface_create
|
||||
#define cairo_set_target_drawable cairo_set_target_drawable_DEPRECATED_BY_cairo_xlib_surface_create
|
||||
#define cairo_get_status_string cairo_get_status_string_DEPRECATED_BY_cairo_status_AND_cairo_status_to_string
|
||||
#define cairo_status_string cairo_status_string_DEPRECATED_BY_cairo_status_AND_cairo_status_to_string
|
||||
|
||||
#endif
|
||||
|
||||
#endif /* CAIRO_DEPRECATED_H */
|
|
@ -38,6 +38,7 @@
|
|||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <math.h>
|
||||
#include <assert.h>
|
||||
|
||||
#include <directfb.h>
|
||||
|
||||
|
@ -50,15 +51,20 @@
|
|||
#include "cairoint.h"
|
||||
|
||||
|
||||
/*
|
||||
* Rectangle works fine.
|
||||
*/
|
||||
#define DFB_RECTANGLES 1
|
||||
|
||||
/*
|
||||
* Composite works fine.
|
||||
*/
|
||||
#define DFB_COMPOSITE 1
|
||||
#define DFB_COMPOSITE 1
|
||||
|
||||
/*
|
||||
* CompositeTrapezoids works (without antialiasing).
|
||||
*/
|
||||
#define DFB_COMPOSITE_TRAPEZOIDS 1
|
||||
#define DFB_COMPOSITE_TRAPEZOIDS 0
|
||||
|
||||
/*
|
||||
* ShowGlyphs works fine.
|
||||
|
@ -73,31 +79,24 @@ D_DEBUG_DOMAIN (Cairo_DirectFB, "Cairo/DirectFB", "Cairo DirectFB backend");
|
|||
|
||||
typedef struct _cairo_directfb_surface {
|
||||
cairo_surface_t base;
|
||||
|
||||
cairo_format_t format;
|
||||
|
||||
IDirectFB *dfb;
|
||||
IDirectFBSurface *surface;
|
||||
IDirectFBSurface *buffer;
|
||||
|
||||
int owner;
|
||||
IDirectFBSurface *dfbsurface;
|
||||
/* color buffer */
|
||||
cairo_surface_t *color;
|
||||
|
||||
DFBRegion *clips;
|
||||
int n_clips;
|
||||
|
||||
cairo_surface_t *buffer_image;
|
||||
|
||||
DFBRegion *dirty_region;
|
||||
int width;
|
||||
int height;
|
||||
|
||||
bool local;
|
||||
} cairo_directfb_surface_t;
|
||||
|
||||
|
||||
typedef struct _cairo_directfb_font_cache {
|
||||
IDirectFB *dfb;
|
||||
IDirectFBSurface *buffer;
|
||||
IDirectFBSurface *dfbsurface;
|
||||
|
||||
int width;
|
||||
int height;
|
||||
|
@ -132,17 +131,17 @@ static cairo_surface_backend_t cairo_directfb_surface_backend;
|
|||
reg.x2 = cli->x2;\
|
||||
if (reg.y2 > cli->y2)\
|
||||
reg.y2 = cli->y2;\
|
||||
(surface)->buffer->SetClip ((surface)->buffer, ®);\
|
||||
(surface)->dfbsurface->SetClip ((surface)->dfbsurface, ®);\
|
||||
}\
|
||||
else {\
|
||||
(surface)->buffer->SetClip ((surface)->buffer,\
|
||||
(surface)->dfbsurface->SetClip ((surface)->dfbsurface,\
|
||||
&(surface)->clips[k]);\
|
||||
}\
|
||||
func;\
|
||||
}\
|
||||
}\
|
||||
else {\
|
||||
(surface)->buffer->SetClip ((surface)->buffer, clip);\
|
||||
(surface)->dfbsurface->SetClip ((surface)->dfbsurface, clip);\
|
||||
func;\
|
||||
}\
|
||||
}
|
||||
|
@ -325,78 +324,77 @@ _directfb_buffer_surface_create (IDirectFB *dfb,
|
|||
|
||||
static cairo_status_t
|
||||
_directfb_acquire_surface (cairo_directfb_surface_t *surface,
|
||||
DFBSurfaceLockFlags lock_flags)
|
||||
cairo_rectangle_int16_t *intrest_rec,
|
||||
cairo_image_surface_t **image_out,
|
||||
cairo_rectangle_int16_t *image_rect_out,
|
||||
void **image_extra,
|
||||
DFBSurfaceLockFlags lock_flags)
|
||||
{
|
||||
if (!surface->local) {
|
||||
int width, height;
|
||||
|
||||
surface->surface->GetSize (surface->surface, &width, &height);
|
||||
void *data;
|
||||
int pitch;
|
||||
IDirectFBSurface *buffer;
|
||||
DFBRectangle source_rect;
|
||||
cairo_format_t cairo_format;
|
||||
cairo_format = surface->format;
|
||||
|
||||
if (surface->width != width || surface->height != height) {
|
||||
DFBSurfacePixelFormat format;
|
||||
|
||||
if (surface->buffer_image) {
|
||||
cairo_surface_destroy (surface->buffer_image);
|
||||
surface->buffer_image = NULL;
|
||||
}
|
||||
|
||||
if (surface->buffer)
|
||||
surface->buffer->Release (surface->buffer);
|
||||
|
||||
surface->surface->GetPixelFormat (surface->surface, &format);
|
||||
surface->format = directfb_to_cairo_format (format);
|
||||
|
||||
if (surface->format == -1) {
|
||||
D_DEBUG_AT (Cairo_DirectFB, "%s buffer for surface.\n",
|
||||
surface->buffer ? "Reallocating" : "Allocating");
|
||||
|
||||
surface->buffer = _directfb_buffer_surface_create (surface->dfb,
|
||||
DSPF_ARGB, width, height);
|
||||
if (!surface->buffer)
|
||||
return CAIRO_STATUS_NO_MEMORY;
|
||||
|
||||
surface->buffer->Blit (surface->buffer,
|
||||
surface->surface, NULL, 0, 0);
|
||||
|
||||
surface->format = CAIRO_FORMAT_ARGB32;
|
||||
}
|
||||
else {
|
||||
surface->surface->AddRef (surface->surface);
|
||||
surface->buffer = surface->surface;
|
||||
}
|
||||
|
||||
surface->width = width;
|
||||
surface->height = height;
|
||||
if (surface->format == -1) {
|
||||
if( intrest_rec ) {
|
||||
source_rect.x = intrest_rec->x;
|
||||
source_rect.y = intrest_rec->y;
|
||||
source_rect.w = intrest_rec->width;
|
||||
source_rect.h = intrest_rec->height;
|
||||
}else {
|
||||
source_rect.x=0;
|
||||
source_rect.y=0;
|
||||
surface->dfbsurface->GetSize (surface->dfbsurface,&source_rect.w, &source_rect.h);
|
||||
}
|
||||
D_DEBUG_AT (Cairo_DirectFB, "%s buffer for surface.\n",
|
||||
surface->dfbsurface ? "Reallocating" : "Allocating");
|
||||
cairo_format = directfb_to_cairo_format(DSPF_ARGB);
|
||||
buffer = _directfb_buffer_surface_create (surface->dfb,DSPF_ARGB,source_rect.w,source_rect.h);
|
||||
if (!buffer)
|
||||
goto ERROR;
|
||||
*image_extra = buffer;
|
||||
buffer->SetBlittingFlags (buffer,DSBLIT_BLEND_ALPHACHANNEL | DSBLIT_COLORIZE);
|
||||
buffer->Blit (buffer,surface->dfbsurface,&source_rect,0,0);
|
||||
} else {
|
||||
/*might be a subsurface get the offset*/
|
||||
surface->dfbsurface->GetVisibleRectangle (surface->dfbsurface,&source_rect);
|
||||
buffer = surface->dfbsurface;
|
||||
*image_extra = buffer;
|
||||
}
|
||||
|
||||
if (lock_flags) {
|
||||
void *data;
|
||||
int pitch;
|
||||
DFBResult ret;
|
||||
|
||||
|
||||
ret = surface->buffer->Lock (surface->buffer,
|
||||
lock_flags, &data, &pitch);
|
||||
if (ret) {
|
||||
DirectFBError ("IDirectFBSurface::Lock()", ret);
|
||||
return CAIRO_STATUS_NO_MEMORY;
|
||||
}
|
||||
if( buffer->Lock (buffer,lock_flags, &data, &pitch) )
|
||||
goto ERROR;
|
||||
|
||||
if (!surface->buffer_image) {
|
||||
surface->buffer_image = cairo_image_surface_create_for_data (data,
|
||||
surface->format, surface->width,
|
||||
surface->height, pitch);
|
||||
if (!surface->buffer_image) {
|
||||
surface->buffer->Unlock (surface->buffer);
|
||||
return CAIRO_STATUS_NO_MEMORY;
|
||||
}
|
||||
}
|
||||
else {
|
||||
cairo_surface_reference (surface->buffer_image);
|
||||
}
|
||||
*image_out = (cairo_image_surface_t *)cairo_image_surface_create_for_data (data,
|
||||
cairo_format,source_rect.w,source_rect.h, pitch);
|
||||
if (*image_out == NULL )
|
||||
goto ERROR;
|
||||
|
||||
if (image_rect_out) {
|
||||
image_rect_out->x = source_rect.x;
|
||||
image_rect_out->y = source_rect.y;
|
||||
image_rect_out->width = source_rect.w;
|
||||
image_rect_out->height = source_rect.h;
|
||||
}else {
|
||||
/*lock for read*/
|
||||
cairo_surface_t *sur = &((*image_out)->base);
|
||||
/*might be a subsurface*/
|
||||
if( buffer == surface->dfbsurface )
|
||||
cairo_surface_set_device_offset (sur,source_rect.x,source_rect.y);
|
||||
}
|
||||
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
|
||||
ERROR:
|
||||
*image_extra = NULL;
|
||||
if( buffer ) {
|
||||
buffer->Unlock (buffer);
|
||||
if( buffer != surface->dfbsurface)
|
||||
buffer->Release(buffer);
|
||||
}
|
||||
return CAIRO_STATUS_NO_MEMORY;
|
||||
}
|
||||
|
||||
|
||||
|
@ -415,33 +413,30 @@ _cairo_directfb_surface_create_similar (void *abstract_src,
|
|||
"%s( src=%p, content=0x%x, width=%d, height=%d).\n",
|
||||
__FUNCTION__, source, content, width, height);
|
||||
|
||||
width = (width <= 0) ? 1 : width;
|
||||
height = (height<= 0) ? 1 : height;
|
||||
|
||||
format = _cairo_format_from_content (content);
|
||||
|
||||
surface = calloc (1, sizeof(cairo_directfb_surface_t));
|
||||
if (!surface)
|
||||
return NULL;
|
||||
|
||||
surface->surface = _directfb_buffer_surface_create (source->dfb,
|
||||
surface->dfbsurface = _directfb_buffer_surface_create (source->dfb,
|
||||
cairo_to_directfb_format (format),
|
||||
MAX (width, 8), MAX (height, 8) );
|
||||
if (!surface->surface) {
|
||||
width, height);
|
||||
assert(surface->dfbsurface);
|
||||
|
||||
surface->owner = TRUE;
|
||||
if (!surface->dfbsurface) {
|
||||
assert(0);
|
||||
free (surface);
|
||||
return NULL;
|
||||
}
|
||||
_cairo_surface_init (&surface->base, &cairo_directfb_surface_backend,content);
|
||||
|
||||
|
||||
source->dfb->AddRef (source->dfb);
|
||||
surface->dfb = source->dfb;
|
||||
|
||||
surface->surface->AddRef (surface->surface);
|
||||
surface->buffer = surface->surface;
|
||||
|
||||
surface->format = format;
|
||||
surface->width = width;
|
||||
surface->height = height;
|
||||
surface->local = true;
|
||||
|
||||
return &surface->base;
|
||||
}
|
||||
|
||||
|
@ -453,11 +448,6 @@ _cairo_directfb_surface_finish (void *data)
|
|||
D_DEBUG_AT (Cairo_DirectFB,
|
||||
"%s( surface=%p ).\n", __FUNCTION__, surface);
|
||||
|
||||
if (surface->buffer_image) {
|
||||
cairo_surface_destroy (surface->buffer_image);
|
||||
surface->buffer_image = NULL;
|
||||
}
|
||||
|
||||
if (surface->clips) {
|
||||
free (surface->clips);
|
||||
surface->clips = NULL;
|
||||
|
@ -469,18 +459,13 @@ _cairo_directfb_surface_finish (void *data)
|
|||
surface->color = NULL;
|
||||
}
|
||||
|
||||
if (surface->buffer) {
|
||||
surface->buffer->Release (surface->buffer);
|
||||
surface->buffer = NULL;
|
||||
}
|
||||
|
||||
if (surface->surface) {
|
||||
surface->surface->Release (surface->surface);
|
||||
surface->surface = NULL;
|
||||
if (surface->dfbsurface) {
|
||||
if( surface->owner )
|
||||
surface->dfbsurface->Release (surface->dfbsurface);
|
||||
surface->dfbsurface = NULL;
|
||||
}
|
||||
|
||||
if (surface->dfb) {
|
||||
surface->dfb->Release (surface->dfb);
|
||||
surface->dfb = NULL;
|
||||
}
|
||||
|
||||
|
@ -493,22 +478,9 @@ _cairo_directfb_surface_acquire_source_image (void *abstract_s
|
|||
void **image_extra)
|
||||
{
|
||||
cairo_directfb_surface_t *surface = abstract_surface;
|
||||
cairo_status_t ret;
|
||||
|
||||
D_DEBUG_AT (Cairo_DirectFB,
|
||||
"%s( surface=%p ).\n", __FUNCTION__, surface);
|
||||
|
||||
ret = _directfb_acquire_surface (surface, DSLF_READ);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
if (image_out)
|
||||
*image_out = (cairo_image_surface_t *)surface->buffer_image;
|
||||
|
||||
if (image_extra)
|
||||
*image_extra = surface;
|
||||
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
return _directfb_acquire_surface (surface,NULL,image_out,NULL,image_extra,DSLF_READ);
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -517,11 +489,16 @@ _cairo_directfb_surface_release_source_image (void *abstract_su
|
|||
void *image_extra)
|
||||
{
|
||||
cairo_directfb_surface_t *surface = abstract_surface;
|
||||
IDirectFBSurface *buffer = image_extra;
|
||||
|
||||
D_DEBUG_AT (Cairo_DirectFB,
|
||||
"%s( surface=%p ).\n", __FUNCTION__, surface);
|
||||
|
||||
surface->buffer->Unlock (surface->buffer);
|
||||
buffer->Unlock (buffer);
|
||||
if (surface->dfbsurface != buffer) {
|
||||
buffer->Release (buffer);
|
||||
}
|
||||
cairo_surface_destroy (&image->base);
|
||||
}
|
||||
|
||||
static cairo_status_t
|
||||
|
@ -532,29 +509,12 @@ _cairo_directfb_surface_acquire_dest_image (void *abstract_sur
|
|||
void **image_extra)
|
||||
{
|
||||
cairo_directfb_surface_t *surface = abstract_surface;
|
||||
cairo_status_t ret;
|
||||
|
||||
D_DEBUG_AT (Cairo_DirectFB,
|
||||
"%s( surface=%p ).\n", __FUNCTION__, surface);
|
||||
|
||||
ret = _directfb_acquire_surface (surface, DSLF_READ | DSLF_WRITE);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
if (image_out)
|
||||
*image_out = (cairo_image_surface_t *)surface->buffer_image;
|
||||
|
||||
if (image_rect_out) {
|
||||
image_rect_out->x = 0;
|
||||
image_rect_out->y = 0;
|
||||
image_rect_out->width = surface->width;
|
||||
image_rect_out->height = surface->height;
|
||||
}
|
||||
|
||||
if (image_extra)
|
||||
*image_extra = interest_rect;
|
||||
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
return _directfb_acquire_surface (surface,interest_rect,image_out,image_rect_out,image_extra,
|
||||
DSLF_READ | DSLF_WRITE);
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -565,11 +525,24 @@ _cairo_directfb_surface_release_dest_image (void *abstract_surf
|
|||
void *image_extra)
|
||||
{
|
||||
cairo_directfb_surface_t *surface = abstract_surface;
|
||||
IDirectFBSurface *buffer = image_extra;
|
||||
|
||||
D_DEBUG_AT (Cairo_DirectFB,
|
||||
"%s( surface=%p ).\n", __FUNCTION__, surface);
|
||||
|
||||
surface->buffer->Unlock (surface->buffer);
|
||||
buffer->Unlock (buffer);
|
||||
|
||||
if (surface->dfbsurface != buffer) {
|
||||
DFBRegion region = { x1:interest_rect->x, y1:interest_rect->y,
|
||||
x2:interest_rect->x+interest_rect->width-1,
|
||||
y2:interest_rect->y+interest_rect->height-1 };
|
||||
surface->dfbsurface->SetClip (surface->dfbsurface, ®ion);
|
||||
//surface->dfbsurface->SetBlittingFlags (surface->dfbsurface,
|
||||
// DSBLIT_BLEND_ALPHACHANNEL | DSBLIT_COLORIZE);
|
||||
surface->dfbsurface->Blit (surface->dfbsurface,buffer,NULL,
|
||||
image_rect->x,image_rect->y);
|
||||
buffer->Release (buffer);
|
||||
}
|
||||
cairo_surface_destroy (&image->base);
|
||||
}
|
||||
|
||||
static cairo_status_t
|
||||
|
@ -603,7 +576,7 @@ _cairo_directfb_surface_clone_similar (void *abstract_surface,
|
|||
if (!clone)
|
||||
return CAIRO_STATUS_NO_MEMORY;
|
||||
|
||||
ret = clone->buffer->Lock (clone->buffer,
|
||||
ret = clone->dfbsurface->Lock (clone->dfbsurface,
|
||||
DSLF_WRITE, (void *)&dst, &pitch);
|
||||
if (ret) {
|
||||
DirectFBError ("IDirectFBSurface::Lock()", ret);
|
||||
|
@ -628,7 +601,7 @@ _cairo_directfb_surface_clone_similar (void *abstract_surface,
|
|||
}
|
||||
}
|
||||
|
||||
clone->buffer->Unlock (clone->buffer);
|
||||
clone->dfbsurface->Unlock (clone->dfbsurface);
|
||||
|
||||
*clone_out = &clone->base;
|
||||
|
||||
|
@ -701,10 +674,6 @@ _directfb_prepare_composite (cairo_directfb_surface_t *dst,
|
|||
color.a = color.r = color.g = color.b = 0xff;
|
||||
}
|
||||
|
||||
ret = _directfb_acquire_surface (dst, 0);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
if (src_pattern->type == CAIRO_PATTERN_TYPE_SOLID) {
|
||||
cairo_solid_pattern_t *pattern = (cairo_solid_pattern_t *)src_pattern;
|
||||
|
||||
|
@ -716,12 +685,12 @@ _directfb_prepare_composite (cairo_directfb_surface_t *dst,
|
|||
}
|
||||
|
||||
src = (cairo_directfb_surface_t *)dst->color;
|
||||
src->buffer->SetColor (src->buffer,
|
||||
src->dfbsurface->SetColor (src->dfbsurface,
|
||||
pattern->color.red_short >> 8,
|
||||
pattern->color.green_short >> 8,
|
||||
pattern->color.blue_short >> 8,
|
||||
pattern->color.alpha_short >> 8);
|
||||
src->buffer->FillRectangle (src->buffer, 0, 0, 1, 1);
|
||||
src->dfbsurface->FillRectangle (src->dfbsurface, 0, 0, 1, 1);
|
||||
|
||||
cairo_matrix_init_identity (&src_attr.matrix);
|
||||
src_attr.matrix = src_pattern->matrix;
|
||||
|
@ -736,12 +705,6 @@ _directfb_prepare_composite (cairo_directfb_surface_t *dst,
|
|||
(cairo_surface_t **)&src, &src_attr);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = _directfb_acquire_surface (src, 0);
|
||||
if (ret) {
|
||||
_cairo_pattern_release_surface (src_pattern, &src->base, &src_attr);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
if (color.a != 0xff)
|
||||
|
@ -749,15 +712,15 @@ _directfb_prepare_composite (cairo_directfb_surface_t *dst,
|
|||
if (color.r != 0xff || color.g != 0xff || color.b != 0xff)
|
||||
flags |= DSBLIT_COLORIZE;
|
||||
|
||||
dst->buffer->SetBlittingFlags (dst->buffer, flags);
|
||||
dst->dfbsurface->SetBlittingFlags (dst->dfbsurface, flags);
|
||||
|
||||
if (flags & (DSBLIT_BLEND_COLORALPHA | DSBLIT_BLEND_ALPHACHANNEL)) {
|
||||
dst->buffer->SetSrcBlendFunction (dst->buffer, sblend);
|
||||
dst->buffer->SetDstBlendFunction (dst->buffer, dblend);
|
||||
dst->dfbsurface->SetSrcBlendFunction (dst->dfbsurface, sblend);
|
||||
dst->dfbsurface->SetDstBlendFunction (dst->dfbsurface, dblend);
|
||||
}
|
||||
|
||||
if (flags & (DSBLIT_BLEND_COLORALPHA | DSBLIT_COLORIZE))
|
||||
dst->buffer->SetColor (dst->buffer, color.r, color.g, color.b, color.a);
|
||||
dst->dfbsurface->SetColor (dst->dfbsurface, color.r, color.g, color.b, color.a);
|
||||
|
||||
*ret_src = src;
|
||||
*ret_src_attr = src_attr;
|
||||
|
@ -822,8 +785,8 @@ _cairo_directfb_surface_composite (cairo_operator_t op,
|
|||
D_DEBUG_AT (Cairo_DirectFB, "Running Blit().\n");
|
||||
|
||||
RUN_CLIPPED( dst, NULL,
|
||||
dst->buffer->Blit (dst->buffer,
|
||||
src->buffer, &sr, dst_x, dst_y));
|
||||
dst->dfbsurface->Blit (dst->dfbsurface,
|
||||
src->dfbsurface, &sr, dst_x, dst_y));
|
||||
ret = CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
else if (src_attr.extend == CAIRO_EXTEND_REPEAT) {
|
||||
|
@ -837,8 +800,8 @@ _cairo_directfb_surface_composite (cairo_operator_t op,
|
|||
D_DEBUG_AT (Cairo_DirectFB, "Running TileBlit().\n");
|
||||
|
||||
RUN_CLIPPED( dst, &clip,
|
||||
dst->buffer->TileBlit (dst->buffer,
|
||||
src->buffer, &sr, dst_x, dst_y));
|
||||
dst->dfbsurface->TileBlit (dst->dfbsurface,
|
||||
src->dfbsurface, &sr, dst_x, dst_y));
|
||||
ret = CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
}
|
||||
|
@ -852,7 +815,7 @@ _cairo_directfb_surface_composite (cairo_operator_t op,
|
|||
*/
|
||||
src_x = src_y = 0;
|
||||
|
||||
dst->buffer->GetAccelerationMask (dst->buffer, src->buffer, &accel);
|
||||
dst->dfbsurface->GetAccelerationMask (dst->dfbsurface, src->dfbsurface, &accel);
|
||||
|
||||
if (m->xy != 0.0 || m->yx != 0.0) {
|
||||
if (accel & DFXL_TEXTRIANGLES) {
|
||||
|
@ -898,8 +861,8 @@ _cairo_directfb_surface_composite (cairo_operator_t op,
|
|||
D_DEBUG_AT (Cairo_DirectFB, "Running TextureTriangles().\n");
|
||||
|
||||
RUN_CLIPPED (dst, NULL,
|
||||
dst->buffer->TextureTriangles (dst->buffer,
|
||||
src->buffer, v, NULL, 4, DTTF_FAN));
|
||||
dst->dfbsurface->TextureTriangles (dst->dfbsurface,
|
||||
src->dfbsurface, v, NULL, 4, DTTF_FAN));
|
||||
ret = CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
}
|
||||
|
@ -926,8 +889,8 @@ _cairo_directfb_surface_composite (cairo_operator_t op,
|
|||
D_DEBUG_AT (Cairo_DirectFB, "Running StretchBlit().\n");
|
||||
|
||||
RUN_CLIPPED (dst, NULL,
|
||||
dst->buffer->StretchBlit (dst->buffer,
|
||||
src->buffer, &sr, &dr));
|
||||
dst->dfbsurface->StretchBlit (dst->dfbsurface,
|
||||
src->dfbsurface, &sr, &dr));
|
||||
ret = CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
}
|
||||
|
@ -939,6 +902,7 @@ _cairo_directfb_surface_composite (cairo_operator_t op,
|
|||
}
|
||||
#endif /* DFB_COMPOSITE */
|
||||
|
||||
#if DFB_RECTANGLES
|
||||
static cairo_int_status_t
|
||||
_cairo_directfb_surface_fill_rectangles (void *abstract_surface,
|
||||
cairo_operator_t op,
|
||||
|
@ -947,7 +911,6 @@ _cairo_directfb_surface_fill_rectangles (void *abstract_surface,
|
|||
int n_rects)
|
||||
{
|
||||
cairo_directfb_surface_t *dst = abstract_surface;
|
||||
cairo_status_t ret;
|
||||
DFBSurfaceDrawingFlags flags;
|
||||
DFBSurfaceBlendFunction sblend;
|
||||
DFBSurfaceBlendFunction dblend;
|
||||
|
@ -961,17 +924,13 @@ _cairo_directfb_surface_fill_rectangles (void *abstract_surface,
|
|||
if (_directfb_get_operator (op, &flags, NULL, &sblend, &dblend))
|
||||
return CAIRO_INT_STATUS_UNSUPPORTED;
|
||||
|
||||
ret = _directfb_acquire_surface (dst, 0);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
dst->buffer->SetDrawingFlags (dst->buffer, flags);
|
||||
dst->dfbsurface->SetDrawingFlags (dst->dfbsurface, flags);
|
||||
if (flags & DSDRAW_BLEND) {
|
||||
dst->buffer->SetSrcBlendFunction (dst->buffer, sblend);
|
||||
dst->buffer->SetDstBlendFunction (dst->buffer, dblend);
|
||||
dst->dfbsurface->SetSrcBlendFunction (dst->dfbsurface, sblend);
|
||||
dst->dfbsurface->SetDstBlendFunction (dst->dfbsurface, dblend);
|
||||
}
|
||||
|
||||
dst->buffer->SetColor (dst->buffer, color->red_short >> 8,
|
||||
dst->dfbsurface->SetColor (dst->dfbsurface, color->red_short >> 8,
|
||||
color->green_short >> 8,
|
||||
color->blue_short >> 8,
|
||||
color->alpha_short >> 8 );
|
||||
|
@ -984,10 +943,11 @@ _cairo_directfb_surface_fill_rectangles (void *abstract_surface,
|
|||
}
|
||||
|
||||
RUN_CLIPPED (dst, NULL,
|
||||
dst->buffer->FillRectangles (dst->buffer, r, n_rects));
|
||||
dst->dfbsurface->FillRectangles (dst->dfbsurface, r, n_rects));
|
||||
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if DFB_COMPOSITE_TRAPEZOIDS
|
||||
static cairo_int_status_t
|
||||
|
@ -1028,7 +988,7 @@ _cairo_directfb_surface_composite_trapezoids (cairo_operator_t op,
|
|||
if (ret)
|
||||
return ret;
|
||||
|
||||
dst->buffer->GetAccelerationMask (dst->buffer, src->buffer, &accel);
|
||||
dst->dfbsurface->GetAccelerationMask (dst->dfbsurface, src->dfbsurface, &accel);
|
||||
|
||||
ret = CAIRO_INT_STATUS_UNSUPPORTED;
|
||||
|
||||
|
@ -1118,7 +1078,7 @@ _cairo_directfb_surface_composite_trapezoids (cairo_operator_t op,
|
|||
D_DEBUG_AT (Cairo_DirectFB, "Running TextureTriangles().\n");
|
||||
|
||||
RUN_CLIPPED (dst, NULL,
|
||||
dst->buffer->TextureTriangles (dst->buffer, src->buffer,
|
||||
dst->dfbsurface->TextureTriangles (dst->dfbsurface, src->dfbsurface,
|
||||
vertex, NULL, n, DTTF_LIST));
|
||||
|
||||
ret = CAIRO_STATUS_SUCCESS;
|
||||
|
@ -1146,7 +1106,8 @@ _cairo_directfb_surface_set_clip_region (void *abstract_surface,
|
|||
int i;
|
||||
|
||||
if (surface->n_clips != n_boxes) {
|
||||
free (surface->clips);
|
||||
if( surface->clips )
|
||||
free (surface->clips);
|
||||
|
||||
surface->clips = malloc (n_boxes * sizeof(DFBRegion));
|
||||
if (!surface->clips) {
|
||||
|
@ -1202,25 +1163,24 @@ _cairo_directfb_surface_mark_dirty_rectangle (void *abstract_surface,
|
|||
int width,
|
||||
int height)
|
||||
{
|
||||
#if 0
|
||||
cairo_directfb_surface_t *surface = abstract_surface;
|
||||
|
||||
D_DEBUG_AT (Cairo_DirectFB,
|
||||
"%s( surface=%p, x=%d, y=%d, width=%d, height=%d ).\n",
|
||||
__FUNCTION__, surface, x, y, width, height);
|
||||
|
||||
if (surface->surface != surface->buffer) {
|
||||
DFBRegion region = { x1:x, y1:y, x2:x+width-1, y2:y+height-1 };
|
||||
surface->buffer->SetClip (surface->buffer, ®ion);
|
||||
surface->buffer->SetBlittingFlags (surface->buffer, DSBLIT_NOFX);
|
||||
surface->buffer->Blit (surface->buffer, surface->surface, NULL, 0, 0);
|
||||
}
|
||||
|
||||
if( !surface->dirty_region )
|
||||
surface->dirty_region = malloc(sizeof(DFBRegion));
|
||||
if (!dirty_region)
|
||||
return CAIRO_STATUS_NO_MEMORY;
|
||||
#endif
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
static cairo_status_t
|
||||
_cairo_directfb_surface_flush (void *abstract_surface)
|
||||
{
|
||||
#if 0
|
||||
cairo_directfb_surface_t *surface = abstract_surface;
|
||||
|
||||
D_DEBUG_AT (Cairo_DirectFB,
|
||||
|
@ -1231,7 +1191,7 @@ _cairo_directfb_surface_flush (void *abstract_surface)
|
|||
surface->surface->SetBlittingFlags (surface->surface, DSBLIT_NOFX);
|
||||
surface->surface->Blit (surface->surface, surface->buffer, NULL, 0, 0);
|
||||
}
|
||||
|
||||
#endif
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
|
@ -1245,13 +1205,13 @@ _directfb_allocate_font_cache (IDirectFB *dfb, int width, int height)
|
|||
if (!cache)
|
||||
return NULL;
|
||||
|
||||
cache->buffer = _directfb_buffer_surface_create( dfb, DSPF_A8, width, height);
|
||||
if (!cache->buffer) {
|
||||
cache->dfbsurface = _directfb_buffer_surface_create( dfb, DSPF_A8, width, height);
|
||||
if (!cache->dfbsurface) {
|
||||
free (cache);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
dfb->AddRef (dfb);
|
||||
//dfb->AddRef (dfb);
|
||||
cache->dfb = dfb;
|
||||
|
||||
cache->width = width;
|
||||
|
@ -1263,8 +1223,7 @@ _directfb_allocate_font_cache (IDirectFB *dfb, int width, int height)
|
|||
static void
|
||||
_directfb_destroy_font_cache (cairo_directfb_font_cache_t *cache)
|
||||
{
|
||||
cache->buffer->Release (cache->buffer);
|
||||
cache->dfb->Release (cache->dfb);
|
||||
cache->dfbsurface->Release (cache->dfbsurface);
|
||||
free (cache);
|
||||
}
|
||||
|
||||
|
@ -1386,8 +1345,8 @@ _directfb_acquire_font_cache (cairo_directfb_surface_t *surface,
|
|||
if (!new_cache)
|
||||
return CAIRO_STATUS_NO_MEMORY;
|
||||
|
||||
new_cache->buffer->Blit (new_cache->buffer,
|
||||
cache->buffer, NULL, 0, 0);
|
||||
new_cache->dfbsurface->Blit (new_cache->dfbsurface,
|
||||
cache->dfbsurface, NULL, 0, 0);
|
||||
|
||||
_directfb_destroy_font_cache (cache);
|
||||
scaled_font->surface_private = cache = new_cache;
|
||||
|
@ -1409,7 +1368,7 @@ _directfb_acquire_font_cache (cairo_directfb_surface_t *surface,
|
|||
unsigned char *data;
|
||||
int pitch;
|
||||
|
||||
if (cache->buffer->Lock (cache->buffer,
|
||||
if (cache->dfbsurface->Lock (cache->dfbsurface,
|
||||
DSLF_WRITE, (void *)&data, &pitch))
|
||||
return CAIRO_STATUS_NO_MEMORY;
|
||||
|
||||
|
@ -1437,7 +1396,7 @@ _directfb_acquire_font_cache (cairo_directfb_surface_t *surface,
|
|||
}
|
||||
}
|
||||
|
||||
cache->buffer->Unlock (cache->buffer);
|
||||
cache->dfbsurface->Unlock (cache->dfbsurface);
|
||||
}
|
||||
|
||||
cache->x = x;
|
||||
|
@ -1509,10 +1468,6 @@ _cairo_directfb_surface_show_glyphs ( void *abstract_dst,
|
|||
sblend == DSBF_DESTALPHA || sblend == DSBF_INVDESTALPHA)
|
||||
return CAIRO_INT_STATUS_UNSUPPORTED;
|
||||
|
||||
ret = _directfb_acquire_surface (dst, 0);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = _directfb_acquire_font_cache (dst, scaled_font, glyphs, num_glyphs,
|
||||
&cache, &rects[0], &points[0], &num);
|
||||
if (ret) {
|
||||
|
@ -1536,16 +1491,16 @@ _cairo_directfb_surface_show_glyphs ( void *abstract_dst,
|
|||
dblend = DSBF_INVSRCALPHA;
|
||||
}
|
||||
|
||||
dst->buffer->SetBlittingFlags (dst->buffer, flags);
|
||||
dst->buffer->SetSrcBlendFunction (dst->buffer, sblend);
|
||||
dst->buffer->SetDstBlendFunction (dst->buffer, dblend);
|
||||
dst->buffer->SetColor (dst->buffer, color.r, color.g, color.b, color.a);
|
||||
dst->dfbsurface->SetBlittingFlags (dst->dfbsurface, flags);
|
||||
dst->dfbsurface->SetSrcBlendFunction (dst->dfbsurface, sblend);
|
||||
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");
|
||||
|
||||
RUN_CLIPPED (dst, NULL,
|
||||
dst->buffer->BatchBlit (dst->buffer,
|
||||
cache->buffer, rects, points, num));
|
||||
dst->dfbsurface->BatchBlit (dst->dfbsurface,
|
||||
cache->dfbsurface, rects, points, num));
|
||||
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
|
@ -1566,7 +1521,11 @@ static cairo_surface_backend_t cairo_directfb_surface_backend = {
|
|||
#else
|
||||
NULL,/*composite*/
|
||||
#endif
|
||||
#if DFB_RECTANGLES
|
||||
_cairo_directfb_surface_fill_rectangles,/*fill_rectangles*/
|
||||
#else
|
||||
NULL,/*fill_rectangles*/
|
||||
#endif
|
||||
#if DFB_COMPOSITE_TRAPEZOIDS
|
||||
_cairo_directfb_surface_composite_trapezoids,/*composite_trapezoids*/
|
||||
#else
|
||||
|
@ -1642,27 +1601,23 @@ cairo_directfb_surface_create (IDirectFB *dfb, IDirectFBSurface *dfbsurface)
|
|||
{
|
||||
DFBSurfacePixelFormat format;
|
||||
cairo_directfb_surface_t *surface;
|
||||
|
||||
|
||||
assert(dfb);
|
||||
assert(dfb);
|
||||
cairo_directfb_surface_backend_init (dfb);
|
||||
|
||||
surface = calloc (1, sizeof(cairo_directfb_surface_t));
|
||||
if (!surface)
|
||||
if (!surface)
|
||||
return NULL;
|
||||
|
||||
dfbsurface->GetPixelFormat (dfbsurface, &format);
|
||||
_cairo_surface_init (&surface->base, &cairo_directfb_surface_backend,
|
||||
_directfb_format_to_content(format));
|
||||
|
||||
dfb->AddRef (dfb);
|
||||
surface->owner = FALSE;
|
||||
surface->dfb = dfb;
|
||||
dfbsurface->AddRef (dfbsurface);
|
||||
surface->surface = dfbsurface;
|
||||
|
||||
if (_directfb_acquire_surface (surface, 0)) {
|
||||
cairo_surface_destroy ((cairo_surface_t *)surface);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
surface->dfbsurface = dfbsurface;
|
||||
dfbsurface->GetSize (dfbsurface,&surface->width, &surface->height);
|
||||
surface->format = directfb_to_cairo_format(format);
|
||||
return &surface->base;
|
||||
}
|
||||
|
||||
|
|
|
@ -43,7 +43,8 @@
|
|||
|
||||
CAIRO_BEGIN_DECLS
|
||||
|
||||
cairo_surface_t * cairo_directfb_surface_create (IDirectFB *dfb,IDirectFBSurface *surface);
|
||||
cairo_public cairo_surface_t *
|
||||
cairo_directfb_surface_create (IDirectFB *dfb,IDirectFBSurface *surface);
|
||||
|
||||
CAIRO_END_DECLS
|
||||
|
||||
|
|
|
@ -95,6 +95,7 @@ cairo_font_options_create (void)
|
|||
|
||||
return options;
|
||||
}
|
||||
slim_hidden_def (cairo_font_options_create);
|
||||
|
||||
/**
|
||||
* cairo_font_options_copy:
|
||||
|
@ -137,6 +138,7 @@ cairo_font_options_destroy (cairo_font_options_t *options)
|
|||
|
||||
free (options);
|
||||
}
|
||||
slim_hidden_def (cairo_font_options_destroy);
|
||||
|
||||
/**
|
||||
* cairo_font_options_status:
|
||||
|
@ -182,6 +184,7 @@ cairo_font_options_merge (cairo_font_options_t *options,
|
|||
if (other->hint_metrics != CAIRO_HINT_METRICS_DEFAULT)
|
||||
options->hint_metrics = other->hint_metrics;
|
||||
}
|
||||
slim_hidden_def (cairo_font_options_merge);
|
||||
|
||||
/**
|
||||
* cairo_font_options_equal:
|
||||
|
@ -201,6 +204,7 @@ cairo_font_options_equal (const cairo_font_options_t *options,
|
|||
options->hint_style == other->hint_style &&
|
||||
options->hint_metrics == other->hint_metrics);
|
||||
}
|
||||
slim_hidden_def (cairo_font_options_equal);
|
||||
|
||||
/**
|
||||
* cairo_font_options_hash:
|
||||
|
@ -222,6 +226,7 @@ cairo_font_options_hash (const cairo_font_options_t *options)
|
|||
(options->hint_style << 8) |
|
||||
(options->hint_metrics << 16));
|
||||
}
|
||||
slim_hidden_def (cairo_font_options_hash);
|
||||
|
||||
/**
|
||||
* cairo_font_options_set_antialias:
|
||||
|
@ -240,6 +245,7 @@ cairo_font_options_set_antialias (cairo_font_options_t *options,
|
|||
|
||||
options->antialias = antialias;
|
||||
}
|
||||
slim_hidden_def (cairo_font_options_set_antialias);
|
||||
|
||||
/**
|
||||
* cairo_font_options_get_antialias:
|
||||
|
@ -275,6 +281,7 @@ cairo_font_options_set_subpixel_order (cairo_font_options_t *options,
|
|||
|
||||
options->subpixel_order = subpixel_order;
|
||||
}
|
||||
slim_hidden_def (cairo_font_options_set_subpixel_order);
|
||||
|
||||
/**
|
||||
* cairo_font_options_get_subpixel_order:
|
||||
|
@ -310,6 +317,7 @@ cairo_font_options_set_hint_style (cairo_font_options_t *options,
|
|||
|
||||
options->hint_style = hint_style;
|
||||
}
|
||||
slim_hidden_def (cairo_font_options_set_hint_style);
|
||||
|
||||
/**
|
||||
* cairo_font_options_get_hint_style:
|
||||
|
@ -345,6 +353,7 @@ cairo_font_options_set_hint_metrics (cairo_font_options_t *options,
|
|||
|
||||
options->hint_metrics = hint_metrics;
|
||||
}
|
||||
slim_hidden_def (cairo_font_options_set_hint_metrics);
|
||||
|
||||
/**
|
||||
* cairo_font_options_get_hint_metrics:
|
||||
|
|
|
@ -1,812 +0,0 @@
|
|||
/* cairo - a vector graphics library with display and print output
|
||||
*
|
||||
* Copyright © 2004 Red Hat, Inc
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it either under the terms of the GNU Lesser General Public
|
||||
* License version 2.1 as published by the Free Software Foundation
|
||||
* (the "LGPL") or, at your option, under the terms of the Mozilla
|
||||
* Public License Version 1.1 (the "MPL"). If you do not alter this
|
||||
* notice, a recipient may use your version of this file under either
|
||||
* the MPL or the LGPL.
|
||||
*
|
||||
* You should have received a copy of the LGPL along with this library
|
||||
* in the file COPYING-LGPL-2.1; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
* You should have received a copy of the MPL along with this library
|
||||
* in the file COPYING-MPL-1.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License
|
||||
* Version 1.1 (the "License"); you may not use this file except in
|
||||
* compliance with the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY
|
||||
* OF ANY KIND, either express or implied. See the LGPL or the MPL for
|
||||
* the specific language governing rights and limitations.
|
||||
*
|
||||
* The Original Code is the cairo graphics library.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Red Hat, Inc.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Kristian Høgsberg <krh@redhat.com>
|
||||
*/
|
||||
|
||||
#include "cairoint.h"
|
||||
#include "cairo-scaled-font-subsets-private.h"
|
||||
|
||||
/* XXX: Eventually, we need to handle other font backends */
|
||||
#include "cairo-ft-private.h"
|
||||
|
||||
#include <ft2build.h>
|
||||
#include FT_FREETYPE_H
|
||||
#include FT_OUTLINE_H
|
||||
#include FT_TRUETYPE_TAGS_H
|
||||
#include FT_TRUETYPE_TABLES_H
|
||||
|
||||
typedef struct ft_subset_glyph ft_subset_glyph_t;
|
||||
struct ft_subset_glyph {
|
||||
int parent_index;
|
||||
unsigned long location;
|
||||
};
|
||||
|
||||
typedef struct _cairo_ft_font {
|
||||
|
||||
cairo_scaled_font_subset_t *scaled_font_subset;
|
||||
|
||||
struct {
|
||||
cairo_unscaled_font_t *unscaled_font;
|
||||
unsigned int font_id;
|
||||
char *base_font;
|
||||
int num_glyphs;
|
||||
int *widths;
|
||||
long x_min, y_min, x_max, y_max;
|
||||
long ascent, descent;
|
||||
} base;
|
||||
|
||||
ft_subset_glyph_t *glyphs;
|
||||
FT_Face face;
|
||||
int checksum_index;
|
||||
cairo_array_t output;
|
||||
int *parent_to_subset;
|
||||
cairo_status_t status;
|
||||
|
||||
} cairo_pdf_ft_font_t;
|
||||
|
||||
static int
|
||||
cairo_pdf_ft_font_use_glyph (cairo_pdf_ft_font_t *font, int glyph);
|
||||
|
||||
#define ARRAY_LENGTH(a) ( (sizeof (a)) / (sizeof ((a)[0])) )
|
||||
|
||||
#define SFNT_VERSION 0x00010000
|
||||
|
||||
#ifdef WORDS_BIGENDIAN
|
||||
|
||||
#define cpu_to_be16(v) (v)
|
||||
#define be16_to_cpu(v) (v)
|
||||
#define cpu_to_be32(v) (v)
|
||||
#define be32_to_cpu(v) (v)
|
||||
|
||||
#else
|
||||
|
||||
static inline unsigned short
|
||||
cpu_to_be16(unsigned short v)
|
||||
{
|
||||
return (v << 8) | (v >> 8);
|
||||
}
|
||||
|
||||
static inline unsigned short
|
||||
be16_to_cpu(unsigned short v)
|
||||
{
|
||||
return cpu_to_be16 (v);
|
||||
}
|
||||
|
||||
static inline unsigned long
|
||||
cpu_to_be32(unsigned long v)
|
||||
{
|
||||
return (cpu_to_be16 (v) << 16) | cpu_to_be16 (v >> 16);
|
||||
}
|
||||
|
||||
static inline unsigned long
|
||||
be32_to_cpu(unsigned long v)
|
||||
{
|
||||
return cpu_to_be32 (v);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
static cairo_status_t
|
||||
_cairo_pdf_ft_font_create (cairo_scaled_font_subset_t *scaled_font_subset,
|
||||
cairo_pdf_ft_font_t **font_return)
|
||||
{
|
||||
cairo_unscaled_font_t *unscaled_font;
|
||||
cairo_ft_unscaled_font_t *ft_unscaled_font;
|
||||
cairo_status_t status = CAIRO_STATUS_NO_MEMORY;
|
||||
cairo_pdf_ft_font_t *font;
|
||||
FT_Face face;
|
||||
unsigned long size;
|
||||
int i, j;
|
||||
|
||||
/* XXX: Need to fix this to work with a general cairo_unscaled_font_t. */
|
||||
if (!_cairo_scaled_font_is_ft (scaled_font_subset->scaled_font))
|
||||
return CAIRO_INT_STATUS_UNSUPPORTED;
|
||||
|
||||
if (_cairo_ft_scaled_font_is_vertical (scaled_font_subset->scaled_font))
|
||||
return CAIRO_INT_STATUS_UNSUPPORTED;
|
||||
|
||||
unscaled_font = _cairo_ft_scaled_font_get_unscaled_font (scaled_font_subset->scaled_font);
|
||||
|
||||
ft_unscaled_font = (cairo_ft_unscaled_font_t *) unscaled_font;
|
||||
|
||||
face = _cairo_ft_unscaled_font_lock_face (ft_unscaled_font);
|
||||
if (face == NULL)
|
||||
/* Assume out of memory */
|
||||
return CAIRO_STATUS_NO_MEMORY;
|
||||
|
||||
/* We currently only support freetype truetype fonts. */
|
||||
size = 0;
|
||||
if (!FT_IS_SFNT (face) ||
|
||||
FT_Load_Sfnt_Table (face, TTAG_glyf, 0, NULL, &size) != 0)
|
||||
return CAIRO_INT_STATUS_UNSUPPORTED;
|
||||
|
||||
font = malloc (sizeof (cairo_pdf_ft_font_t));
|
||||
if (font == NULL)
|
||||
return CAIRO_STATUS_NO_MEMORY;
|
||||
|
||||
font->scaled_font_subset = scaled_font_subset;
|
||||
|
||||
font->base.unscaled_font = _cairo_unscaled_font_reference (unscaled_font);
|
||||
|
||||
_cairo_array_init (&font->output, sizeof (char));
|
||||
if (_cairo_array_grow_by (&font->output, 4096) != CAIRO_STATUS_SUCCESS)
|
||||
goto fail1;
|
||||
|
||||
font->glyphs = calloc (face->num_glyphs + 1, sizeof (ft_subset_glyph_t));
|
||||
if (font->glyphs == NULL)
|
||||
goto fail2;
|
||||
|
||||
font->parent_to_subset = calloc (face->num_glyphs, sizeof (int));
|
||||
if (font->parent_to_subset == NULL)
|
||||
goto fail3;
|
||||
|
||||
font->base.num_glyphs = 0;
|
||||
font->base.x_min = face->bbox.xMin;
|
||||
font->base.y_min = face->bbox.yMin;
|
||||
font->base.x_max = face->bbox.xMax;
|
||||
font->base.y_max = face->bbox.yMax;
|
||||
font->base.ascent = face->ascender;
|
||||
font->base.descent = face->descender;
|
||||
font->base.base_font = strdup (face->family_name);
|
||||
if (font->base.base_font == NULL)
|
||||
goto fail4;
|
||||
|
||||
for (i = 0, j = 0; font->base.base_font[j]; j++) {
|
||||
if (font->base.base_font[j] == ' ')
|
||||
continue;
|
||||
font->base.base_font[i++] = font->base.base_font[j];
|
||||
}
|
||||
font->base.base_font[i] = '\0';
|
||||
|
||||
font->base.widths = calloc (face->num_glyphs, sizeof (int));
|
||||
if (font->base.widths == NULL)
|
||||
goto fail5;
|
||||
|
||||
_cairo_ft_unscaled_font_unlock_face (ft_unscaled_font);
|
||||
|
||||
font->status = CAIRO_STATUS_SUCCESS;
|
||||
|
||||
*font_return = font;
|
||||
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
|
||||
fail5:
|
||||
free (font->base.base_font);
|
||||
fail4:
|
||||
free (font->parent_to_subset);
|
||||
fail3:
|
||||
free (font->glyphs);
|
||||
fail2:
|
||||
_cairo_array_fini (&font->output);
|
||||
fail1:
|
||||
free (font);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
static void
|
||||
cairo_pdf_ft_font_destroy (cairo_pdf_ft_font_t *font)
|
||||
{
|
||||
_cairo_unscaled_font_destroy (font->base.unscaled_font);
|
||||
free (font->base.base_font);
|
||||
free (font->parent_to_subset);
|
||||
free (font->glyphs);
|
||||
_cairo_array_fini (&font->output);
|
||||
free (font);
|
||||
}
|
||||
|
||||
static cairo_status_t
|
||||
cairo_pdf_ft_font_allocate_write_buffer (cairo_pdf_ft_font_t *font,
|
||||
size_t length,
|
||||
unsigned char **buffer)
|
||||
{
|
||||
cairo_status_t status;
|
||||
|
||||
status = _cairo_array_allocate (&font->output, length, (void **) buffer);
|
||||
if (status)
|
||||
return status;
|
||||
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
static cairo_status_t
|
||||
cairo_pdf_ft_font_write (cairo_pdf_ft_font_t *font,
|
||||
const void *data, size_t length)
|
||||
{
|
||||
cairo_status_t status;
|
||||
|
||||
status = _cairo_array_append_multiple (&font->output, data, length);
|
||||
if (status)
|
||||
return status;
|
||||
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
static void
|
||||
cairo_pdf_ft_font_write_be16 (cairo_pdf_ft_font_t *font,
|
||||
unsigned short value)
|
||||
{
|
||||
unsigned short be16_value;
|
||||
|
||||
be16_value = cpu_to_be16 (value);
|
||||
cairo_pdf_ft_font_write (font, &be16_value, sizeof be16_value);
|
||||
}
|
||||
|
||||
static void
|
||||
cairo_pdf_ft_font_write_be32 (cairo_pdf_ft_font_t *font, unsigned long value)
|
||||
{
|
||||
unsigned long be32_value;
|
||||
|
||||
be32_value = cpu_to_be32 (value);
|
||||
cairo_pdf_ft_font_write (font, &be32_value, sizeof be32_value);
|
||||
}
|
||||
|
||||
static unsigned long
|
||||
cairo_pdf_ft_font_align_output (cairo_pdf_ft_font_t *font)
|
||||
{
|
||||
int length, aligned, pad;
|
||||
unsigned char *ignored;
|
||||
|
||||
length = _cairo_array_num_elements (&font->output);
|
||||
aligned = (length + 3) & ~3;
|
||||
pad = aligned - length;
|
||||
|
||||
if (pad)
|
||||
cairo_pdf_ft_font_allocate_write_buffer (font, pad, &ignored);
|
||||
|
||||
return aligned;
|
||||
}
|
||||
|
||||
static int
|
||||
cairo_pdf_ft_font_write_cmap_table (cairo_pdf_ft_font_t *font, unsigned long tag)
|
||||
{
|
||||
int i;
|
||||
|
||||
cairo_pdf_ft_font_write_be16 (font, 0);
|
||||
cairo_pdf_ft_font_write_be16 (font, 1);
|
||||
|
||||
cairo_pdf_ft_font_write_be16 (font, 1);
|
||||
cairo_pdf_ft_font_write_be16 (font, 0);
|
||||
cairo_pdf_ft_font_write_be32 (font, 12);
|
||||
|
||||
/* Output a format 6 encoding table. */
|
||||
|
||||
cairo_pdf_ft_font_write_be16 (font, 6);
|
||||
cairo_pdf_ft_font_write_be16 (font, 10 + 2 * (font->base.num_glyphs - 1));
|
||||
cairo_pdf_ft_font_write_be16 (font, 0);
|
||||
cairo_pdf_ft_font_write_be16 (font, 1); /* First glyph */
|
||||
cairo_pdf_ft_font_write_be16 (font, font->base.num_glyphs - 1);
|
||||
for (i = 1; i < font->base.num_glyphs; i++)
|
||||
cairo_pdf_ft_font_write_be16 (font, i);
|
||||
|
||||
return font->status;
|
||||
}
|
||||
|
||||
static int
|
||||
cairo_pdf_ft_font_write_generic_table (cairo_pdf_ft_font_t *font,
|
||||
unsigned long tag)
|
||||
{
|
||||
cairo_status_t status;
|
||||
unsigned char *buffer;
|
||||
unsigned long size;
|
||||
|
||||
size = 0;
|
||||
FT_Load_Sfnt_Table (font->face, tag, 0, NULL, &size);
|
||||
status = cairo_pdf_ft_font_allocate_write_buffer (font, size, &buffer);
|
||||
/* XXX: Need to check status here. */
|
||||
FT_Load_Sfnt_Table (font->face, tag, 0, buffer, &size);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
typedef struct composite_glyph composite_glyph_t;
|
||||
struct composite_glyph {
|
||||
unsigned short flags;
|
||||
unsigned short index;
|
||||
unsigned short args[7]; /* 1 to 7 arguments depending on value of flags */
|
||||
};
|
||||
|
||||
typedef struct glyph_data glyph_data_t;
|
||||
struct glyph_data {
|
||||
short num_contours;
|
||||
char data[8];
|
||||
composite_glyph_t glyph;
|
||||
};
|
||||
|
||||
/* composite_glyph_t flags */
|
||||
#define ARG_1_AND_2_ARE_WORDS 0x0001
|
||||
#define WE_HAVE_A_SCALE 0x0008
|
||||
#define MORE_COMPONENTS 0x0020
|
||||
#define WE_HAVE_AN_X_AND_Y_SCALE 0x0040
|
||||
#define WE_HAVE_A_TWO_BY_TWO 0x0080
|
||||
|
||||
static void
|
||||
cairo_pdf_ft_font_remap_composite_glyph (cairo_pdf_ft_font_t *font,
|
||||
unsigned char *buffer)
|
||||
{
|
||||
glyph_data_t *glyph_data;
|
||||
composite_glyph_t *composite_glyph;
|
||||
int num_args;
|
||||
int has_more_components;
|
||||
unsigned short flags;
|
||||
unsigned short index;
|
||||
|
||||
glyph_data = (glyph_data_t *) buffer;
|
||||
if ((short)be16_to_cpu (glyph_data->num_contours) >= 0)
|
||||
return;
|
||||
|
||||
composite_glyph = &glyph_data->glyph;
|
||||
do {
|
||||
flags = be16_to_cpu (composite_glyph->flags);
|
||||
has_more_components = flags & MORE_COMPONENTS;
|
||||
index = cairo_pdf_ft_font_use_glyph (font, be16_to_cpu (composite_glyph->index));
|
||||
composite_glyph->index = cpu_to_be16 (index);
|
||||
num_args = 1;
|
||||
if (flags & ARG_1_AND_2_ARE_WORDS)
|
||||
num_args += 1;
|
||||
if (flags & WE_HAVE_A_SCALE)
|
||||
num_args += 1;
|
||||
else if (flags & WE_HAVE_AN_X_AND_Y_SCALE)
|
||||
num_args += 2;
|
||||
else if (flags & WE_HAVE_A_TWO_BY_TWO)
|
||||
num_args += 3;
|
||||
composite_glyph = (composite_glyph_t *) &(composite_glyph->args[num_args]);
|
||||
} while (has_more_components);
|
||||
}
|
||||
|
||||
static int
|
||||
cairo_pdf_ft_font_write_glyf_table (cairo_pdf_ft_font_t *font,
|
||||
unsigned long tag)
|
||||
{
|
||||
cairo_status_t status;
|
||||
unsigned long start_offset, index, size;
|
||||
TT_Header *header;
|
||||
unsigned long begin, end;
|
||||
unsigned char *buffer;
|
||||
int i;
|
||||
union {
|
||||
unsigned char *bytes;
|
||||
unsigned short *short_offsets;
|
||||
unsigned long *long_offsets;
|
||||
} u;
|
||||
|
||||
header = FT_Get_Sfnt_Table (font->face, ft_sfnt_head);
|
||||
if (header->Index_To_Loc_Format == 0)
|
||||
size = sizeof (short) * (font->face->num_glyphs + 1);
|
||||
else
|
||||
size = sizeof (long) * (font->face->num_glyphs + 1);
|
||||
|
||||
u.bytes = malloc (size);
|
||||
if (u.bytes == NULL) {
|
||||
font->status = CAIRO_STATUS_NO_MEMORY;
|
||||
return font->status;
|
||||
}
|
||||
FT_Load_Sfnt_Table (font->face, TTAG_loca, 0, u.bytes, &size);
|
||||
|
||||
start_offset = _cairo_array_num_elements (&font->output);
|
||||
for (i = 0; i < font->base.num_glyphs; i++) {
|
||||
index = font->glyphs[i].parent_index;
|
||||
if (header->Index_To_Loc_Format == 0) {
|
||||
begin = be16_to_cpu (u.short_offsets[index]) * 2;
|
||||
end = be16_to_cpu (u.short_offsets[index + 1]) * 2;
|
||||
}
|
||||
else {
|
||||
begin = be32_to_cpu (u.long_offsets[index]);
|
||||
end = be32_to_cpu (u.long_offsets[index + 1]);
|
||||
}
|
||||
|
||||
size = end - begin;
|
||||
|
||||
font->glyphs[i].location =
|
||||
cairo_pdf_ft_font_align_output (font) - start_offset;
|
||||
status = cairo_pdf_ft_font_allocate_write_buffer (font, size, &buffer);
|
||||
if (status)
|
||||
break;
|
||||
if (size != 0) {
|
||||
FT_Load_Sfnt_Table (font->face, TTAG_glyf, begin, buffer, &size);
|
||||
cairo_pdf_ft_font_remap_composite_glyph (font, buffer);
|
||||
}
|
||||
}
|
||||
|
||||
font->glyphs[i].location =
|
||||
cairo_pdf_ft_font_align_output (font) - start_offset;
|
||||
|
||||
free (u.bytes);
|
||||
|
||||
return font->status;
|
||||
}
|
||||
|
||||
static int
|
||||
cairo_pdf_ft_font_write_head_table (cairo_pdf_ft_font_t *font,
|
||||
unsigned long tag)
|
||||
{
|
||||
TT_Header *head;
|
||||
|
||||
head = FT_Get_Sfnt_Table (font->face, ft_sfnt_head);
|
||||
|
||||
cairo_pdf_ft_font_write_be32 (font, head->Table_Version);
|
||||
cairo_pdf_ft_font_write_be32 (font, head->Font_Revision);
|
||||
|
||||
font->checksum_index = _cairo_array_num_elements (&font->output);
|
||||
cairo_pdf_ft_font_write_be32 (font, 0);
|
||||
cairo_pdf_ft_font_write_be32 (font, head->Magic_Number);
|
||||
|
||||
cairo_pdf_ft_font_write_be16 (font, head->Flags);
|
||||
cairo_pdf_ft_font_write_be16 (font, head->Units_Per_EM);
|
||||
|
||||
cairo_pdf_ft_font_write_be32 (font, head->Created[0]);
|
||||
cairo_pdf_ft_font_write_be32 (font, head->Created[1]);
|
||||
cairo_pdf_ft_font_write_be32 (font, head->Modified[0]);
|
||||
cairo_pdf_ft_font_write_be32 (font, head->Modified[1]);
|
||||
|
||||
cairo_pdf_ft_font_write_be16 (font, head->xMin);
|
||||
cairo_pdf_ft_font_write_be16 (font, head->yMin);
|
||||
cairo_pdf_ft_font_write_be16 (font, head->xMax);
|
||||
cairo_pdf_ft_font_write_be16 (font, head->yMax);
|
||||
|
||||
cairo_pdf_ft_font_write_be16 (font, head->Mac_Style);
|
||||
cairo_pdf_ft_font_write_be16 (font, head->Lowest_Rec_PPEM);
|
||||
|
||||
cairo_pdf_ft_font_write_be16 (font, head->Font_Direction);
|
||||
cairo_pdf_ft_font_write_be16 (font, head->Index_To_Loc_Format);
|
||||
cairo_pdf_ft_font_write_be16 (font, head->Glyph_Data_Format);
|
||||
|
||||
return font->status;
|
||||
}
|
||||
|
||||
static int cairo_pdf_ft_font_write_hhea_table (cairo_pdf_ft_font_t *font, unsigned long tag)
|
||||
{
|
||||
TT_HoriHeader *hhea;
|
||||
|
||||
hhea = FT_Get_Sfnt_Table (font->face, ft_sfnt_hhea);
|
||||
|
||||
cairo_pdf_ft_font_write_be32 (font, hhea->Version);
|
||||
cairo_pdf_ft_font_write_be16 (font, hhea->Ascender);
|
||||
cairo_pdf_ft_font_write_be16 (font, hhea->Descender);
|
||||
cairo_pdf_ft_font_write_be16 (font, hhea->Line_Gap);
|
||||
|
||||
cairo_pdf_ft_font_write_be16 (font, hhea->advance_Width_Max);
|
||||
|
||||
cairo_pdf_ft_font_write_be16 (font, hhea->min_Left_Side_Bearing);
|
||||
cairo_pdf_ft_font_write_be16 (font, hhea->min_Right_Side_Bearing);
|
||||
cairo_pdf_ft_font_write_be16 (font, hhea->xMax_Extent);
|
||||
cairo_pdf_ft_font_write_be16 (font, hhea->caret_Slope_Rise);
|
||||
cairo_pdf_ft_font_write_be16 (font, hhea->caret_Slope_Run);
|
||||
cairo_pdf_ft_font_write_be16 (font, hhea->caret_Offset);
|
||||
|
||||
cairo_pdf_ft_font_write_be16 (font, 0);
|
||||
cairo_pdf_ft_font_write_be16 (font, 0);
|
||||
cairo_pdf_ft_font_write_be16 (font, 0);
|
||||
cairo_pdf_ft_font_write_be16 (font, 0);
|
||||
|
||||
cairo_pdf_ft_font_write_be16 (font, hhea->metric_Data_Format);
|
||||
cairo_pdf_ft_font_write_be16 (font, font->base.num_glyphs);
|
||||
|
||||
return font->status;
|
||||
}
|
||||
|
||||
static int
|
||||
cairo_pdf_ft_font_write_hmtx_table (cairo_pdf_ft_font_t *font,
|
||||
unsigned long tag)
|
||||
{
|
||||
cairo_status_t status;
|
||||
unsigned long entry_size;
|
||||
short *p;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < font->base.num_glyphs; i++) {
|
||||
entry_size = 2 * sizeof (short);
|
||||
status = cairo_pdf_ft_font_allocate_write_buffer (font, entry_size,
|
||||
(unsigned char **) &p);
|
||||
/* XXX: Need to check status here. */
|
||||
FT_Load_Sfnt_Table (font->face, TTAG_hmtx,
|
||||
font->glyphs[i].parent_index * entry_size,
|
||||
(FT_Byte *) p, &entry_size);
|
||||
font->base.widths[i] = be16_to_cpu (p[0]);
|
||||
}
|
||||
|
||||
return font->status;
|
||||
}
|
||||
|
||||
static int
|
||||
cairo_pdf_ft_font_write_loca_table (cairo_pdf_ft_font_t *font,
|
||||
unsigned long tag)
|
||||
{
|
||||
int i;
|
||||
TT_Header *header;
|
||||
|
||||
header = FT_Get_Sfnt_Table (font->face, ft_sfnt_head);
|
||||
|
||||
if (header->Index_To_Loc_Format == 0) {
|
||||
for (i = 0; i < font->base.num_glyphs + 1; i++)
|
||||
cairo_pdf_ft_font_write_be16 (font, font->glyphs[i].location / 2);
|
||||
}
|
||||
else {
|
||||
for (i = 0; i < font->base.num_glyphs + 1; i++)
|
||||
cairo_pdf_ft_font_write_be32 (font, font->glyphs[i].location);
|
||||
}
|
||||
|
||||
return font->status;
|
||||
}
|
||||
|
||||
static int
|
||||
cairo_pdf_ft_font_write_maxp_table (cairo_pdf_ft_font_t *font,
|
||||
unsigned long tag)
|
||||
{
|
||||
TT_MaxProfile *maxp;
|
||||
|
||||
maxp = FT_Get_Sfnt_Table (font->face, ft_sfnt_maxp);
|
||||
|
||||
cairo_pdf_ft_font_write_be32 (font, maxp->version);
|
||||
cairo_pdf_ft_font_write_be16 (font, font->base.num_glyphs);
|
||||
cairo_pdf_ft_font_write_be16 (font, maxp->maxPoints);
|
||||
cairo_pdf_ft_font_write_be16 (font, maxp->maxContours);
|
||||
cairo_pdf_ft_font_write_be16 (font, maxp->maxCompositePoints);
|
||||
cairo_pdf_ft_font_write_be16 (font, maxp->maxCompositeContours);
|
||||
cairo_pdf_ft_font_write_be16 (font, maxp->maxZones);
|
||||
cairo_pdf_ft_font_write_be16 (font, maxp->maxTwilightPoints);
|
||||
cairo_pdf_ft_font_write_be16 (font, maxp->maxStorage);
|
||||
cairo_pdf_ft_font_write_be16 (font, maxp->maxFunctionDefs);
|
||||
cairo_pdf_ft_font_write_be16 (font, maxp->maxInstructionDefs);
|
||||
cairo_pdf_ft_font_write_be16 (font, maxp->maxStackElements);
|
||||
cairo_pdf_ft_font_write_be16 (font, maxp->maxSizeOfInstructions);
|
||||
cairo_pdf_ft_font_write_be16 (font, maxp->maxComponentElements);
|
||||
cairo_pdf_ft_font_write_be16 (font, maxp->maxComponentDepth);
|
||||
|
||||
return font->status;
|
||||
}
|
||||
|
||||
typedef struct table table_t;
|
||||
struct table {
|
||||
unsigned long tag;
|
||||
int (*write) (cairo_pdf_ft_font_t *font, unsigned long tag);
|
||||
};
|
||||
|
||||
static const table_t truetype_tables[] = {
|
||||
/* As we write out the glyf table we remap composite glyphs.
|
||||
* Remapping composite glyphs will reference the sub glyphs the
|
||||
* composite glyph is made up of. That needs to be done first so
|
||||
* we have all the glyphs in the subset before going further. */
|
||||
{ TTAG_glyf, cairo_pdf_ft_font_write_glyf_table },
|
||||
{ TTAG_cmap, cairo_pdf_ft_font_write_cmap_table },
|
||||
{ TTAG_cvt, cairo_pdf_ft_font_write_generic_table },
|
||||
{ TTAG_fpgm, cairo_pdf_ft_font_write_generic_table },
|
||||
{ TTAG_head, cairo_pdf_ft_font_write_head_table },
|
||||
{ TTAG_hhea, cairo_pdf_ft_font_write_hhea_table },
|
||||
{ TTAG_hmtx, cairo_pdf_ft_font_write_hmtx_table },
|
||||
{ TTAG_loca, cairo_pdf_ft_font_write_loca_table },
|
||||
{ TTAG_maxp, cairo_pdf_ft_font_write_maxp_table },
|
||||
{ TTAG_name, cairo_pdf_ft_font_write_generic_table },
|
||||
{ TTAG_prep, cairo_pdf_ft_font_write_generic_table },
|
||||
};
|
||||
|
||||
static cairo_status_t
|
||||
cairo_pdf_ft_font_write_offset_table (cairo_pdf_ft_font_t *font)
|
||||
{
|
||||
cairo_status_t status;
|
||||
unsigned char *table_buffer;
|
||||
size_t table_buffer_length;
|
||||
unsigned short search_range, entry_selector, range_shift;
|
||||
int num_tables;
|
||||
|
||||
num_tables = ARRAY_LENGTH (truetype_tables);
|
||||
search_range = 1;
|
||||
entry_selector = 0;
|
||||
while (search_range * 2 <= num_tables) {
|
||||
search_range *= 2;
|
||||
entry_selector++;
|
||||
}
|
||||
search_range *= 16;
|
||||
range_shift = num_tables * 16 - search_range;
|
||||
|
||||
cairo_pdf_ft_font_write_be32 (font, SFNT_VERSION);
|
||||
cairo_pdf_ft_font_write_be16 (font, num_tables);
|
||||
cairo_pdf_ft_font_write_be16 (font, search_range);
|
||||
cairo_pdf_ft_font_write_be16 (font, entry_selector);
|
||||
cairo_pdf_ft_font_write_be16 (font, range_shift);
|
||||
|
||||
/* XXX: Why are we allocating a table here and then ignoring the
|
||||
* returned buffer? This should result in garbage in the output
|
||||
* file, correct? Is this just unfinished code? -cworth. */
|
||||
table_buffer_length = ARRAY_LENGTH (truetype_tables) * 16;
|
||||
status = cairo_pdf_ft_font_allocate_write_buffer (font, table_buffer_length,
|
||||
&table_buffer);
|
||||
if (status)
|
||||
return status;
|
||||
|
||||
return font->status;
|
||||
}
|
||||
|
||||
static unsigned long
|
||||
cairo_pdf_ft_font_calculate_checksum (cairo_pdf_ft_font_t *font,
|
||||
unsigned long start, unsigned long end)
|
||||
{
|
||||
unsigned long *padded_end;
|
||||
unsigned long *p;
|
||||
unsigned long checksum;
|
||||
char *data;
|
||||
|
||||
checksum = 0;
|
||||
data = _cairo_array_index (&font->output, 0);
|
||||
p = (unsigned long *) (data + start);
|
||||
padded_end = (unsigned long *) (data + ((end + 3) & ~3));
|
||||
while (p < padded_end)
|
||||
checksum += *p++;
|
||||
|
||||
return checksum;
|
||||
}
|
||||
|
||||
static void
|
||||
cairo_pdf_ft_font_update_entry (cairo_pdf_ft_font_t *font, int index, unsigned long tag,
|
||||
unsigned long start, unsigned long end)
|
||||
{
|
||||
unsigned long *entry;
|
||||
|
||||
entry = _cairo_array_index (&font->output, 12 + 16 * index);
|
||||
entry[0] = cpu_to_be32 (tag);
|
||||
entry[1] = cpu_to_be32 (cairo_pdf_ft_font_calculate_checksum (font, start, end));
|
||||
entry[2] = cpu_to_be32 (start);
|
||||
entry[3] = cpu_to_be32 (end - start);
|
||||
}
|
||||
|
||||
static cairo_status_t
|
||||
cairo_pdf_ft_font_generate (void *abstract_font,
|
||||
const char **data, unsigned long *length)
|
||||
{
|
||||
cairo_ft_unscaled_font_t *ft_unscaled_font;
|
||||
cairo_pdf_ft_font_t *font = abstract_font;
|
||||
unsigned long start, end, next, checksum, *checksum_location;
|
||||
int i;
|
||||
|
||||
/* XXX: It would be cleaner to do something besides this cast
|
||||
* here. Perhaps cairo_pdf_ft_font_t should just have the
|
||||
* cairo_ft_unscaled_font_t rather than having the generic
|
||||
* cairo_unscaled_font_t in the base class? */
|
||||
ft_unscaled_font = (cairo_ft_unscaled_font_t *) font->base.unscaled_font;
|
||||
|
||||
font->face = _cairo_ft_unscaled_font_lock_face (ft_unscaled_font);
|
||||
|
||||
if (cairo_pdf_ft_font_write_offset_table (font))
|
||||
goto fail;
|
||||
|
||||
start = cairo_pdf_ft_font_align_output (font);
|
||||
end = start;
|
||||
|
||||
end = 0;
|
||||
for (i = 0; i < ARRAY_LENGTH (truetype_tables); i++) {
|
||||
if (truetype_tables[i].write (font, truetype_tables[i].tag))
|
||||
goto fail;
|
||||
|
||||
end = _cairo_array_num_elements (&font->output);
|
||||
next = cairo_pdf_ft_font_align_output (font);
|
||||
cairo_pdf_ft_font_update_entry (font, i, truetype_tables[i].tag,
|
||||
start, end);
|
||||
start = next;
|
||||
}
|
||||
|
||||
checksum =
|
||||
0xb1b0afba - cairo_pdf_ft_font_calculate_checksum (font, 0, end);
|
||||
checksum_location = _cairo_array_index (&font->output, font->checksum_index);
|
||||
*checksum_location = cpu_to_be32 (checksum);
|
||||
|
||||
*data = _cairo_array_index (&font->output, 0);
|
||||
*length = _cairo_array_num_elements (&font->output);
|
||||
|
||||
fail:
|
||||
_cairo_ft_unscaled_font_unlock_face (ft_unscaled_font);
|
||||
font->face = NULL;
|
||||
|
||||
return font->status;
|
||||
}
|
||||
|
||||
static int
|
||||
cairo_pdf_ft_font_use_glyph (cairo_pdf_ft_font_t *font, int glyph)
|
||||
{
|
||||
if (font->parent_to_subset[glyph] == 0) {
|
||||
font->parent_to_subset[glyph] = font->base.num_glyphs;
|
||||
font->glyphs[font->base.num_glyphs].parent_index = glyph;
|
||||
font->base.num_glyphs++;
|
||||
}
|
||||
|
||||
return font->parent_to_subset[glyph];
|
||||
}
|
||||
|
||||
cairo_status_t
|
||||
_cairo_truetype_subset_init (cairo_truetype_subset_t *truetype_subset,
|
||||
cairo_scaled_font_subset_t *font_subset)
|
||||
{
|
||||
cairo_pdf_ft_font_t *font;
|
||||
cairo_status_t status;
|
||||
const char *data = NULL; /* squelch bogus compiler warning */
|
||||
unsigned long parent_glyph, length = 0; /* squelch bogus compiler warning */
|
||||
int i;
|
||||
|
||||
status = _cairo_pdf_ft_font_create (font_subset, &font);
|
||||
if (status)
|
||||
return status;
|
||||
|
||||
for (i = 0; i < font->scaled_font_subset->num_glyphs; i++) {
|
||||
parent_glyph = font->scaled_font_subset->glyphs[i];
|
||||
cairo_pdf_ft_font_use_glyph (font, parent_glyph);
|
||||
}
|
||||
|
||||
status = cairo_pdf_ft_font_generate (font, &data, &length);
|
||||
if (status)
|
||||
goto fail1;
|
||||
|
||||
truetype_subset->base_font = strdup (font->base.base_font);
|
||||
if (truetype_subset->base_font == NULL)
|
||||
goto fail1;
|
||||
|
||||
truetype_subset->widths = calloc (sizeof (int), font->base.num_glyphs);
|
||||
if (truetype_subset->widths == NULL)
|
||||
goto fail2;
|
||||
for (i = 0; i < font->base.num_glyphs; i++)
|
||||
truetype_subset->widths[i] = font->base.widths[i];
|
||||
|
||||
truetype_subset->x_min = font->base.x_min;
|
||||
truetype_subset->y_min = font->base.y_min;
|
||||
truetype_subset->x_max = font->base.x_max;
|
||||
truetype_subset->y_max = font->base.y_max;
|
||||
truetype_subset->ascent = font->base.ascent;
|
||||
truetype_subset->descent = font->base.descent;
|
||||
|
||||
truetype_subset->data = malloc (length);
|
||||
if (truetype_subset->data == NULL)
|
||||
goto fail3;
|
||||
|
||||
memcpy (truetype_subset->data, data, length);
|
||||
truetype_subset->data_length = length;
|
||||
|
||||
cairo_pdf_ft_font_destroy (font);
|
||||
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
|
||||
fail3:
|
||||
free (truetype_subset->widths);
|
||||
fail2:
|
||||
free (truetype_subset->base_font);
|
||||
fail1:
|
||||
cairo_pdf_ft_font_destroy (font);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
void
|
||||
_cairo_truetype_subset_fini (cairo_truetype_subset_t *subset)
|
||||
{
|
||||
free (subset->base_font);
|
||||
free (subset->widths);
|
||||
free (subset->data);
|
||||
}
|
||||
|
|
@ -49,7 +49,7 @@ static const cairo_font_face_backend_t _cairo_toy_font_face_backend;
|
|||
const cairo_font_face_t _cairo_font_face_nil = {
|
||||
{ 0 }, /* hash_entry */
|
||||
CAIRO_STATUS_NO_MEMORY, /* status */
|
||||
-1, /* ref_count */
|
||||
CAIRO_REF_COUNT_INVALID, /* ref_count */
|
||||
{ 0, 0, 0, NULL }, /* user_data */
|
||||
&_cairo_toy_font_face_backend
|
||||
};
|
||||
|
@ -82,7 +82,7 @@ cairo_font_face_reference (cairo_font_face_t *font_face)
|
|||
if (font_face == NULL)
|
||||
return NULL;
|
||||
|
||||
if (font_face->ref_count == (unsigned int)-1)
|
||||
if (font_face->ref_count == CAIRO_REF_COUNT_INVALID)
|
||||
return font_face;
|
||||
|
||||
/* We would normally assert (font_face->ref_count >0) here but we
|
||||
|
@ -93,6 +93,7 @@ cairo_font_face_reference (cairo_font_face_t *font_face)
|
|||
|
||||
return font_face;
|
||||
}
|
||||
slim_hidden_def (cairo_font_face_reference);
|
||||
|
||||
/**
|
||||
* cairo_font_face_destroy:
|
||||
|
@ -108,7 +109,7 @@ cairo_font_face_destroy (cairo_font_face_t *font_face)
|
|||
if (font_face == NULL)
|
||||
return;
|
||||
|
||||
if (font_face->ref_count == (unsigned int)-1)
|
||||
if (font_face->ref_count == CAIRO_REF_COUNT_INVALID)
|
||||
return;
|
||||
|
||||
assert (font_face->ref_count > 0);
|
||||
|
@ -129,12 +130,16 @@ cairo_font_face_destroy (cairo_font_face_t *font_face)
|
|||
|
||||
free (font_face);
|
||||
}
|
||||
slim_hidden_def (cairo_font_face_destroy);
|
||||
|
||||
/**
|
||||
* cairo_font_face_get_type:
|
||||
* @font_face: a #cairo_font_face_t
|
||||
*
|
||||
* Return value: The type of @font_face. See #cairo_font_type_t.
|
||||
* This function returns the type of the backend used to create
|
||||
* a font face. See #cairo_font_type_t for available types.
|
||||
*
|
||||
* Return value: The type of @font_face.
|
||||
*
|
||||
* Since: 1.2
|
||||
**/
|
||||
|
@ -202,7 +207,7 @@ cairo_font_face_set_user_data (cairo_font_face_t *font_face,
|
|||
void *user_data,
|
||||
cairo_destroy_func_t destroy)
|
||||
{
|
||||
if (font_face->ref_count == -1)
|
||||
if (font_face->ref_count == CAIRO_REF_COUNT_INVALID)
|
||||
return CAIRO_STATUS_NO_MEMORY;
|
||||
|
||||
return _cairo_user_data_array_set_data (&font_face->user_data,
|
||||
|
|
|
@ -48,6 +48,7 @@
|
|||
#include FT_FREETYPE_H
|
||||
#include FT_OUTLINE_H
|
||||
#include FT_IMAGE_H
|
||||
#include FT_TRUETYPE_TABLES_H
|
||||
#if HAVE_FT_GLYPHSLOT_EMBOLDEN
|
||||
#include FT_SYNTHESIS_H
|
||||
#endif
|
||||
|
@ -97,6 +98,7 @@ struct _cairo_ft_unscaled_font {
|
|||
double y_scale; /* Extracted Y scale factor */
|
||||
cairo_bool_t have_shape; /* true if the current scale has a non-scale component*/
|
||||
cairo_matrix_t current_shape;
|
||||
FT_Matrix Current_Shape;
|
||||
|
||||
int lock; /* count of how many times this font has been locked */
|
||||
|
||||
|
@ -550,6 +552,7 @@ _cairo_ft_unscaled_font_lock_face (cairo_ft_unscaled_font_t *unscaled)
|
|||
|
||||
return face;
|
||||
}
|
||||
slim_hidden_def (cairo_ft_scaled_font_lock_face);
|
||||
|
||||
/* Unlock unscaled font locked with _cairo_ft_unscaled_font_lock_face
|
||||
*/
|
||||
|
@ -560,6 +563,7 @@ _cairo_ft_unscaled_font_unlock_face (cairo_ft_unscaled_font_t *unscaled)
|
|||
|
||||
unscaled->lock--;
|
||||
}
|
||||
slim_hidden_def (cairo_ft_scaled_font_unlock_face);
|
||||
|
||||
static void
|
||||
_compute_transform (cairo_ft_font_transform_t *sf,
|
||||
|
@ -601,7 +605,6 @@ _cairo_ft_unscaled_font_set_scale (cairo_ft_unscaled_font_t *unscaled,
|
|||
{
|
||||
cairo_ft_font_transform_t sf;
|
||||
FT_Matrix mat;
|
||||
FT_UInt pixel_width, pixel_height;
|
||||
FT_Error error;
|
||||
|
||||
assert (unscaled->face != NULL);
|
||||
|
@ -631,6 +634,7 @@ _cairo_ft_unscaled_font_set_scale (cairo_ft_unscaled_font_t *unscaled,
|
|||
mat.xy != 0x00000 ||
|
||||
mat.yy != 0x10000);
|
||||
|
||||
unscaled->Current_Shape = mat;
|
||||
cairo_matrix_init (&unscaled->current_shape,
|
||||
sf.shape[0][0], sf.shape[0][1],
|
||||
sf.shape[1][0], sf.shape[1][1],
|
||||
|
@ -639,19 +643,16 @@ _cairo_ft_unscaled_font_set_scale (cairo_ft_unscaled_font_t *unscaled,
|
|||
FT_Set_Transform(unscaled->face, &mat, NULL);
|
||||
|
||||
if ((unscaled->face->face_flags & FT_FACE_FLAG_SCALABLE) != 0) {
|
||||
pixel_width = sf.x_scale;
|
||||
pixel_height = sf.y_scale;
|
||||
error = FT_Set_Char_Size (unscaled->face,
|
||||
sf.x_scale * 64.0,
|
||||
sf.y_scale * 64.0,
|
||||
0, 0);
|
||||
assert (error == 0);
|
||||
} else {
|
||||
double min_distance = DBL_MAX;
|
||||
int i;
|
||||
int best_i = 0;
|
||||
|
||||
pixel_width = pixel_height = 0;
|
||||
|
||||
for (i = 0; i < unscaled->face->num_fixed_sizes; i++) {
|
||||
#if HAVE_FT_BITMAP_SIZE_Y_PPEM
|
||||
double size = unscaled->face->available_sizes[i].y_ppem / 64.;
|
||||
|
@ -675,9 +676,8 @@ _cairo_ft_unscaled_font_set_scale (cairo_ft_unscaled_font_t *unscaled,
|
|||
error = FT_Set_Pixel_Sizes (unscaled->face,
|
||||
unscaled->face->available_sizes[best_i].width,
|
||||
unscaled->face->available_sizes[best_i].height);
|
||||
assert (error == 0);
|
||||
}
|
||||
|
||||
assert (error == 0);
|
||||
}
|
||||
|
||||
/* Empirically-derived subpixel filtering values thanks to Keith
|
||||
|
@ -978,6 +978,7 @@ _render_glyph_outline (FT_Face face,
|
|||
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;
|
||||
|
@ -1231,6 +1232,8 @@ _get_pattern_ft_options (FcPattern *pattern)
|
|||
antialias = FcTrue;
|
||||
|
||||
if (antialias) {
|
||||
cairo_subpixel_order_t subpixel_order;
|
||||
|
||||
if (!bitmap)
|
||||
ft_options.load_flags |= FT_LOAD_NO_BITMAP;
|
||||
|
||||
|
@ -1245,25 +1248,28 @@ _get_pattern_ft_options (FcPattern *pattern)
|
|||
|
||||
switch (rgba) {
|
||||
case FC_RGBA_RGB:
|
||||
ft_options.base.subpixel_order = CAIRO_SUBPIXEL_ORDER_RGB;
|
||||
subpixel_order = CAIRO_SUBPIXEL_ORDER_RGB;
|
||||
break;
|
||||
case FC_RGBA_BGR:
|
||||
ft_options.base.subpixel_order = CAIRO_SUBPIXEL_ORDER_BGR;
|
||||
subpixel_order = CAIRO_SUBPIXEL_ORDER_BGR;
|
||||
break;
|
||||
case FC_RGBA_VRGB:
|
||||
ft_options.base.subpixel_order = CAIRO_SUBPIXEL_ORDER_VRGB;
|
||||
subpixel_order = CAIRO_SUBPIXEL_ORDER_VRGB;
|
||||
break;
|
||||
case FC_RGBA_VBGR:
|
||||
ft_options.base.subpixel_order = CAIRO_SUBPIXEL_ORDER_VBGR;
|
||||
subpixel_order = CAIRO_SUBPIXEL_ORDER_VBGR;
|
||||
break;
|
||||
case FC_RGBA_UNKNOWN:
|
||||
case FC_RGBA_NONE:
|
||||
default:
|
||||
subpixel_order = CAIRO_SUBPIXEL_ORDER_DEFAULT;
|
||||
break;
|
||||
}
|
||||
|
||||
if (ft_options.base.subpixel_order != CAIRO_SUBPIXEL_ORDER_DEFAULT)
|
||||
if (subpixel_order != CAIRO_SUBPIXEL_ORDER_DEFAULT) {
|
||||
ft_options.base.subpixel_order = subpixel_order;
|
||||
ft_options.base.antialias = CAIRO_ANTIALIAS_SUBPIXEL;
|
||||
}
|
||||
|
||||
#ifdef FC_HINT_STYLE
|
||||
if (FcPatternGetInteger (pattern,
|
||||
|
@ -1458,7 +1464,7 @@ _cairo_ft_scaled_font_create (cairo_ft_unscaled_font_t *unscaled,
|
|||
fs_metrics.ascent = DOUBLE_FROM_26_6(metrics->ascender) * y_factor;
|
||||
fs_metrics.descent = DOUBLE_FROM_26_6(- metrics->descender) * y_factor;
|
||||
fs_metrics.height = DOUBLE_FROM_26_6(metrics->height) * y_factor;
|
||||
if (!(scaled_font->ft_options.load_flags & FT_LOAD_VERTICAL_LAYOUT)) {
|
||||
if (!_cairo_ft_scaled_font_is_vertical (&scaled_font->base)) {
|
||||
fs_metrics.max_x_advance = DOUBLE_FROM_26_6(metrics->max_advance) * x_factor;
|
||||
fs_metrics.max_y_advance = 0;
|
||||
} else {
|
||||
|
@ -1471,7 +1477,7 @@ _cairo_ft_scaled_font_create (cairo_ft_unscaled_font_t *unscaled,
|
|||
fs_metrics.ascent = face->ascender / scale;
|
||||
fs_metrics.descent = - face->descender / scale;
|
||||
fs_metrics.height = face->height / scale;
|
||||
if (!(scaled_font->ft_options.load_flags & FT_LOAD_VERTICAL_LAYOUT)) {
|
||||
if (!_cairo_ft_scaled_font_is_vertical (&scaled_font->base)) {
|
||||
fs_metrics.max_x_advance = face->max_advance_width / scale;
|
||||
fs_metrics.max_y_advance = 0;
|
||||
} else {
|
||||
|
@ -1726,16 +1732,21 @@ _decompose_glyph_outline (FT_Face face,
|
|||
* Translate glyph to match its metrics.
|
||||
*/
|
||||
static void
|
||||
_cairo_ft_scaled_glyph_vertical_layout_bearing_fix (FT_GlyphSlot glyph)
|
||||
_cairo_ft_scaled_glyph_vertical_layout_bearing_fix (void *abstract_font,
|
||||
FT_GlyphSlot glyph)
|
||||
{
|
||||
FT_Pos x = glyph->metrics.vertBearingX - glyph->metrics.horiBearingX;
|
||||
FT_Pos y = -glyph->metrics.vertBearingY - glyph->metrics.horiBearingY;
|
||||
cairo_ft_scaled_font_t *scaled_font = abstract_font;
|
||||
FT_Vector vector;
|
||||
|
||||
if (glyph->format == FT_GLYPH_FORMAT_OUTLINE)
|
||||
FT_Outline_Translate(&glyph->outline, x, y);
|
||||
else if (glyph->format == FT_GLYPH_FORMAT_BITMAP) {
|
||||
glyph->bitmap_left += x / 64;
|
||||
glyph->bitmap_top += y / 64;
|
||||
vector.x = glyph->metrics.vertBearingX - glyph->metrics.horiBearingX;
|
||||
vector.y = -glyph->metrics.vertBearingY - glyph->metrics.horiBearingY;
|
||||
|
||||
if (glyph->format == FT_GLYPH_FORMAT_OUTLINE) {
|
||||
FT_Vector_Transform (&vector, &scaled_font->unscaled->Current_Shape);
|
||||
FT_Outline_Translate(&glyph->outline, vector.x, vector.y);
|
||||
} else if (glyph->format == FT_GLYPH_FORMAT_BITMAP) {
|
||||
glyph->bitmap_left += vector.x / 64;
|
||||
glyph->bitmap_top += vector.y / 64;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1796,7 +1807,7 @@ _cairo_ft_scaled_glyph_init (void *abstract_font,
|
|||
#endif
|
||||
|
||||
if (vertical_layout)
|
||||
_cairo_ft_scaled_glyph_vertical_layout_bearing_fix (glyph);
|
||||
_cairo_ft_scaled_glyph_vertical_layout_bearing_fix (scaled_font, glyph);
|
||||
|
||||
if (info & CAIRO_SCALED_GLYPH_INFO_METRICS) {
|
||||
/*
|
||||
|
@ -1815,8 +1826,7 @@ _cairo_ft_scaled_glyph_init (void *abstract_font,
|
|||
y_factor = 1 / unscaled->y_scale;
|
||||
|
||||
/*
|
||||
* Note: the font's coordinate system is upside down from ours, so the
|
||||
* Y coordinates of the bearing and advance need to be negated.
|
||||
* Note: Y coordinates of the horizontal bearing need to be negated.
|
||||
*
|
||||
* Scale metrics back to glyph space from the scaled glyph space returned
|
||||
* by FreeType
|
||||
|
@ -1934,7 +1944,7 @@ _cairo_ft_scaled_glyph_init (void *abstract_font,
|
|||
FT_GlyphSlot_Embolden (glyph);
|
||||
#endif
|
||||
if (vertical_layout)
|
||||
_cairo_ft_scaled_glyph_vertical_layout_bearing_fix (glyph);
|
||||
_cairo_ft_scaled_glyph_vertical_layout_bearing_fix (scaled_font, glyph);
|
||||
|
||||
}
|
||||
if (glyph->format == FT_GLYPH_FORMAT_OUTLINE)
|
||||
|
@ -1990,6 +2000,36 @@ _cairo_ft_show_glyphs (void *abstract_font,
|
|||
return CAIRO_INT_STATUS_UNSUPPORTED;
|
||||
}
|
||||
|
||||
static cairo_int_status_t
|
||||
_cairo_ft_load_truetype_table (void *abstract_font,
|
||||
unsigned long tag,
|
||||
long offset,
|
||||
unsigned char *buffer,
|
||||
unsigned long *length)
|
||||
{
|
||||
cairo_ft_scaled_font_t *scaled_font = abstract_font;
|
||||
cairo_ft_unscaled_font_t *unscaled = scaled_font->unscaled;
|
||||
FT_Face face;
|
||||
cairo_status_t status = CAIRO_INT_STATUS_UNSUPPORTED;
|
||||
|
||||
if (_cairo_ft_scaled_font_is_vertical (&scaled_font->base))
|
||||
return CAIRO_INT_STATUS_UNSUPPORTED;
|
||||
|
||||
#if HAVE_FT_LOAD_SFNT_TABLE
|
||||
face = _cairo_ft_unscaled_font_lock_face (unscaled);
|
||||
if (!face)
|
||||
return CAIRO_STATUS_NO_MEMORY;
|
||||
|
||||
if (FT_IS_SFNT (face) &&
|
||||
FT_Load_Sfnt_Table (face, tag, offset, buffer, length) == 0)
|
||||
status = CAIRO_STATUS_SUCCESS;
|
||||
|
||||
_cairo_ft_unscaled_font_unlock_face (unscaled);
|
||||
#endif
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
const cairo_scaled_font_backend_t cairo_ft_scaled_font_backend = {
|
||||
CAIRO_FONT_TYPE_FT,
|
||||
_cairo_ft_scaled_font_create_toy,
|
||||
|
@ -1998,6 +2038,7 @@ const cairo_scaled_font_backend_t cairo_ft_scaled_font_backend = {
|
|||
NULL, /* text_to_glyphs */
|
||||
_cairo_ft_ucs4_to_index,
|
||||
_cairo_ft_show_glyphs,
|
||||
_cairo_ft_load_truetype_table,
|
||||
};
|
||||
|
||||
/* cairo_ft_font_face_t */
|
||||
|
@ -2157,6 +2198,10 @@ cairo_ft_font_options_substitute (const cairo_font_options_t *options,
|
|||
if (FcPatternGet (pattern, FC_ANTIALIAS, 0, &v) == FcResultNoMatch)
|
||||
{
|
||||
FcPatternAddBool (pattern, FC_ANTIALIAS, options->antialias != CAIRO_ANTIALIAS_NONE);
|
||||
if (options->antialias != CAIRO_ANTIALIAS_SUBPIXEL) {
|
||||
FcPatternDel (pattern, FC_RGBA);
|
||||
FcPatternAddInteger (pattern, FC_RGBA, FC_RGBA_NONE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2204,6 +2249,9 @@ cairo_ft_font_options_substitute (const cairo_font_options_t *options,
|
|||
int hint_style;
|
||||
|
||||
switch (options->hint_style) {
|
||||
case CAIRO_HINT_STYLE_NONE:
|
||||
hint_style = FC_HINT_NONE;
|
||||
break;
|
||||
case CAIRO_HINT_STYLE_SLIGHT:
|
||||
hint_style = FC_HINT_SLIGHT;
|
||||
break;
|
||||
|
@ -2211,6 +2259,7 @@ cairo_ft_font_options_substitute (const cairo_font_options_t *options,
|
|||
hint_style = FC_HINT_MEDIUM;
|
||||
break;
|
||||
case CAIRO_HINT_STYLE_FULL:
|
||||
case CAIRO_HINT_STYLE_DEFAULT:
|
||||
default:
|
||||
hint_style = FC_HINT_FULL;
|
||||
break;
|
||||
|
@ -2221,6 +2270,7 @@ cairo_ft_font_options_substitute (const cairo_font_options_t *options,
|
|||
#endif
|
||||
}
|
||||
}
|
||||
slim_hidden_def (cairo_ft_font_options_substitute);
|
||||
|
||||
/**
|
||||
* cairo_ft_font_face_create_for_pattern:
|
||||
|
|
|
@ -64,11 +64,14 @@ _cairo_ft_unscaled_font_lock_face (cairo_ft_unscaled_font_t *unscaled);
|
|||
cairo_private void
|
||||
_cairo_ft_unscaled_font_unlock_face (cairo_ft_unscaled_font_t *unscaled);
|
||||
|
||||
cairo_bool_t
|
||||
cairo_private cairo_bool_t
|
||||
_cairo_ft_scaled_font_is_vertical (cairo_scaled_font_t *scaled_font);
|
||||
|
||||
slim_hidden_proto (cairo_ft_font_options_substitute);
|
||||
slim_hidden_proto (cairo_ft_scaled_font_lock_face);
|
||||
slim_hidden_proto (cairo_ft_scaled_font_unlock_face);
|
||||
|
||||
CAIRO_END_DECLS
|
||||
|
||||
#endif /* CAIRO_HAS_FT_FONT */
|
||||
|
||||
#endif /* CAIRO_FT_PRIVATE_H */
|
||||
|
|
|
@ -492,9 +492,9 @@ _cairo_gstate_get_line_join (cairo_gstate_t *gstate)
|
|||
}
|
||||
|
||||
cairo_status_t
|
||||
_cairo_gstate_set_dash (cairo_gstate_t *gstate, double *dash, int num_dashes, double offset)
|
||||
_cairo_gstate_set_dash (cairo_gstate_t *gstate, const double *dash, int num_dashes, double offset)
|
||||
{
|
||||
int i;
|
||||
unsigned int i;
|
||||
double dash_total;
|
||||
|
||||
if (gstate->stroke_style.dash)
|
||||
|
@ -706,6 +706,25 @@ _cairo_gstate_backend_to_user (cairo_gstate_t *gstate, double *x, double *y)
|
|||
cairo_matrix_transform_point (&gstate->ctm_inverse, x, y);
|
||||
}
|
||||
|
||||
void
|
||||
_cairo_gstate_backend_to_user_rectangle (cairo_gstate_t *gstate,
|
||||
double *x1, double *y1,
|
||||
double *x2, double *y2,
|
||||
cairo_bool_t *is_tight)
|
||||
{
|
||||
double width = *x2 - *x1;
|
||||
double height = *y2 - *y1;
|
||||
cairo_matrix_t matrix_inverse;
|
||||
|
||||
cairo_matrix_multiply (&matrix_inverse, &gstate->ctm_inverse,
|
||||
&gstate->target->device_transform_inverse);
|
||||
_cairo_matrix_transform_bounding_box (
|
||||
&matrix_inverse, x1, y1, &width, &height, is_tight);
|
||||
|
||||
*x2 = *x1 + width;
|
||||
*y2 = *y1 + height;
|
||||
}
|
||||
|
||||
/* XXX: NYI
|
||||
cairo_status_t
|
||||
_cairo_gstate_stroke_to_path (cairo_gstate_t *gstate)
|
||||
|
@ -1041,6 +1060,29 @@ _cairo_gstate_show_page (cairo_gstate_t *gstate)
|
|||
return status;
|
||||
}
|
||||
|
||||
static void
|
||||
_cairo_gstate_traps_extents_to_user_rectangle (cairo_gstate_t *gstate,
|
||||
cairo_traps_t *traps,
|
||||
double *x1, double *y1,
|
||||
double *x2, double *y2)
|
||||
{
|
||||
cairo_box_t extents;
|
||||
|
||||
_cairo_traps_extents (traps, &extents);
|
||||
|
||||
if (extents.p1.x >= extents.p2.x || extents.p1.y >= extents.p2.y) {
|
||||
/* no traps, so we actually won't draw anything */
|
||||
*x1 = *y1 = *x2 = *y2 = 0;
|
||||
} else {
|
||||
*x1 = _cairo_fixed_to_double (extents.p1.x);
|
||||
*y1 = _cairo_fixed_to_double (extents.p1.y);
|
||||
*x2 = _cairo_fixed_to_double (extents.p2.x);
|
||||
*y2 = _cairo_fixed_to_double (extents.p2.y);
|
||||
|
||||
_cairo_gstate_backend_to_user_rectangle (gstate, x1, y1, x2, y2, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
cairo_status_t
|
||||
_cairo_gstate_stroke_extents (cairo_gstate_t *gstate,
|
||||
cairo_path_fixed_t *path,
|
||||
|
@ -1049,7 +1091,6 @@ _cairo_gstate_stroke_extents (cairo_gstate_t *gstate,
|
|||
{
|
||||
cairo_status_t status;
|
||||
cairo_traps_t traps;
|
||||
cairo_box_t extents;
|
||||
|
||||
_cairo_traps_init (&traps);
|
||||
|
||||
|
@ -1059,20 +1100,10 @@ _cairo_gstate_stroke_extents (cairo_gstate_t *gstate,
|
|||
&gstate->ctm_inverse,
|
||||
gstate->tolerance,
|
||||
&traps);
|
||||
if (status)
|
||||
goto BAIL;
|
||||
if (status == CAIRO_STATUS_SUCCESS) {
|
||||
_cairo_gstate_traps_extents_to_user_rectangle(gstate, &traps, x1, y1, x2, y2);
|
||||
}
|
||||
|
||||
_cairo_traps_extents (&traps, &extents);
|
||||
|
||||
*x1 = _cairo_fixed_to_double (extents.p1.x);
|
||||
*y1 = _cairo_fixed_to_double (extents.p1.y);
|
||||
*x2 = _cairo_fixed_to_double (extents.p2.x);
|
||||
*y2 = _cairo_fixed_to_double (extents.p2.y);
|
||||
|
||||
_cairo_gstate_backend_to_user (gstate, x1, y1);
|
||||
_cairo_gstate_backend_to_user (gstate, x2, y2);
|
||||
|
||||
BAIL:
|
||||
_cairo_traps_fini (&traps);
|
||||
|
||||
return status;
|
||||
|
@ -1094,20 +1125,10 @@ _cairo_gstate_fill_extents (cairo_gstate_t *gstate,
|
|||
gstate->fill_rule,
|
||||
gstate->tolerance,
|
||||
&traps);
|
||||
if (status)
|
||||
goto BAIL;
|
||||
if (status == CAIRO_STATUS_SUCCESS) {
|
||||
_cairo_gstate_traps_extents_to_user_rectangle(gstate, &traps, x1, y1, x2, y2);
|
||||
}
|
||||
|
||||
_cairo_traps_extents (&traps, &extents);
|
||||
|
||||
*x1 = _cairo_fixed_to_double (extents.p1.x);
|
||||
*y1 = _cairo_fixed_to_double (extents.p1.y);
|
||||
*x2 = _cairo_fixed_to_double (extents.p2.x);
|
||||
*y2 = _cairo_fixed_to_double (extents.p2.y);
|
||||
|
||||
_cairo_gstate_backend_to_user (gstate, x1, y1);
|
||||
_cairo_gstate_backend_to_user (gstate, x2, y2);
|
||||
|
||||
BAIL:
|
||||
_cairo_traps_fini (&traps);
|
||||
|
||||
return status;
|
||||
|
@ -1127,6 +1148,40 @@ _cairo_gstate_clip (cairo_gstate_t *gstate, cairo_path_fixed_t *path)
|
|||
gstate->antialias, gstate->target);
|
||||
}
|
||||
|
||||
cairo_status_t
|
||||
_cairo_gstate_clip_extents (cairo_gstate_t *gstate,
|
||||
double *x1,
|
||||
double *y1,
|
||||
double *x2,
|
||||
double *y2)
|
||||
{
|
||||
cairo_rectangle_int16_t extents;
|
||||
cairo_status_t status;
|
||||
|
||||
status = _cairo_surface_get_extents (gstate->target, &extents);
|
||||
if (status)
|
||||
return status;
|
||||
|
||||
status = _cairo_clip_intersect_to_rectangle (&gstate->clip, &extents);
|
||||
if (status)
|
||||
return status;
|
||||
|
||||
*x1 = extents.x;
|
||||
*y1 = extents.y;
|
||||
*x2 = extents.x + extents.width;
|
||||
*y2 = extents.y + extents.height;
|
||||
|
||||
_cairo_gstate_backend_to_user_rectangle (gstate, x1, y1, x2, y2, NULL);
|
||||
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
cairo_rectangle_list_t*
|
||||
_cairo_gstate_copy_clip_rectangles (cairo_gstate_t *gstate)
|
||||
{
|
||||
return _cairo_clip_copy_rectangles (&gstate->clip, gstate);
|
||||
}
|
||||
|
||||
static void
|
||||
_cairo_gstate_unset_scaled_font (cairo_gstate_t *gstate)
|
||||
{
|
||||
|
@ -1411,7 +1466,7 @@ _cairo_gstate_glyph_extents (cairo_gstate_t *gstate,
|
|||
|
||||
cairo_status_t
|
||||
_cairo_gstate_show_glyphs (cairo_gstate_t *gstate,
|
||||
cairo_glyph_t *glyphs,
|
||||
const cairo_glyph_t *glyphs,
|
||||
int num_glyphs)
|
||||
{
|
||||
cairo_status_t status;
|
||||
|
@ -1436,10 +1491,12 @@ _cairo_gstate_show_glyphs (cairo_gstate_t *gstate,
|
|||
|
||||
for (i = 0; i < num_glyphs; ++i)
|
||||
{
|
||||
transformed_glyphs[i] = glyphs[i];
|
||||
_cairo_gstate_user_to_device (gstate,
|
||||
&transformed_glyphs[i].x,
|
||||
&transformed_glyphs[i].y);
|
||||
transformed_glyphs[i].index = glyphs[i].index;
|
||||
transformed_glyphs[i].x = glyphs[i].x + gstate->font_matrix.x0;
|
||||
transformed_glyphs[i].y = glyphs[i].y + gstate->font_matrix.y0;
|
||||
_cairo_gstate_user_to_backend (gstate,
|
||||
&transformed_glyphs[i].x,
|
||||
&transformed_glyphs[i].y);
|
||||
}
|
||||
|
||||
_cairo_gstate_copy_transformed_source (gstate, &source_pattern.base);
|
||||
|
@ -1477,7 +1534,9 @@ _cairo_gstate_glyph_path (cairo_gstate_t *gstate,
|
|||
|
||||
for (i = 0; i < num_glyphs; ++i)
|
||||
{
|
||||
transformed_glyphs[i] = glyphs[i];
|
||||
transformed_glyphs[i].index = glyphs[i].index;
|
||||
transformed_glyphs[i].x = glyphs[i].x + gstate->font_matrix.x0;
|
||||
transformed_glyphs[i].y = glyphs[i].y + gstate->font_matrix.y0;
|
||||
_cairo_gstate_user_to_backend (gstate,
|
||||
&(transformed_glyphs[i].x),
|
||||
&(transformed_glyphs[i].y));
|
||||
|
@ -1505,21 +1564,3 @@ _cairo_gstate_get_antialias (cairo_gstate_t *gstate)
|
|||
{
|
||||
return gstate->antialias;
|
||||
}
|
||||
|
||||
cairo_bool_t
|
||||
_cairo_gstate_has_clip (cairo_gstate_t *gstate)
|
||||
{
|
||||
return _cairo_clip_has_clip (&gstate->clip);
|
||||
}
|
||||
|
||||
cairo_bool_t
|
||||
_cairo_gstate_extract_clip_rectangles (cairo_gstate_t *gstate,
|
||||
int max_rectangles,
|
||||
cairo_clip_rect_t *rectangles_out,
|
||||
int *num_rectangles_out)
|
||||
{
|
||||
return _cairo_clip_extract_rectangles (&gstate->clip,
|
||||
max_rectangles,
|
||||
rectangles_out,
|
||||
num_rectangles_out);
|
||||
}
|
||||
|
|
|
@ -115,7 +115,7 @@ static const cairo_hash_table_arrangement_t hash_table_arrangements [] = {
|
|||
{ 268435456, 590559793, 590559791 }
|
||||
};
|
||||
|
||||
#define NUM_HASH_TABLE_ARRANGEMENTS (sizeof(hash_table_arrangements)/sizeof(hash_table_arrangements[0]))
|
||||
#define NUM_HASH_TABLE_ARRANGEMENTS ((int)(sizeof(hash_table_arrangements)/sizeof(hash_table_arrangements[0])))
|
||||
|
||||
struct _cairo_hash_table {
|
||||
cairo_hash_keys_equal_func_t keys_equal;
|
||||
|
|
|
@ -44,8 +44,6 @@ _cairo_format_bpp (cairo_format_t format)
|
|||
return 1;
|
||||
case CAIRO_FORMAT_A8:
|
||||
return 8;
|
||||
case CAIRO_FORMAT_RGB16_565:
|
||||
return 16;
|
||||
case CAIRO_FORMAT_RGB24:
|
||||
case CAIRO_FORMAT_ARGB32:
|
||||
return 32;
|
||||
|
@ -90,22 +88,33 @@ _cairo_image_surface_create_for_pixman_image (pixman_image_t *pixman_image,
|
|||
static cairo_format_t
|
||||
_cairo_format_from_pixman_format (pixman_format_t *pixman_format)
|
||||
{
|
||||
int bpp, am, rm, gm, bm;
|
||||
unsigned int bpp, am, rm, gm, bm;
|
||||
|
||||
pixman_format_get_masks (pixman_format, &bpp, &am, &rm, &gm, &bm);
|
||||
|
||||
/* See definition of cairo_internal_format_t for an explanation of
|
||||
* the CAIRO_INTERNAL_FORMAT values used here. */
|
||||
switch (bpp) {
|
||||
case 32:
|
||||
if (am == 0xff000000 &&
|
||||
rm == 0x00ff0000 &&
|
||||
gm == 0x0000ff00 &&
|
||||
bm == 0x000000ff)
|
||||
return CAIRO_FORMAT_ARGB32;
|
||||
if (am == 0x0 &&
|
||||
rm == 0x00ff0000 &&
|
||||
gm == 0x0000ff00 &&
|
||||
bm == 0x000000ff)
|
||||
return CAIRO_FORMAT_RGB24;
|
||||
if (am == 0xff000000) {
|
||||
if (rm == 0x00ff0000 &&
|
||||
gm == 0x0000ff00 &&
|
||||
bm == 0x000000ff)
|
||||
return CAIRO_FORMAT_ARGB32;
|
||||
if (rm == 0x000000ff &&
|
||||
gm == 0x0000ff00 &&
|
||||
bm == 0x00ff0000)
|
||||
return CAIRO_INTERNAL_FORMAT_ABGR32;
|
||||
} else if (am == 0x0) {
|
||||
if (rm == 0x00ff0000 &&
|
||||
gm == 0x0000ff00 &&
|
||||
bm == 0x000000ff)
|
||||
return CAIRO_FORMAT_RGB24;
|
||||
if (rm == 0x000000ff &&
|
||||
gm == 0x0000ff00 &&
|
||||
bm == 0x00ff0000)
|
||||
return CAIRO_INTERNAL_FORMAT_BGR24;
|
||||
}
|
||||
break;
|
||||
case 16:
|
||||
if (am == 0x0 &&
|
||||
|
@ -131,13 +140,13 @@ _cairo_format_from_pixman_format (pixman_format_t *pixman_format)
|
|||
}
|
||||
|
||||
fprintf (stderr,
|
||||
"Error: Cairo does not yet support the requested image format:\n"
|
||||
"Error: Cairo " PACKAGE_VERSION " does not yet support the requested image format:\n"
|
||||
"\tDepth: %d\n"
|
||||
"\tAlpha mask: 0x%08x\n"
|
||||
"\tRed mask: 0x%08x\n"
|
||||
"\tGreen mask: 0x%08x\n"
|
||||
"\tBlue mask: 0x%08x\n"
|
||||
"Please file an enhacement request (quoting the above) at:\n"
|
||||
"Please file an enhancement request (quoting the above) at:\n"
|
||||
PACKAGE_BUGREPORT "\n",
|
||||
bpp, am, rm, gm, bm);
|
||||
|
||||
|
@ -145,6 +154,10 @@ _cairo_format_from_pixman_format (pixman_format_t *pixman_format)
|
|||
return (cairo_format_t) -1;
|
||||
}
|
||||
|
||||
/* XXX: This function really should be eliminated. We don't really
|
||||
* want to advertise a cairo image surface that supports any possible
|
||||
* format. A minimal step would be to replace this function with one
|
||||
* that accepts a cairo_internal_format_t rather than mask values. */
|
||||
cairo_surface_t *
|
||||
_cairo_image_surface_create_with_masks (unsigned char *data,
|
||||
cairo_format_masks_t *format,
|
||||
|
@ -196,9 +209,6 @@ _create_pixman_format (cairo_format_t format)
|
|||
case CAIRO_FORMAT_A8:
|
||||
return pixman_format_create (PIXMAN_FORMAT_NAME_A8);
|
||||
break;
|
||||
case CAIRO_FORMAT_RGB16_565:
|
||||
return pixman_format_create (PIXMAN_FORMAT_NAME_RGB16_565);
|
||||
break;
|
||||
case CAIRO_FORMAT_RGB24:
|
||||
return pixman_format_create (PIXMAN_FORMAT_NAME_RGB24);
|
||||
break;
|
||||
|
@ -260,6 +270,7 @@ cairo_image_surface_create (cairo_format_t format,
|
|||
|
||||
return surface;
|
||||
}
|
||||
slim_hidden_def (cairo_image_surface_create);
|
||||
|
||||
cairo_surface_t *
|
||||
_cairo_image_surface_create_with_content (cairo_content_t content,
|
||||
|
@ -339,6 +350,7 @@ cairo_image_surface_create_for_data (unsigned char *data,
|
|||
|
||||
return surface;
|
||||
}
|
||||
slim_hidden_def (cairo_image_surface_create_for_data);
|
||||
|
||||
cairo_surface_t *
|
||||
_cairo_image_surface_create_for_data_with_content (unsigned char *data,
|
||||
|
@ -400,6 +412,8 @@ cairo_image_surface_get_format (cairo_surface_t *surface)
|
|||
return 0;
|
||||
}
|
||||
|
||||
assert (CAIRO_FORMAT_VALID (image_surface->format));
|
||||
|
||||
return image_surface->format;
|
||||
}
|
||||
|
||||
|
@ -423,6 +437,7 @@ cairo_image_surface_get_width (cairo_surface_t *surface)
|
|||
|
||||
return image_surface->width;
|
||||
}
|
||||
slim_hidden_def (cairo_image_surface_get_width);
|
||||
|
||||
/**
|
||||
* cairo_image_surface_get_height:
|
||||
|
@ -444,6 +459,7 @@ cairo_image_surface_get_height (cairo_surface_t *surface)
|
|||
|
||||
return image_surface->height;
|
||||
}
|
||||
slim_hidden_def (cairo_image_surface_get_height);
|
||||
|
||||
/**
|
||||
* cairo_image_surface_get_stride:
|
||||
|
@ -491,11 +507,20 @@ _cairo_format_from_content (cairo_content_t content)
|
|||
cairo_content_t
|
||||
_cairo_content_from_format (cairo_format_t format)
|
||||
{
|
||||
switch (format) {
|
||||
/* XXX: Use an int to avoid the warnings from mixed cairo_format_t
|
||||
* and cairo_internal_format_t values. The warnings are extremely
|
||||
* valuable since mixing enums can lead to subtle bugs. It's just
|
||||
* that cairo_internal_format_t is an interim approach to getting
|
||||
* bug #7294 fixed so we can release cairo 1.2.2 . */
|
||||
int f = format;
|
||||
|
||||
switch (f) {
|
||||
case CAIRO_FORMAT_ARGB32:
|
||||
case CAIRO_INTERNAL_FORMAT_ABGR32:
|
||||
return CAIRO_CONTENT_COLOR_ALPHA;
|
||||
case CAIRO_FORMAT_RGB24:
|
||||
case CAIRO_FORMAT_RGB16_565:
|
||||
case CAIRO_INTERNAL_FORMAT_BGR24:
|
||||
return CAIRO_CONTENT_COLOR;
|
||||
case CAIRO_FORMAT_A8:
|
||||
case CAIRO_FORMAT_A1:
|
||||
|
@ -639,6 +664,12 @@ _cairo_image_surface_set_filter (cairo_image_surface_t *surface, cairo_filter_t
|
|||
case CAIRO_FILTER_BILINEAR:
|
||||
pixman_filter = PIXMAN_FILTER_BILINEAR;
|
||||
break;
|
||||
case CAIRO_FILTER_GAUSSIAN:
|
||||
/* XXX: The GAUSSIAN value has no implementation in cairo
|
||||
* whatsoever, so it was really a mistake to have it in the
|
||||
* API. We could fix this by officially deprecating it, or
|
||||
* else inventing semantics and providing an actual
|
||||
* implementation for it. */
|
||||
default:
|
||||
pixman_filter = PIXMAN_FILTER_BEST;
|
||||
}
|
||||
|
@ -895,6 +926,9 @@ _cairo_image_surface_composite_trapezoids (cairo_operator_t op,
|
|||
mask_stride = (width + 31)/8;
|
||||
mask_bpp = 1;
|
||||
break;
|
||||
case CAIRO_ANTIALIAS_GRAY:
|
||||
case CAIRO_ANTIALIAS_SUBPIXEL:
|
||||
case CAIRO_ANTIALIAS_DEFAULT:
|
||||
default:
|
||||
format = pixman_format_create (PIXMAN_FORMAT_NAME_A8);
|
||||
mask_stride = (width + 3) & ~3;
|
||||
|
@ -1015,3 +1049,29 @@ const cairo_surface_backend_t cairo_image_surface_backend = {
|
|||
_cairo_image_surface_get_extents,
|
||||
NULL /* old_show_glyphs */
|
||||
};
|
||||
|
||||
/* A convenience function for when one needs to coerce an image
|
||||
* surface to an alternate format. */
|
||||
cairo_image_surface_t *
|
||||
_cairo_image_surface_clone (cairo_image_surface_t *surface,
|
||||
cairo_format_t format)
|
||||
{
|
||||
cairo_image_surface_t *clone;
|
||||
cairo_t *cr;
|
||||
double x, y;
|
||||
|
||||
clone = (cairo_image_surface_t *)
|
||||
cairo_image_surface_create (format,
|
||||
surface->width, surface->height);
|
||||
|
||||
cr = cairo_create (&clone->base);
|
||||
cairo_surface_get_device_offset (&surface->base, &x, &y);
|
||||
cairo_set_source_surface (cr, &surface->base, x, y);
|
||||
cairo_set_operator (cr, CAIRO_OPERATOR_SOURCE);
|
||||
cairo_paint (cr);
|
||||
cairo_destroy (cr);
|
||||
|
||||
cairo_surface_set_device_offset (&clone->base, x, y);
|
||||
|
||||
return clone;
|
||||
}
|
||||
|
|
|
@ -43,7 +43,7 @@ typedef struct _lzw_buf {
|
|||
int data_size;
|
||||
int num_data;
|
||||
uint32_t pending;
|
||||
int pending_bits;
|
||||
unsigned int pending_bits;
|
||||
} lzw_buf_t;
|
||||
|
||||
/* An lzw_buf_t is a simple, growable chunk of memory for holding
|
||||
|
@ -67,6 +67,10 @@ _lzw_buf_init (lzw_buf_t *buf, int size)
|
|||
size = 16;
|
||||
|
||||
buf->status = CAIRO_STATUS_SUCCESS;
|
||||
buf->data_size = size;
|
||||
buf->num_data = 0;
|
||||
buf->pending = 0;
|
||||
buf->pending_bits = 0;
|
||||
|
||||
buf->data = malloc (size);
|
||||
if (buf->data == NULL) {
|
||||
|
@ -74,11 +78,6 @@ _lzw_buf_init (lzw_buf_t *buf, int size)
|
|||
buf->status = CAIRO_STATUS_NO_MEMORY;
|
||||
return;
|
||||
}
|
||||
|
||||
buf->data_size = size;
|
||||
buf->num_data = 0;
|
||||
buf->pending = 0;
|
||||
buf->pending_bits = 0;
|
||||
}
|
||||
|
||||
/* Increase the buffer size by doubling.
|
||||
|
|
|
@ -170,6 +170,7 @@ cairo_matrix_translate (cairo_matrix_t *matrix, double tx, double ty)
|
|||
|
||||
cairo_matrix_multiply (matrix, &tmp, matrix);
|
||||
}
|
||||
slim_hidden_def (cairo_matrix_translate);
|
||||
|
||||
/**
|
||||
* cairo_matrix_init_scale:
|
||||
|
@ -357,7 +358,8 @@ slim_hidden_def(cairo_matrix_transform_point);
|
|||
void
|
||||
_cairo_matrix_transform_bounding_box (const cairo_matrix_t *matrix,
|
||||
double *x, double *y,
|
||||
double *width, double *height)
|
||||
double *width, double *height,
|
||||
cairo_bool_t *is_tight)
|
||||
{
|
||||
int i;
|
||||
double quad_x[4], quad_y[4];
|
||||
|
@ -404,6 +406,21 @@ _cairo_matrix_transform_bounding_box (const cairo_matrix_t *matrix,
|
|||
*y = min_y;
|
||||
*width = max_x - min_x;
|
||||
*height = max_y - min_y;
|
||||
|
||||
if (is_tight) {
|
||||
/* it's tight if and only if the four corner points form an axis-aligned
|
||||
rectangle.
|
||||
And that's true if and only if we can derive corners 0 and 3 from
|
||||
corners 1 and 2 in one of two straightforward ways...
|
||||
We could use a tolerance here but for now we'll fall back to FALSE in the case
|
||||
of floating point error.
|
||||
*/
|
||||
*is_tight =
|
||||
(quad_x[1] == quad_x[0] && quad_y[1] == quad_y[3] &&
|
||||
quad_x[2] == quad_x[3] && quad_y[2] == quad_y[0]) ||
|
||||
(quad_x[1] == quad_x[3] && quad_y[1] == quad_y[0] &&
|
||||
quad_x[2] == quad_x[0] && quad_y[2] == quad_y[3]);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
|
@ -97,7 +97,7 @@ typedef struct _cairo_command_show_glyphs {
|
|||
cairo_operator_t op;
|
||||
cairo_pattern_union_t source;
|
||||
cairo_glyph_t *glyphs;
|
||||
int num_glyphs;
|
||||
unsigned int num_glyphs;
|
||||
cairo_scaled_font_t *scaled_font;
|
||||
} cairo_command_show_glyphs_t;
|
||||
|
||||
|
|
|
@ -615,6 +615,26 @@ static const cairo_surface_backend_t cairo_meta_surface_backend = {
|
|||
_cairo_meta_surface_snapshot
|
||||
};
|
||||
|
||||
static cairo_path_fixed_t *
|
||||
_cairo_command_get_path (cairo_command_t *command)
|
||||
{
|
||||
switch (command->type) {
|
||||
case CAIRO_COMMAND_PAINT:
|
||||
case CAIRO_COMMAND_MASK:
|
||||
case CAIRO_COMMAND_SHOW_GLYPHS:
|
||||
return NULL;
|
||||
case CAIRO_COMMAND_STROKE:
|
||||
return &command->stroke.path;
|
||||
case CAIRO_COMMAND_FILL:
|
||||
return &command->fill.path;
|
||||
case CAIRO_COMMAND_INTERSECT_CLIP_PATH:
|
||||
return command->intersect_clip_path.path_pointer;
|
||||
}
|
||||
|
||||
ASSERT_NOT_REACHED;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
cairo_status_t
|
||||
_cairo_meta_surface_replay (cairo_surface_t *surface,
|
||||
cairo_surface_t *target)
|
||||
|
@ -624,6 +644,9 @@ _cairo_meta_surface_replay (cairo_surface_t *surface,
|
|||
int i, num_elements;
|
||||
cairo_int_status_t status;
|
||||
cairo_clip_t clip;
|
||||
cairo_bool_t has_device_transform = _cairo_surface_has_device_transform (target);
|
||||
cairo_matrix_t *device_transform = &target->device_transform;
|
||||
cairo_path_fixed_t path_copy, *dev_path;
|
||||
|
||||
meta = (cairo_meta_surface_t *) surface;
|
||||
status = CAIRO_STATUS_SUCCESS;
|
||||
|
@ -634,89 +657,118 @@ _cairo_meta_surface_replay (cairo_surface_t *surface,
|
|||
elements = _cairo_array_index (&meta->commands, 0);
|
||||
for (i = meta->replay_start_idx; i < num_elements; i++) {
|
||||
command = elements[i];
|
||||
switch (command->type) {
|
||||
case CAIRO_COMMAND_PAINT:
|
||||
|
||||
/* For all commands except intersect_clip_path, we have to
|
||||
* ensure the current clip gets set on the surface. */
|
||||
if (command->type != CAIRO_COMMAND_INTERSECT_CLIP_PATH) {
|
||||
status = _cairo_surface_set_clip (target, &clip);
|
||||
if (status)
|
||||
break;
|
||||
}
|
||||
|
||||
dev_path = _cairo_command_get_path (command);
|
||||
if (dev_path && has_device_transform) {
|
||||
_cairo_path_fixed_init_copy (&path_copy, dev_path);
|
||||
_cairo_path_fixed_device_transform (&path_copy, device_transform);
|
||||
dev_path = &path_copy;
|
||||
}
|
||||
|
||||
switch (command->type) {
|
||||
case CAIRO_COMMAND_PAINT:
|
||||
status = _cairo_surface_paint (target,
|
||||
command->paint.op,
|
||||
&command->paint.source.base);
|
||||
break;
|
||||
|
||||
case CAIRO_COMMAND_MASK:
|
||||
status = _cairo_surface_set_clip (target, &clip);
|
||||
if (status)
|
||||
break;
|
||||
|
||||
status = _cairo_surface_mask (target,
|
||||
command->mask.op,
|
||||
&command->mask.source.base,
|
||||
&command->mask.mask.base);
|
||||
break;
|
||||
|
||||
case CAIRO_COMMAND_STROKE:
|
||||
status = _cairo_surface_set_clip (target, &clip);
|
||||
if (status)
|
||||
break;
|
||||
{
|
||||
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);
|
||||
}
|
||||
|
||||
status = _cairo_surface_stroke (target,
|
||||
command->stroke.op,
|
||||
&command->stroke.source.base,
|
||||
&command->stroke.path,
|
||||
dev_path,
|
||||
&command->stroke.style,
|
||||
&command->stroke.ctm,
|
||||
&command->stroke.ctm_inverse,
|
||||
&dev_ctm,
|
||||
&dev_ctm_inverse,
|
||||
command->stroke.tolerance,
|
||||
command->stroke.antialias);
|
||||
break;
|
||||
|
||||
}
|
||||
case CAIRO_COMMAND_FILL:
|
||||
status = _cairo_surface_set_clip (target, &clip);
|
||||
if (status)
|
||||
break;
|
||||
|
||||
status = _cairo_surface_fill (target,
|
||||
command->fill.op,
|
||||
&command->fill.source.base,
|
||||
&command->fill.path,
|
||||
dev_path,
|
||||
command->fill.fill_rule,
|
||||
command->fill.tolerance,
|
||||
command->fill.antialias);
|
||||
break;
|
||||
|
||||
case CAIRO_COMMAND_SHOW_GLYPHS:
|
||||
status = _cairo_surface_set_clip (target, &clip);
|
||||
if (status)
|
||||
break;
|
||||
{
|
||||
cairo_glyph_t *glyphs = command->show_glyphs.glyphs;
|
||||
cairo_glyph_t *dev_glyphs = glyphs;
|
||||
int i, num_glyphs = command->show_glyphs.num_glyphs;
|
||||
|
||||
if (has_device_transform) {
|
||||
dev_glyphs = malloc (sizeof (cairo_glyph_t) * num_glyphs);
|
||||
if (dev_glyphs == NULL) {
|
||||
status = CAIRO_STATUS_NO_MEMORY;
|
||||
break;
|
||||
}
|
||||
for (i = 0; i < num_glyphs; i++) {
|
||||
dev_glyphs[i] = glyphs[i];
|
||||
cairo_matrix_transform_point (device_transform,
|
||||
&dev_glyphs[i].x,
|
||||
&dev_glyphs[i].y);
|
||||
}
|
||||
}
|
||||
|
||||
status = _cairo_surface_show_glyphs (target,
|
||||
command->show_glyphs.op,
|
||||
&command->show_glyphs.source.base,
|
||||
command->show_glyphs.glyphs,
|
||||
command->show_glyphs.num_glyphs,
|
||||
dev_glyphs, num_glyphs,
|
||||
command->show_glyphs.scaled_font);
|
||||
break;
|
||||
|
||||
if (dev_glyphs != glyphs)
|
||||
free (dev_glyphs);
|
||||
|
||||
break;
|
||||
}
|
||||
case CAIRO_COMMAND_INTERSECT_CLIP_PATH:
|
||||
/* XXX Meta surface clipping is broken and requires some
|
||||
* cairo-gstate.c rewriting. Work around it for now. */
|
||||
if (command->intersect_clip_path.path_pointer == NULL)
|
||||
if (dev_path == NULL)
|
||||
status = _cairo_clip_reset (&clip);
|
||||
else
|
||||
status = _cairo_clip_clip (&clip,
|
||||
command->intersect_clip_path.path_pointer,
|
||||
status = _cairo_clip_clip (&clip, dev_path,
|
||||
command->intersect_clip_path.fill_rule,
|
||||
command->intersect_clip_path.tolerance,
|
||||
command->intersect_clip_path.antialias,
|
||||
target);
|
||||
break;
|
||||
|
||||
default:
|
||||
ASSERT_NOT_REACHED;
|
||||
}
|
||||
|
||||
if (dev_path == &path_copy)
|
||||
_cairo_path_fixed_fini (&path_copy);
|
||||
|
||||
if (status)
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -31,7 +31,7 @@
|
|||
* The Initial Developer of the Original Code is Mozilla Corporation.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Vladimir Vukicevic <vladimir@mozilla.com>
|
||||
* Vladimir Vukicevic <vladimir@mozilla.com>
|
||||
*/
|
||||
|
||||
#include <Carbon/Carbon.h>
|
||||
|
@ -50,28 +50,28 @@
|
|||
#undef NQUARTZ_DEBUG
|
||||
|
||||
#ifdef NQUARTZ_DEBUG
|
||||
#define ND(_x) fprintf _x
|
||||
#define ND(_x) fprintf _x
|
||||
#else
|
||||
#define ND(_x) do {} while(0)
|
||||
#define ND(_x) do {} while(0)
|
||||
#endif
|
||||
|
||||
/* This method is private, but it exists. Its params are are exposed
|
||||
* as args to the NS* method, but not as CG.
|
||||
*/
|
||||
enum PrivateCGCompositeMode {
|
||||
kPrivateCGCompositeClear = 0,
|
||||
kPrivateCGCompositeCopy = 1,
|
||||
kPrivateCGCompositeSourceOver = 2,
|
||||
kPrivateCGCompositeSourceIn = 3,
|
||||
kPrivateCGCompositeSourceOut = 4,
|
||||
kPrivateCGCompositeSourceAtop = 5,
|
||||
kPrivateCGCompositeDestinationOver = 6,
|
||||
kPrivateCGCompositeDestinationIn = 7,
|
||||
kPrivateCGCompositeDestinationOut = 8,
|
||||
kPrivateCGCompositeDestinationAtop = 9,
|
||||
kPrivateCGCompositeXOR = 10,
|
||||
kPrivateCGCompositePlusDarker = 11, // (max (0, (1-d) + (1-s)))
|
||||
kPrivateCGCompositePlusLighter = 12, // (min (1, s + d))
|
||||
kPrivateCGCompositeClear = 0,
|
||||
kPrivateCGCompositeCopy = 1,
|
||||
kPrivateCGCompositeSourceOver = 2,
|
||||
kPrivateCGCompositeSourceIn = 3,
|
||||
kPrivateCGCompositeSourceOut = 4,
|
||||
kPrivateCGCompositeSourceAtop = 5,
|
||||
kPrivateCGCompositeDestinationOver = 6,
|
||||
kPrivateCGCompositeDestinationIn = 7,
|
||||
kPrivateCGCompositeDestinationOut = 8,
|
||||
kPrivateCGCompositeDestinationAtop = 9,
|
||||
kPrivateCGCompositeXOR = 10,
|
||||
kPrivateCGCompositePlusDarker = 11, // (max (0, (1-d) + (1-s)))
|
||||
kPrivateCGCompositePlusLighter = 12, // (min (1, s + d))
|
||||
};
|
||||
typedef enum PrivateCGCompositeMode PrivateCGCompositeMode;
|
||||
CG_EXTERN void CGContextSetCompositeOperation (CGContextRef, PrivateCGCompositeMode);
|
||||
|
@ -683,8 +683,8 @@ _cairo_nquartz_setup_source (cairo_nquartz_surface_t *surface,
|
|||
// pattern (which may be stack allocated)
|
||||
CGContextSaveGState(surface->cgContext);
|
||||
|
||||
CGColorSpaceRef patternSpace = CGColorSpaceCreatePattern(NULL);
|
||||
CGContextSetFillColorSpace (surface->cgContext, patternSpace);
|
||||
CGColorSpaceRef patternSpace = CGColorSpaceCreatePattern(NULL);
|
||||
CGContextSetFillColorSpace (surface->cgContext, patternSpace);
|
||||
CGContextSetFillPattern (surface->cgContext, pattern, &patternAlpha);
|
||||
CGColorSpaceRelease (patternSpace);
|
||||
|
||||
|
@ -732,7 +732,7 @@ static void
|
|||
ImageDataReleaseFunc(void *info, const void *data, size_t size)
|
||||
{
|
||||
if (data != NULL) {
|
||||
free((void *) data);
|
||||
free((void *) data);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -941,7 +941,7 @@ _cairo_nquartz_surface_acquire_dest_image (void *abstract_surface,
|
|||
|
||||
status = _cairo_nquartz_get_image (surface, image_out, &data);
|
||||
if (status)
|
||||
return status;
|
||||
return status;
|
||||
|
||||
*image_extra = data;
|
||||
|
||||
|
@ -1521,7 +1521,7 @@ _cairo_nquartz_surface_create_internal (CGContextRef cgContext,
|
|||
/* Init the base surface */
|
||||
surface = malloc(sizeof(cairo_nquartz_surface_t));
|
||||
if (surface == NULL) {
|
||||
_cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
_cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
@ -1578,7 +1578,7 @@ cairo_nquartz_surface_create_for_agl_context (AGLContext aglContext,
|
|||
if (!surf) {
|
||||
CGContextRelease (cgc);
|
||||
// create_internal will have set an error
|
||||
return (cairo_surface_t*) &_cairo_surface_nil;
|
||||
return (cairo_surface_t*) &_cairo_surface_nil;
|
||||
}
|
||||
|
||||
return (cairo_surface_t *) surf;
|
||||
|
@ -1600,7 +1600,7 @@ cairo_nquartz_surface_create_for_cg_context (CGContextRef cgContext,
|
|||
if (!surf) {
|
||||
CGContextRelease (cgContext);
|
||||
// create_internal will have set an error
|
||||
return (cairo_surface_t*) &_cairo_surface_nil;
|
||||
return (cairo_surface_t*) &_cairo_surface_nil;
|
||||
}
|
||||
|
||||
return (cairo_surface_t *) surf;
|
||||
|
@ -1643,17 +1643,17 @@ cairo_nquartz_surface_create (cairo_format_t format,
|
|||
* quantities.
|
||||
*/
|
||||
_cairo_error (CAIRO_STATUS_INVALID_FORMAT);
|
||||
return (cairo_surface_t*) &_cairo_surface_nil;
|
||||
return (cairo_surface_t*) &_cairo_surface_nil;
|
||||
} else {
|
||||
_cairo_error (CAIRO_STATUS_INVALID_FORMAT);
|
||||
return (cairo_surface_t*) &_cairo_surface_nil;
|
||||
return (cairo_surface_t*) &_cairo_surface_nil;
|
||||
}
|
||||
|
||||
imageData = malloc (height * stride);
|
||||
if (!imageData) {
|
||||
CGColorSpaceRelease (cgColorspace);
|
||||
_cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
return (cairo_surface_t*) &_cairo_surface_nil;
|
||||
return (cairo_surface_t*) &_cairo_surface_nil;
|
||||
}
|
||||
|
||||
cgc = CGBitmapContextCreate (imageData,
|
||||
|
@ -1666,7 +1666,7 @@ cairo_nquartz_surface_create (cairo_format_t format,
|
|||
CGColorSpaceRelease (cgColorspace);
|
||||
|
||||
if (!cgc) {
|
||||
_cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
_cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
return (cairo_surface_t*) &_cairo_surface_nil;
|
||||
}
|
||||
|
||||
|
@ -1675,7 +1675,7 @@ cairo_nquartz_surface_create (cairo_format_t format,
|
|||
if (!surf) {
|
||||
CGContextRelease (cgc);
|
||||
// create_internal will have set an error
|
||||
return (cairo_surface_t*) &_cairo_surface_nil;
|
||||
return (cairo_surface_t*) &_cairo_surface_nil;
|
||||
}
|
||||
|
||||
surf->imageData = imageData;
|
||||
|
@ -1714,34 +1714,34 @@ void ExportCGImageToPNGFile(CGImageRef inImageRef, char* dest)
|
|||
|
||||
// create the data reference
|
||||
result = QTNewDataReferenceFromFullPathCFString(inPath, kQTNativeDefaultPathStyle,
|
||||
0, &dataRef, &dataRefType);
|
||||
0, &dataRef, &dataRefType);
|
||||
|
||||
if (NULL != dataRef && noErr == result) {
|
||||
// get the PNG exporter
|
||||
result = OpenADefaultComponent(GraphicsExporterComponentType, kQTFileTypePNG,
|
||||
&grex);
|
||||
// get the PNG exporter
|
||||
result = OpenADefaultComponent(GraphicsExporterComponentType, kQTFileTypePNG,
|
||||
&grex);
|
||||
|
||||
if (grex) {
|
||||
// tell the exporter where to find its source image
|
||||
result = GraphicsExportSetInputCGImage(grex, inImageRef);
|
||||
if (grex) {
|
||||
// tell the exporter where to find its source image
|
||||
result = GraphicsExportSetInputCGImage(grex, inImageRef);
|
||||
|
||||
if (noErr == result) {
|
||||
// tell the exporter where to save the exporter image
|
||||
result = GraphicsExportSetOutputDataReference(grex, dataRef,
|
||||
dataRefType);
|
||||
if (noErr == result) {
|
||||
// tell the exporter where to save the exporter image
|
||||
result = GraphicsExportSetOutputDataReference(grex, dataRef,
|
||||
dataRefType);
|
||||
|
||||
if (noErr == result) {
|
||||
// write the PNG file
|
||||
result = GraphicsExportDoExport(grex, &sizeWritten);
|
||||
}
|
||||
}
|
||||
if (noErr == result) {
|
||||
// write the PNG file
|
||||
result = GraphicsExportDoExport(grex, &sizeWritten);
|
||||
}
|
||||
}
|
||||
|
||||
// remember to close the component
|
||||
CloseComponent(grex);
|
||||
}
|
||||
// remember to close the component
|
||||
CloseComponent(grex);
|
||||
}
|
||||
|
||||
// remember to dispose of the data reference handle
|
||||
DisposeHandle(dataRef);
|
||||
// remember to dispose of the data reference handle
|
||||
DisposeHandle(dataRef);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -46,29 +46,29 @@
|
|||
|
||||
CAIRO_BEGIN_DECLS
|
||||
|
||||
cairo_surface_t *
|
||||
cairo_public cairo_surface_t *
|
||||
cairo_nquartz_surface_create (cairo_format_t format,
|
||||
unsigned int width,
|
||||
unsigned int height);
|
||||
|
||||
#ifdef CAIRO_NQUARTZ_SUPPORT_AGL
|
||||
cairo_surface_t *
|
||||
cairo_public cairo_surface_t *
|
||||
cairo_nquartz_surface_create_for_agl_context (AGLContext aglContext,
|
||||
unsigned int width,
|
||||
unsigned int height,
|
||||
cairo_bool_t y_grows_down);
|
||||
#endif
|
||||
|
||||
cairo_surface_t *
|
||||
cairo_public cairo_surface_t *
|
||||
cairo_nquartz_surface_create_for_cg_context (CGContextRef cgContext,
|
||||
unsigned int width,
|
||||
unsigned int height,
|
||||
cairo_bool_t y_grows_down);
|
||||
|
||||
cairo_bool_t
|
||||
cairo_public cairo_bool_t
|
||||
cairo_surface_is_nquartz (cairo_surface_t *surf);
|
||||
|
||||
CGContextRef
|
||||
cairo_public CGContextRef
|
||||
cairo_nquartz_surface_get_cg_context (cairo_surface_t *surf);
|
||||
|
||||
CAIRO_END_DECLS
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
/* vim: set sw=4 sts=4 et cin: */
|
||||
/* cairo - a vector graphics library with display and print output
|
||||
*
|
||||
* Copyright © 2004 Red Hat, Inc
|
||||
* Copyright (c) 2005-2006 netlabs.org
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it either under the terms of the GNU Lesser General Public
|
||||
|
@ -27,41 +28,50 @@
|
|||
*
|
||||
* The Original Code is the cairo graphics library.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Red Hat, Inc.
|
||||
* The Initial Developer of the Original Code is
|
||||
* Doodle <doodle@scenergy.dfmk.hu>
|
||||
*
|
||||
* Contributor(s):
|
||||
* Kristian Høgsberg <krh@redhat.com>
|
||||
* Peter Weilbacher <mozilla@Weilbacher.org>
|
||||
*/
|
||||
|
||||
#include "cairoint.h"
|
||||
#ifndef CAIRO_OS2_PRIVATE_H
|
||||
#define CAIRO_OS2_PRIVATE_H
|
||||
|
||||
#ifndef CAIRO_FONT_SUBSET_PRIVATE_H
|
||||
#define CAIRO_FONT_SUBSET_PRIVATE_H
|
||||
#define INCL_DOS
|
||||
#define INCL_DOSSEMAPHORES
|
||||
#define INCL_DOSERRORS
|
||||
#define INCL_WIN
|
||||
#define INCL_GPI
|
||||
#ifdef __WATCOMC__
|
||||
# include <os2.h>
|
||||
#else
|
||||
# include <os2emx.h>
|
||||
#endif
|
||||
|
||||
typedef struct cairo_font_subset_backend cairo_font_subset_backend_t;
|
||||
typedef struct cairo_font_subset cairo_font_subset_t;
|
||||
struct cairo_font_subset {
|
||||
cairo_font_subset_backend_t *backend;
|
||||
cairo_unscaled_font_t *unscaled_font;
|
||||
unsigned int font_id;
|
||||
char *base_font;
|
||||
int num_glyphs;
|
||||
int *widths;
|
||||
long x_min, y_min, x_max, y_max;
|
||||
long ascent, descent;
|
||||
};
|
||||
#include <cairo-os2.h>
|
||||
#include <cairoint.h>
|
||||
|
||||
cairo_private int
|
||||
_cairo_font_subset_use_glyph (cairo_font_subset_t *font, int glyph);
|
||||
typedef struct _cairo_os2_surface
|
||||
{
|
||||
cairo_surface_t base;
|
||||
|
||||
cairo_private cairo_status_t
|
||||
_cairo_font_subset_generate (cairo_font_subset_t *font,
|
||||
const char **data, unsigned long *length);
|
||||
/* Mutex semaphore to protect private fields from concurrent access */
|
||||
HMTX hmtx_use_private_fields;
|
||||
/* Private fields: */
|
||||
HPS hps_client_window;
|
||||
HWND hwnd_client_window;
|
||||
BITMAPINFO2 bitmap_info;
|
||||
unsigned char *pixels;
|
||||
cairo_image_surface_t *image_surface;
|
||||
int pixel_array_lend_count;
|
||||
HEV hev_pixel_array_came_back;
|
||||
|
||||
cairo_private void
|
||||
_cairo_font_subset_destroy (cairo_font_subset_t *font);
|
||||
RECTL rcl_dirty_area;
|
||||
cairo_bool_t dirty_area_present;
|
||||
|
||||
cairo_private cairo_font_subset_t *
|
||||
_cairo_font_subset_create (cairo_unscaled_font_t *unscaled_font);
|
||||
/* General flags: */
|
||||
cairo_bool_t blit_as_changes;
|
||||
} cairo_os2_surface_t;
|
||||
|
||||
#endif /* CAIRO_FONT_SUBSET_PRIVATE_H */
|
||||
#endif /* CAIRO_OS2_PRIVATE_H */
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -0,0 +1,201 @@
|
|||
/* vim: set sw=4 sts=4 et cin: */
|
||||
/* cairo - a vector graphics library with display and print output
|
||||
*
|
||||
* Copyright (c) 2005-2006 netlabs.org
|
||||
*
|
||||
* 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
|
||||
* Doodle <doodle@scenergy.dfmk.hu>
|
||||
*
|
||||
* Contributor(s):
|
||||
* Peter Weilbacher <mozilla@Weilbacher.org>
|
||||
*/
|
||||
|
||||
#ifndef _CAIRO_OS2_H_
|
||||
#define _CAIRO_OS2_H_
|
||||
|
||||
#include <cairo.h>
|
||||
|
||||
CAIRO_BEGIN_DECLS
|
||||
|
||||
/* The OS/2 Specific Cairo API */
|
||||
|
||||
/* cairo_os2_init () : */
|
||||
/* */
|
||||
/* Initializes the Cairo library. This function is automatically */
|
||||
/* called if Cairo was compiled to be a DLL (however it's not a */
|
||||
/* problem if it's called multiple times), but if you link to */
|
||||
/* Cairo statically, you have to call it once to set up Cairo's */
|
||||
/* internal structures and mutexes. */
|
||||
|
||||
cairo_public void
|
||||
cairo_os2_init (void);
|
||||
|
||||
/* cairo_os2_fini () : */
|
||||
/* */
|
||||
/* Uninitializes the Cairo library. This function is automatically */
|
||||
/* called if Cairo was compiled to be a DLL (however it's not a */
|
||||
/* problem if it's called multiple times), but if you link to */
|
||||
/* Cairo statically, you have to call it once to shut down Cairo, */
|
||||
/* to let it free all the resources it has allocated. */
|
||||
|
||||
cairo_public void
|
||||
cairo_os2_fini (void);
|
||||
|
||||
#if CAIRO_HAS_OS2_SURFACE
|
||||
|
||||
/* cairo_os2_surface_create () : */
|
||||
/* */
|
||||
/* Create a Cairo surface which is bounded to a given presentation */
|
||||
/* space (HPS). The surface will be created to have the given */
|
||||
/* size. */
|
||||
/* By default: Every change to the surface will be made visible */
|
||||
/* immediately by blitting it into the window. This */
|
||||
/* can be changed with the */
|
||||
/* cairo_os2_surface_set_manual_window_refresh () API. */
|
||||
/* Note that the surface will contain garbage when created, so the */
|
||||
/* pixels have to be initialized by hand first. You can use the */
|
||||
/* Cairo functions to fill it with black, or use the */
|
||||
/* cairo_surface_mark_dirty () API to fill the surface with pixels */
|
||||
/* from the window/HPS. */
|
||||
|
||||
cairo_public cairo_surface_t *
|
||||
cairo_os2_surface_create (HPS hps_client_window,
|
||||
int width,
|
||||
int height);
|
||||
|
||||
/* cairo_os2_surface_set_hwnd () : */
|
||||
/* */
|
||||
/* Sets window handle for surface. If Cairo wants to blit into the */
|
||||
/* window because it's set that it should blit as the surface */
|
||||
/* changes (see cairo_os2_surface_set_manual_window_refresh () API),*/
|
||||
/* then there are two ways it can choose: */
|
||||
/* If it knows the HWND of the surface, then it invalidates that */
|
||||
/* area, so the application will get a WM_PAINT message and it can */
|
||||
/* call cairo_os2_surface_refresh_window () to redraw that area. */
|
||||
/* Otherwise cairo itself will use the HPS it got at surface */
|
||||
/* creation time, and blit the pixels itself. */
|
||||
/* It's also a solution, but experience shows that if this happens */
|
||||
/* from a non-PM thread, then it can screw up PM internals. */
|
||||
/* */
|
||||
/* So, best solution is to set the HWND for the surface after the */
|
||||
/* surface creation, so every blit will be done from application's */
|
||||
/* message processing loop, which is the safest way to do. */
|
||||
|
||||
cairo_public void
|
||||
cairo_os2_surface_set_hwnd (cairo_surface_t *surface,
|
||||
HWND hwnd_client_window);
|
||||
|
||||
/* cairo_os2_surface_set_size () : */
|
||||
/* */
|
||||
/* When the client window is resized, call this API so the */
|
||||
/* underlaying surface will also be resized. This function will */
|
||||
/* reallocate everything, so you'll have to redraw everything in */
|
||||
/* the surface after this call. */
|
||||
/* The surface will contain garbage after the resizing, just like */
|
||||
/* after cairo_os2_surface_create (), so all those notes also apply */
|
||||
/* here, please read that! */
|
||||
/* */
|
||||
/* The timeout value is in milliseconds, and tells how much the */
|
||||
/* function should wait on other parts of the program to release */
|
||||
/* the buffers. It is necessary, because it can be that Cairo is */
|
||||
/* just drawing something into the surface while we want to */
|
||||
/* destroy and recreate it. */
|
||||
/* Returns CAIRO_STATUS_SUCCESS if the surface could be resized, */
|
||||
/* or returns other error code if */
|
||||
/* - the surface is not a real OS/2 Surface */
|
||||
/* - there is not enough memory to resize the surface */
|
||||
/* - waiting for all the buffers to be released timed out */
|
||||
|
||||
cairo_public int
|
||||
cairo_os2_surface_set_size (cairo_surface_t *surface,
|
||||
int new_width,
|
||||
int new_height,
|
||||
int timeout);
|
||||
|
||||
/* cairo_os2_surface_refresh_window () : */
|
||||
/* */
|
||||
/* This function can be used to force a repaint of a given area */
|
||||
/* of the client window. Most of the time it is called from the */
|
||||
/* WM_PAINT processing of the window proc. However, it can be */
|
||||
/* called anytime if a given part of the window has to be updated. */
|
||||
/* */
|
||||
/* The function expects a HPS of the window, and a RECTL to tell */
|
||||
/* which part of the window should be redrawn. */
|
||||
/* The returned values of WinBeginPaint () is just perfect here, */
|
||||
/* but you can also get the HPS by using the WinGetPS () function, */
|
||||
/* and you can assemble your own update rect by hand. */
|
||||
/* If the hps_begin_paint parameter is NULL, the function will use */
|
||||
/* the HPS you passed in to cairo_os2_surface_create (). If the */
|
||||
/* prcl_begin_paint_rect parameter is NULL, the function will query */
|
||||
/* the current window size and repaint the whole window. */
|
||||
/* */
|
||||
/* Cairo/2 assumes that if you told the HWND to the surface using */
|
||||
/* the cairo_os2_surface_set_hwnd () API, then this function will */
|
||||
/* be called by the application every time it gets a WM_PAINT for */
|
||||
/* that HWND. If the HWND is told to the surface, Cairo uses this */
|
||||
/* function to handle dirty areas too, so you were warned. :) */
|
||||
|
||||
cairo_public void
|
||||
cairo_os2_surface_refresh_window (cairo_surface_t *surface,
|
||||
HPS hps_begin_paint,
|
||||
PRECTL prcl_begin_paint_rect);
|
||||
|
||||
/* cairo_os2_surface_set_manual_window_refresh () : */
|
||||
/* */
|
||||
/* This API can tell Cairo if it should show every change to this */
|
||||
/* surface immediately in the window, or if it should be cached */
|
||||
/* and will only be visible if the user calls the */
|
||||
/* cairo_os2_surface_refresh_window () API explicitly. */
|
||||
/* If the HWND was not told to Cairo, then it will use the HPS to */
|
||||
/* blit the graphics. Otherwise it will invalidate the given */
|
||||
/* window region so the user will get WM_PAINT to redraw that area */
|
||||
/* of the window. */
|
||||
/* */
|
||||
/* So, if you're only interested in displaying the final result */
|
||||
/* after several drawing operations, you might get better */
|
||||
/* performance if you put the surface into a manual refresh mode */
|
||||
/* by passing a true value to cairo_os2_surface_set_manual_refresh()*/
|
||||
/* and then calling cairo_os2_surface_refresh() whenever desired. */
|
||||
|
||||
cairo_public void
|
||||
cairo_os2_surface_set_manual_window_refresh (cairo_surface_t *surface,
|
||||
cairo_bool_t manual_refresh);
|
||||
|
||||
/* cairo_os2_surface_get_manual_window_refresh () : */
|
||||
/* */
|
||||
/* This API can return the current mode of the surface. It is */
|
||||
/* TRUE by default. */
|
||||
|
||||
cairo_public cairo_bool_t
|
||||
cairo_os2_surface_get_manual_window_refresh (cairo_surface_t *surface);
|
||||
|
||||
#endif /* CAIRO_HAS_OS2_SURFACE */
|
||||
|
||||
CAIRO_END_DECLS
|
||||
|
||||
#endif /* _CAIRO_OS2_H_ */
|
|
@ -60,7 +60,7 @@ _cairo_output_stream_init (cairo_output_stream_t *stream,
|
|||
cairo_output_stream_write_func_t write_func,
|
||||
cairo_output_stream_close_func_t close_func);
|
||||
|
||||
cairo_private void
|
||||
cairo_private cairo_status_t
|
||||
_cairo_output_stream_fini (cairo_output_stream_t *stream);
|
||||
|
||||
|
||||
|
@ -86,10 +86,16 @@ _cairo_output_stream_create (cairo_write_func_t write_func,
|
|||
cairo_close_func_t close_func,
|
||||
void *closure);
|
||||
|
||||
cairo_private void
|
||||
/* Returns the final status value associated with this object, just
|
||||
* before its last gasp. This final status value will capture any
|
||||
* status failure returned by the stream's close_func as well. */
|
||||
cairo_private cairo_status_t
|
||||
_cairo_output_stream_close (cairo_output_stream_t *stream);
|
||||
|
||||
cairo_private void
|
||||
/* Returns the final status value associated with this object, just
|
||||
* before its last gasp. This final status value will capture any
|
||||
* status failure returned by the stream's close_func as well. */
|
||||
cairo_private cairo_status_t
|
||||
_cairo_output_stream_destroy (cairo_output_stream_t *stream);
|
||||
|
||||
cairo_private void
|
||||
|
|
|
@ -57,13 +57,12 @@ _cairo_output_stream_init (cairo_output_stream_t *stream,
|
|||
stream->closed = FALSE;
|
||||
}
|
||||
|
||||
cairo_private void
|
||||
cairo_private cairo_status_t
|
||||
_cairo_output_stream_fini (cairo_output_stream_t *stream)
|
||||
{
|
||||
_cairo_output_stream_close (stream);
|
||||
return _cairo_output_stream_close (stream);
|
||||
}
|
||||
|
||||
|
||||
const cairo_output_stream_t cairo_output_stream_nil = {
|
||||
NULL, /* write_func */
|
||||
NULL, /* close_func */
|
||||
|
@ -130,37 +129,44 @@ _cairo_output_stream_create (cairo_write_func_t write_func,
|
|||
return &stream->base;
|
||||
}
|
||||
|
||||
void
|
||||
cairo_status_t
|
||||
_cairo_output_stream_close (cairo_output_stream_t *stream)
|
||||
{
|
||||
cairo_status_t status;
|
||||
|
||||
if (stream->closed)
|
||||
return;
|
||||
return stream->status;
|
||||
|
||||
if (stream == &cairo_output_stream_nil ||
|
||||
stream == &cairo_output_stream_nil_write_error)
|
||||
{
|
||||
return;
|
||||
return stream->status;
|
||||
}
|
||||
|
||||
if (stream->close_func) {
|
||||
status = stream->close_func (stream);
|
||||
if (status)
|
||||
/* Don't overwrite a pre-existing status failure. */
|
||||
if (stream->status == CAIRO_STATUS_SUCCESS)
|
||||
stream->status = status;
|
||||
}
|
||||
|
||||
stream->closed = TRUE;
|
||||
|
||||
return stream->status;
|
||||
}
|
||||
|
||||
void
|
||||
cairo_status_t
|
||||
_cairo_output_stream_destroy (cairo_output_stream_t *stream)
|
||||
{
|
||||
if (stream == NULL)
|
||||
return;
|
||||
cairo_status_t status;
|
||||
|
||||
_cairo_output_stream_fini (stream);
|
||||
if (stream == NULL)
|
||||
return CAIRO_STATUS_NULL_POINTER;
|
||||
|
||||
status = _cairo_output_stream_fini (stream);
|
||||
free (stream);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -184,7 +190,7 @@ _cairo_output_stream_write_hex_string (cairo_output_stream_t *stream,
|
|||
{
|
||||
const char hex_chars[] = "0123456789abcdef";
|
||||
char buffer[2];
|
||||
int i, column;
|
||||
unsigned int i, column;
|
||||
|
||||
if (stream->status)
|
||||
return;
|
||||
|
@ -459,8 +465,10 @@ _cairo_output_stream_create_for_filename (const char *filename)
|
|||
return (cairo_output_stream_t *) &cairo_output_stream_nil_write_error;
|
||||
|
||||
stream = malloc (sizeof *stream);
|
||||
if (stream == NULL)
|
||||
if (stream == NULL) {
|
||||
fclose (file);
|
||||
return (cairo_output_stream_t *) &cairo_output_stream_nil;
|
||||
}
|
||||
|
||||
_cairo_output_stream_init (&stream->base, stdio_write, stdio_close);
|
||||
stream->file = file;
|
||||
|
|
|
@ -163,6 +163,25 @@ _cairo_paginated_surface_finish (void *abstract_surface)
|
|||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
static cairo_surface_t *
|
||||
_cairo_paginated_surface_create_image_surface (void *abstract_surface,
|
||||
int width,
|
||||
int height)
|
||||
{
|
||||
cairo_paginated_surface_t *surface = abstract_surface;
|
||||
cairo_surface_t *image;
|
||||
cairo_font_options_t options;
|
||||
|
||||
image = _cairo_image_surface_create_with_content (surface->content,
|
||||
width,
|
||||
height);
|
||||
|
||||
cairo_surface_get_font_options (&surface->base, &options);
|
||||
_cairo_surface_set_font_options (image, &options);
|
||||
|
||||
return image;
|
||||
}
|
||||
|
||||
static cairo_status_t
|
||||
_cairo_paginated_surface_acquire_source_image (void *abstract_surface,
|
||||
cairo_image_surface_t **image_out,
|
||||
|
@ -174,9 +193,9 @@ _cairo_paginated_surface_acquire_source_image (void *abstract_surface,
|
|||
|
||||
_cairo_surface_get_extents (surface->target, &extents);
|
||||
|
||||
image = _cairo_image_surface_create_with_content (surface->content,
|
||||
extents.width,
|
||||
extents.height);
|
||||
image = _cairo_paginated_surface_create_image_surface (surface,
|
||||
extents.width,
|
||||
extents.height);
|
||||
|
||||
_cairo_meta_surface_replay (surface->meta, image);
|
||||
|
||||
|
@ -221,9 +240,9 @@ _paint_page (cairo_paginated_surface_t *surface)
|
|||
double y_scale = surface->base.y_fallback_resolution / 72.0;
|
||||
cairo_matrix_t matrix;
|
||||
|
||||
image = _cairo_image_surface_create_with_content (surface->content,
|
||||
surface->width * x_scale,
|
||||
surface->height * y_scale);
|
||||
image = _cairo_paginated_surface_create_image_surface (surface,
|
||||
surface->width * x_scale,
|
||||
surface->height * y_scale);
|
||||
_cairo_surface_set_device_scale (image, x_scale, y_scale);
|
||||
|
||||
_cairo_meta_surface_replay (surface->meta, image);
|
||||
|
@ -460,9 +479,9 @@ _cairo_paginated_surface_snapshot (void *abstract_other)
|
|||
|
||||
_cairo_surface_get_extents (other->target, &extents);
|
||||
|
||||
surface = _cairo_image_surface_create_with_content (other->content,
|
||||
extents.width,
|
||||
extents.height);
|
||||
surface = _cairo_paginated_surface_create_image_surface (other,
|
||||
extents.width,
|
||||
extents.height);
|
||||
|
||||
_cairo_meta_surface_replay (other->meta, surface);
|
||||
|
||||
|
|
|
@ -125,9 +125,6 @@ _cpdc_close_path (void *closure)
|
|||
|
||||
cpdc->count += 1;
|
||||
|
||||
cpdc->current_point.x = 0;
|
||||
cpdc->current_point.y = 0;
|
||||
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
|
@ -304,9 +301,6 @@ _cpdp_close_path (void *closure)
|
|||
|
||||
cpdp->data += data->header.length;
|
||||
|
||||
cpdp->current_point.x = 0;
|
||||
cpdp->current_point.y = 0;
|
||||
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
|
|
|
@ -59,7 +59,7 @@ typedef struct cairo_stroker {
|
|||
cairo_stroke_face_t first_face;
|
||||
|
||||
cairo_bool_t dashed;
|
||||
int dash_index;
|
||||
unsigned int dash_index;
|
||||
int dash_on;
|
||||
double dash_remain;
|
||||
} cairo_stroker_t;
|
||||
|
@ -114,7 +114,7 @@ _cairo_stroker_start_dash (cairo_stroker_t *stroker)
|
|||
{
|
||||
double offset;
|
||||
int on = 1;
|
||||
int i = 0;
|
||||
unsigned int i = 0;
|
||||
|
||||
offset = stroker->style->dash_offset;
|
||||
|
||||
|
@ -699,6 +699,8 @@ _cairo_stroker_line_to_dashed (void *closure, cairo_point_t *point)
|
|||
cairo_point_t *p2 = point;
|
||||
cairo_slope_t slope;
|
||||
|
||||
stroker->has_sub_path = stroker->dash_on;
|
||||
|
||||
if (p1->x == p2->x && p1->y == p2->y)
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
|
||||
|
@ -758,6 +760,7 @@ _cairo_stroker_line_to_dashed (void *closure, cairo_point_t *point)
|
|||
return status;
|
||||
}
|
||||
}
|
||||
stroker->has_sub_path = TRUE;
|
||||
}
|
||||
if (remain) {
|
||||
/*
|
||||
|
|
|
@ -228,8 +228,13 @@ _cairo_path_fixed_line_to (cairo_path_fixed_t *path,
|
|||
point.x = x;
|
||||
point.y = y;
|
||||
|
||||
/* When there is not yet a current point, the line_to operation
|
||||
* becomes a move_to instead. Note: We have to do this by
|
||||
* explicitly calling into _cairo_path_fixed_line_to to ensure
|
||||
* that the last_move_point state is updated properly.
|
||||
*/
|
||||
if (! path->has_current_point)
|
||||
status = _cairo_path_fixed_add (path, CAIRO_PATH_OP_MOVE_TO, &point, 1);
|
||||
status = _cairo_path_fixed_move_to (path, point.x, point.y);
|
||||
else
|
||||
status = _cairo_path_fixed_add (path, CAIRO_PATH_OP_LINE_TO, &point, 1);
|
||||
|
||||
|
@ -328,9 +333,11 @@ _cairo_path_fixed_close_path (cairo_path_fixed_t *path)
|
|||
if (status)
|
||||
return status;
|
||||
|
||||
path->current_point.x = path->last_move_point.x;
|
||||
path->current_point.y = path->last_move_point.y;
|
||||
path->has_current_point = TRUE;
|
||||
status = _cairo_path_fixed_move_to (path,
|
||||
path->last_move_point.x,
|
||||
path->last_move_point.y);
|
||||
if (status)
|
||||
return status;
|
||||
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
|
|
|
@ -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 © 2004 David Reveman
|
||||
|
@ -31,7 +32,7 @@
|
|||
|
||||
const cairo_solid_pattern_t cairo_pattern_nil = {
|
||||
{ CAIRO_PATTERN_TYPE_SOLID, /* type */
|
||||
(unsigned int)-1, /* ref_count */
|
||||
CAIRO_REF_COUNT_INVALID, /* ref_count */
|
||||
CAIRO_STATUS_NO_MEMORY, /* status */
|
||||
{ 1., 0., 0., 1., 0., 0., }, /* matrix */
|
||||
CAIRO_FILTER_DEFAULT, /* filter */
|
||||
|
@ -40,7 +41,7 @@ const cairo_solid_pattern_t cairo_pattern_nil = {
|
|||
|
||||
static const cairo_solid_pattern_t cairo_pattern_nil_null_pointer = {
|
||||
{ CAIRO_PATTERN_TYPE_SOLID, /* type */
|
||||
(unsigned int)-1, /* ref_count */
|
||||
CAIRO_REF_COUNT_INVALID, /* ref_count */
|
||||
CAIRO_STATUS_NULL_POINTER,/* status */
|
||||
{ 1., 0., 0., 1., 0., 0., }, /* matrix */
|
||||
CAIRO_FILTER_DEFAULT, /* filter */
|
||||
|
@ -49,7 +50,7 @@ static const cairo_solid_pattern_t cairo_pattern_nil_null_pointer = {
|
|||
|
||||
static const cairo_solid_pattern_t cairo_pattern_nil_file_not_found = {
|
||||
{ CAIRO_PATTERN_TYPE_SOLID, /* type */
|
||||
(unsigned int)-1, /* ref_count */
|
||||
CAIRO_REF_COUNT_INVALID, /* ref_count */
|
||||
CAIRO_STATUS_FILE_NOT_FOUND, /* status */
|
||||
{ 1., 0., 0., 1., 0., 0., }, /* matrix */
|
||||
CAIRO_FILTER_DEFAULT, /* filter */
|
||||
|
@ -58,7 +59,7 @@ static const cairo_solid_pattern_t cairo_pattern_nil_file_not_found = {
|
|||
|
||||
static const cairo_solid_pattern_t cairo_pattern_nil_read_error = {
|
||||
{ CAIRO_PATTERN_TYPE_SOLID, /* type */
|
||||
(unsigned int)-1, /* ref_count */
|
||||
CAIRO_REF_COUNT_INVALID, /* ref_count */
|
||||
CAIRO_STATUS_READ_ERROR, /* status */
|
||||
{ 1., 0., 0., 1., 0., 0., }, /* matrix */
|
||||
CAIRO_FILTER_DEFAULT, /* filter */
|
||||
|
@ -68,17 +69,17 @@ static const cairo_solid_pattern_t cairo_pattern_nil_read_error = {
|
|||
static const cairo_pattern_t *
|
||||
_cairo_pattern_nil_for_status (cairo_status_t status)
|
||||
{
|
||||
switch (status) {
|
||||
case CAIRO_STATUS_NULL_POINTER:
|
||||
/* A switch statement would be more natural here, but we're
|
||||
* avoiding that to prevent a "false positive" warning from
|
||||
* -Wswitch-enum, (and I don't want to maintain a list of all
|
||||
* status values here). */
|
||||
if (status == CAIRO_STATUS_NULL_POINTER)
|
||||
return &cairo_pattern_nil_null_pointer.base;
|
||||
case CAIRO_STATUS_FILE_NOT_FOUND:
|
||||
if (status == CAIRO_STATUS_FILE_NOT_FOUND)
|
||||
return &cairo_pattern_nil_file_not_found.base;
|
||||
case CAIRO_STATUS_READ_ERROR:
|
||||
if (status == CAIRO_STATUS_READ_ERROR)
|
||||
return &cairo_pattern_nil_read_error.base;
|
||||
default:
|
||||
case CAIRO_STATUS_NO_MEMORY:
|
||||
return &cairo_pattern_nil.base;
|
||||
}
|
||||
return &cairo_pattern_nil.base;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -331,6 +332,7 @@ cairo_pattern_create_rgb (double red, double green, double blue)
|
|||
|
||||
return pattern;
|
||||
}
|
||||
slim_hidden_def (cairo_pattern_create_rgb);
|
||||
|
||||
/**
|
||||
* cairo_pattern_create_rgba:
|
||||
|
@ -373,6 +375,7 @@ cairo_pattern_create_rgba (double red, double green, double blue,
|
|||
|
||||
return pattern;
|
||||
}
|
||||
slim_hidden_def (cairo_pattern_create_rgba);
|
||||
|
||||
/**
|
||||
* cairo_pattern_create_for_surface:
|
||||
|
@ -410,6 +413,7 @@ cairo_pattern_create_for_surface (cairo_surface_t *surface)
|
|||
|
||||
return &pattern->base;
|
||||
}
|
||||
slim_hidden_def (cairo_pattern_create_for_surface);
|
||||
|
||||
/**
|
||||
* cairo_pattern_create_linear:
|
||||
|
@ -457,10 +461,10 @@ cairo_pattern_create_linear (double x0, double y0, double x1, double y1)
|
|||
* cairo_pattern_create_radial:
|
||||
* @cx0: x coordinate for the center of the start circle
|
||||
* @cy0: y coordinate for the center of the start circle
|
||||
* @radius0: radius of the start cirle
|
||||
* @radius0: radius of the start circle
|
||||
* @cx1: x coordinate for the center of the end circle
|
||||
* @cy1: y coordinate for the center of the end circle
|
||||
* @radius1: radius of the end cirle
|
||||
* @radius1: radius of the end circle
|
||||
*
|
||||
* Creates a new radial gradient cairo_pattern_t between the two
|
||||
* circles defined by (x0, y0, c0) and (x1, y1, c0). Before using the
|
||||
|
@ -514,7 +518,7 @@ cairo_pattern_reference (cairo_pattern_t *pattern)
|
|||
if (pattern == NULL)
|
||||
return NULL;
|
||||
|
||||
if (pattern->ref_count == (unsigned int)-1)
|
||||
if (pattern->ref_count == CAIRO_REF_COUNT_INVALID)
|
||||
return pattern;
|
||||
|
||||
assert (pattern->ref_count > 0);
|
||||
|
@ -523,12 +527,16 @@ cairo_pattern_reference (cairo_pattern_t *pattern)
|
|||
|
||||
return pattern;
|
||||
}
|
||||
slim_hidden_def (cairo_pattern_reference);
|
||||
|
||||
/**
|
||||
* cairo_pattern_get_type:
|
||||
* @pattern: a #cairo_pattern_t
|
||||
*
|
||||
* Return value: The type of @pattern. See #cairo_pattern_type_t.
|
||||
* This function returns the type a pattern.
|
||||
* See #cairo_pattern_type_t for available types.
|
||||
*
|
||||
* Return value: The type of @pattern.
|
||||
*
|
||||
* Since: 1.2
|
||||
**/
|
||||
|
@ -537,6 +545,7 @@ cairo_pattern_get_type (cairo_pattern_t *pattern)
|
|||
{
|
||||
return pattern->type;
|
||||
}
|
||||
slim_hidden_def (cairo_pattern_get_type);
|
||||
|
||||
/**
|
||||
* cairo_pattern_status:
|
||||
|
@ -568,7 +577,7 @@ cairo_pattern_destroy (cairo_pattern_t *pattern)
|
|||
if (pattern == NULL)
|
||||
return;
|
||||
|
||||
if (pattern->ref_count == (unsigned int)-1)
|
||||
if (pattern->ref_count == CAIRO_REF_COUNT_INVALID)
|
||||
return;
|
||||
|
||||
assert (pattern->ref_count > 0);
|
||||
|
@ -580,6 +589,7 @@ cairo_pattern_destroy (cairo_pattern_t *pattern)
|
|||
_cairo_pattern_fini (pattern);
|
||||
free (pattern);
|
||||
}
|
||||
slim_hidden_def (cairo_pattern_destroy);
|
||||
|
||||
static void
|
||||
_cairo_pattern_add_color_stop (cairo_gradient_pattern_t *pattern,
|
||||
|
@ -591,7 +601,7 @@ _cairo_pattern_add_color_stop (cairo_gradient_pattern_t *pattern,
|
|||
{
|
||||
pixman_gradient_stop_t *new_stops;
|
||||
cairo_fixed_t x;
|
||||
int i;
|
||||
unsigned int i;
|
||||
|
||||
new_stops = realloc (pattern->stops, (pattern->n_stops + 1) *
|
||||
sizeof (pixman_gradient_stop_t));
|
||||
|
@ -761,6 +771,7 @@ cairo_pattern_set_matrix (cairo_pattern_t *pattern,
|
|||
|
||||
pattern->matrix = *matrix;
|
||||
}
|
||||
slim_hidden_def (cairo_pattern_set_matrix);
|
||||
|
||||
/**
|
||||
* cairo_pattern_get_matrix:
|
||||
|
@ -824,6 +835,7 @@ cairo_pattern_get_extend (cairo_pattern_t *pattern)
|
|||
{
|
||||
return pattern->extend;
|
||||
}
|
||||
slim_hidden_def (cairo_pattern_get_extend);
|
||||
|
||||
void
|
||||
_cairo_pattern_transform (cairo_pattern_t *pattern,
|
||||
|
@ -1079,7 +1091,7 @@ _cairo_pattern_is_opaque_solid (const cairo_pattern_t *pattern)
|
|||
static cairo_bool_t
|
||||
_gradient_is_opaque (const cairo_gradient_pattern_t *gradient)
|
||||
{
|
||||
int i;
|
||||
unsigned int i;
|
||||
|
||||
for (i = 0; i < gradient->n_stops; i++)
|
||||
if (! CAIRO_ALPHA_IS_OPAQUE (gradient->stops[i].color.alpha))
|
||||
|
@ -1466,67 +1478,234 @@ _cairo_pattern_get_extents (cairo_pattern_t *pattern,
|
|||
}
|
||||
|
||||
/**
|
||||
* cairo_pattern_get_solid_color
|
||||
* cairo_pattern_get_rgba
|
||||
* @pattern: a #cairo_pattern_t
|
||||
* @r, @g, @b, @a: a double to return a color value in. must not be NULL.
|
||||
* @red: return value for red component of color, or %NULL
|
||||
* @green: return value for green component of color, or %NULL
|
||||
* @blue: return value for blue component of color, or %NULL
|
||||
* @alpha: return value for alpha component of color, or %NULL
|
||||
*
|
||||
* Gets the solid color for a solid color pattern.
|
||||
*
|
||||
* Return value: CAIRO_STATUS_SUCCESS, or
|
||||
* CAIRO_STATUS_PATTERN_TYPE_MISMATCH if the pattern is not a solid
|
||||
* Return value: %CAIRO_STATUS_SUCCESS, or
|
||||
* %CAIRO_STATUS_PATTERN_TYPE_MISMATCH if the pattern is not a solid
|
||||
* color pattern.
|
||||
*
|
||||
* Since: 1.4
|
||||
**/
|
||||
cairo_status_t
|
||||
cairo_pattern_get_solid_color (cairo_pattern_t *pattern,
|
||||
double *r, double *g, double *b, double *a)
|
||||
cairo_pattern_get_rgba (cairo_pattern_t *pattern,
|
||||
double *red, double *green,
|
||||
double *blue, double *alpha)
|
||||
{
|
||||
cairo_solid_pattern_t *solid = (cairo_solid_pattern_t*) pattern;
|
||||
|
||||
assert(r && g && b && a);
|
||||
double r0, g0, b0, a0;
|
||||
|
||||
if (pattern->type != CAIRO_PATTERN_TYPE_SOLID)
|
||||
return CAIRO_STATUS_PATTERN_TYPE_MISMATCH;
|
||||
return CAIRO_STATUS_PATTERN_TYPE_MISMATCH;
|
||||
|
||||
_cairo_color_get_rgba (&solid->color, r, g, b, a);
|
||||
_cairo_color_get_rgba (&solid->color, &r0, &g0, &b0, &a0);
|
||||
|
||||
if (red)
|
||||
*red = r0;
|
||||
if (green)
|
||||
*green = g0;
|
||||
if (blue)
|
||||
*blue = b0;
|
||||
if (alpha)
|
||||
*alpha = a0;
|
||||
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* cairo_pattern_get_color_stop
|
||||
* cairo_pattern_get_surface
|
||||
* @pattern: a #cairo_pattern_t
|
||||
* @stop_index: a number from 0 to 1 minus the number of color stops
|
||||
* @offset: a double representing the color stop offset
|
||||
* @r, @g, @b, @a: a double to return a color value in. must not be NULL.
|
||||
* @surface: return value for surface of pattern, or %NULL
|
||||
*
|
||||
* Gets the surface of a surface pattern. The reference returned in
|
||||
* @surface is owned by the pattern; the caller should call
|
||||
* cairo_surface_reference() if the surface is to be retained.
|
||||
*
|
||||
* Gets the color stop from a gradient pattern. The caller should
|
||||
* keep increasing stop_index until this function returns CAIRO_STATUS_INVALID_INDEX
|
||||
* Return value: %CAIRO_STATUS_SUCCESS, or
|
||||
* %CAIRO_STATUS_PATTERN_TYPE_MISMATCH if the pattern is not a surface
|
||||
* pattern.
|
||||
*
|
||||
* Return value: CAIRO_STATUS_SUCCESS, or CAIRO_STATUS_INVALID_INDEX if there
|
||||
* is no stop at the given index. If the pattern is not a gradient pattern,
|
||||
* CAIRO_STATUS_PATTERN_TYPE_MISMATCH is returned.
|
||||
* Since: 1.4
|
||||
**/
|
||||
cairo_status_t
|
||||
cairo_pattern_get_color_stop (cairo_pattern_t *pattern,
|
||||
int stop_index, double *offset,
|
||||
double *r, double *g, double *b, double *a)
|
||||
cairo_pattern_get_surface (cairo_pattern_t *pattern,
|
||||
cairo_surface_t **surface)
|
||||
{
|
||||
cairo_gradient_pattern_t *gradient = (cairo_gradient_pattern_t*) pattern;
|
||||
cairo_surface_pattern_t *spat = (cairo_surface_pattern_t*) pattern;
|
||||
|
||||
assert(offset && r && g && b && a);
|
||||
if (pattern->type != CAIRO_PATTERN_TYPE_SURFACE)
|
||||
return CAIRO_STATUS_PATTERN_TYPE_MISMATCH;
|
||||
|
||||
if (pattern->type != CAIRO_PATTERN_TYPE_LINEAR ||
|
||||
pattern->type != CAIRO_PATTERN_TYPE_RADIAL)
|
||||
return CAIRO_STATUS_PATTERN_TYPE_MISMATCH;
|
||||
|
||||
if (stop_index < 0 || stop_index >= gradient->n_stops)
|
||||
return CAIRO_STATUS_INVALID_INDEX;
|
||||
|
||||
*offset = _cairo_fixed_to_double(gradient->stops[stop_index].x);
|
||||
*r = gradient->stops[stop_index].color.red / (double) 0xffff;
|
||||
*g = gradient->stops[stop_index].color.green / (double) 0xffff;
|
||||
*b = gradient->stops[stop_index].color.blue / (double) 0xffff;
|
||||
*a = gradient->stops[stop_index].color.alpha / (double) 0xffff;
|
||||
if (surface)
|
||||
*surface = spat->surface;
|
||||
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* cairo_pattern_get_color_stop_rgba
|
||||
* @pattern: a #cairo_pattern_t
|
||||
* @index: index of the stop to return data for
|
||||
* @red: return value for red component of color, or %NULL
|
||||
* @green: return value for green component of color, or %NULL
|
||||
* @blue: return value for blue component of color, or %NULL
|
||||
* @alpha: return value for alpha component of color, or %NULL
|
||||
*
|
||||
* Gets the color and offset information at the given @index for a
|
||||
* gradient pattern. Values of @index are 0 to 1 less than the number
|
||||
* returned by cairo_pattern_get_color_stop_count().
|
||||
*
|
||||
* Return value: %CAIRO_STATUS_SUCCESS, or %CAIRO_STATUS_INVALID_INDEX
|
||||
* if @index is not valid for the given pattern. If the pattern is
|
||||
* not a gradient pattern, %CAIRO_STATUS_PATTERN_TYPE_MISMATCH is
|
||||
* returned.
|
||||
*
|
||||
* Since: 1.4
|
||||
**/
|
||||
cairo_status_t
|
||||
cairo_pattern_get_color_stop_rgba (cairo_pattern_t *pattern,
|
||||
int index, double *offset,
|
||||
double *red, double *green,
|
||||
double *blue, double *alpha)
|
||||
{
|
||||
cairo_gradient_pattern_t *gradient = (cairo_gradient_pattern_t*) pattern;
|
||||
|
||||
if (pattern->type != CAIRO_PATTERN_TYPE_LINEAR &&
|
||||
pattern->type != CAIRO_PATTERN_TYPE_RADIAL)
|
||||
return CAIRO_STATUS_PATTERN_TYPE_MISMATCH;
|
||||
|
||||
if (index < 0 || index >= gradient->n_stops)
|
||||
return CAIRO_STATUS_INVALID_INDEX;
|
||||
|
||||
if (offset)
|
||||
*offset = _cairo_fixed_to_double(gradient->stops[index].x);
|
||||
if (red)
|
||||
*red = gradient->stops[index].color.red / (double) 0xffff;
|
||||
if (green)
|
||||
*green = gradient->stops[index].color.green / (double) 0xffff;
|
||||
if (blue)
|
||||
*blue = gradient->stops[index].color.blue / (double) 0xffff;
|
||||
if (alpha)
|
||||
*alpha = gradient->stops[index].color.alpha / (double) 0xffff;
|
||||
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* cairo_pattern_get_color_stop_count
|
||||
* @pattern: a #cairo_pattern_t
|
||||
* @count: return value for the number of color stops, or %NULL
|
||||
*
|
||||
* Gets the number of color stops specified in the given gradient
|
||||
* pattern.
|
||||
*
|
||||
* Return value: %CAIRO_STATUS_SUCCESS, or
|
||||
* %CAIRO_STATUS_PATTERN_TYPE_MISMATCH if @pattern is not a gradient
|
||||
* pattern.
|
||||
*
|
||||
* Since: 1.4
|
||||
*/
|
||||
cairo_status_t
|
||||
cairo_pattern_get_color_stop_count (cairo_pattern_t *pattern,
|
||||
int *count)
|
||||
{
|
||||
cairo_gradient_pattern_t *gradient = (cairo_gradient_pattern_t*) pattern;
|
||||
|
||||
if (pattern->type != CAIRO_PATTERN_TYPE_LINEAR &&
|
||||
pattern->type != CAIRO_PATTERN_TYPE_RADIAL)
|
||||
return CAIRO_STATUS_PATTERN_TYPE_MISMATCH;
|
||||
|
||||
if (count)
|
||||
*count = gradient->n_stops;
|
||||
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* cairo_pattern_get_linear_points
|
||||
* @pattern: a #cairo_pattern_t
|
||||
* @x0: return value for the x coordinate of the first point, or %NULL
|
||||
* @y0: return value for the y coordinate of the first point, or %NULL
|
||||
* @x1: return value for the x coordinate of the second point, or %NULL
|
||||
* @y1: return value for the y coordinate of the second point, or %NULL
|
||||
*
|
||||
* Gets the gradient endpoints for a linear gradient.
|
||||
*
|
||||
* Return value: %CAIRO_STATUS_SUCCESS, or
|
||||
* %CAIRO_STATUS_PATTERN_TYPE_MISMATCH if @pattern is not a linear
|
||||
* gradient pattern.
|
||||
*
|
||||
* Since: 1.4
|
||||
**/
|
||||
cairo_status_t
|
||||
cairo_pattern_get_linear_points (cairo_pattern_t *pattern,
|
||||
double *x0, double *y0,
|
||||
double *x1, double *y1)
|
||||
{
|
||||
cairo_linear_pattern_t *linear = (cairo_linear_pattern_t*) pattern;
|
||||
|
||||
if (pattern->type != CAIRO_PATTERN_TYPE_LINEAR)
|
||||
return CAIRO_STATUS_PATTERN_TYPE_MISMATCH;
|
||||
|
||||
if (x0)
|
||||
*x0 = _cairo_fixed_to_double (linear->gradient.p1.x);
|
||||
if (y0)
|
||||
*y0 = _cairo_fixed_to_double (linear->gradient.p1.y);
|
||||
if (x1)
|
||||
*x1 = _cairo_fixed_to_double (linear->gradient.p2.x);
|
||||
if (y1)
|
||||
*y1 = _cairo_fixed_to_double (linear->gradient.p2.y);
|
||||
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* cairo_pattern_get_radial_circles
|
||||
* @pattern: a #cairo_pattern_t
|
||||
* @x0: return value for the x coordinate of the center of the first (inner) circle, or %NULL
|
||||
* @y0: return value for the y coordinate of the center of the first (inner) circle, or %NULL
|
||||
* @r0: return value for the radius of the first (inner) circle, or %NULL
|
||||
* @x1: return value for the x coordinate of the center of the second (outer) circle, or %NULL
|
||||
* @y1: return value for the y coordinate of the center of the second (outer) circle, or %NULL
|
||||
* @r1: return value for the radius of the second (outer) circle, or %NULL
|
||||
*
|
||||
* Gets the gradient endpoint circles for a radial gradient, each
|
||||
* specified as a center coordinate and a radius.
|
||||
*
|
||||
* Return value: %CAIRO_STATUS_SUCCESS, or
|
||||
* %CAIRO_STATUS_PATTERN_TYPE_MISMATCH if @pattern is not a radial
|
||||
* gradient pattern.
|
||||
*
|
||||
* Since: 1.4
|
||||
**/
|
||||
cairo_status_t
|
||||
cairo_pattern_get_radial_circles (cairo_pattern_t *pattern,
|
||||
double *x0, double *y0, double *r0,
|
||||
double *x1, double *y1, double *r1)
|
||||
{
|
||||
cairo_radial_pattern_t *radial = (cairo_radial_pattern_t*) pattern;
|
||||
|
||||
if (pattern->type != CAIRO_PATTERN_TYPE_RADIAL)
|
||||
return CAIRO_STATUS_PATTERN_TYPE_MISMATCH;
|
||||
|
||||
if (x0)
|
||||
*x0 = _cairo_fixed_to_double (radial->gradient.inner.x);
|
||||
if (y0)
|
||||
*y0 = _cairo_fixed_to_double (radial->gradient.inner.y);
|
||||
if (r0)
|
||||
*r0 = _cairo_fixed_to_double (radial->gradient.inner.radius);
|
||||
if (x1)
|
||||
*x1 = _cairo_fixed_to_double (radial->gradient.outer.x);
|
||||
if (y1)
|
||||
*y1 = _cairo_fixed_to_double (radial->gradient.outer.y);
|
||||
if (r1)
|
||||
*r1 = _cairo_fixed_to_double (radial->gradient.outer.radius);
|
||||
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
|
|
|
@ -40,7 +40,6 @@
|
|||
#include "cairo-pdf.h"
|
||||
#include "cairo-pdf-test.h"
|
||||
#include "cairo-scaled-font-subsets-private.h"
|
||||
#include "cairo-ft-private.h"
|
||||
#include "cairo-paginated-surface-private.h"
|
||||
#include "cairo-path-fixed-private.h"
|
||||
#include "cairo-output-stream-private.h"
|
||||
|
@ -296,6 +295,8 @@ _cairo_pdf_surface_create_for_stream_internal (cairo_output_stream_t *output,
|
|||
/* Document header */
|
||||
_cairo_output_stream_printf (surface->output,
|
||||
"%%PDF-1.4\r\n");
|
||||
_cairo_output_stream_printf (surface->output,
|
||||
"%%%c%c%c%c\r\n", 181, 237, 174, 251);
|
||||
|
||||
return _cairo_paginated_surface_create (&surface->base,
|
||||
CAIRO_CONTENT_COLOR_ALPHA,
|
||||
|
@ -453,19 +454,6 @@ _cairo_pdf_surface_clear (cairo_pdf_surface_t *surface)
|
|||
_cairo_array_truncate (&surface->streams, 0);
|
||||
}
|
||||
|
||||
static cairo_surface_t *
|
||||
_cairo_pdf_surface_create_similar (void *abstract_src,
|
||||
cairo_content_t content,
|
||||
int width,
|
||||
int height)
|
||||
{
|
||||
cairo_format_t format = _cairo_format_from_content (content);
|
||||
|
||||
/* Just return an image for now, until PDF surface can be used
|
||||
* as source. */
|
||||
return cairo_image_surface_create (format, width, height);
|
||||
}
|
||||
|
||||
static cairo_pdf_resource_t
|
||||
_cairo_pdf_surface_open_stream (cairo_pdf_surface_t *surface,
|
||||
const char *fmt,
|
||||
|
@ -558,8 +546,7 @@ _cairo_pdf_surface_finish (void *abstract_surface)
|
|||
"%%%%EOF\r\n",
|
||||
offset);
|
||||
|
||||
status = _cairo_output_stream_get_status (surface->output);
|
||||
_cairo_output_stream_destroy (surface->output);
|
||||
status = _cairo_output_stream_destroy (surface->output);
|
||||
|
||||
_cairo_array_fini (&surface->objects);
|
||||
_cairo_array_fini (&surface->pages);
|
||||
|
@ -893,8 +880,12 @@ emit_surface_pattern (cairo_pdf_surface_t *surface,
|
|||
xstep = image->width;
|
||||
ystep = image->height;
|
||||
break;
|
||||
/* All the reset should have been analyzed away, so this case
|
||||
* should be unreachable. */
|
||||
case CAIRO_EXTEND_REFLECT:
|
||||
case CAIRO_EXTEND_PAD:
|
||||
default:
|
||||
ASSERT_NOT_REACHED; /* all others should be analyzed away */
|
||||
ASSERT_NOT_REACHED;
|
||||
xstep = 0;
|
||||
ystep = 0;
|
||||
}
|
||||
|
@ -1081,8 +1072,7 @@ emit_pattern_stops (cairo_pdf_surface_t *surface, cairo_gradient_pattern_t *patt
|
|||
{
|
||||
cairo_pdf_resource_t function;
|
||||
cairo_pdf_color_stop_t *allstops, *stops;
|
||||
unsigned int n_stops;
|
||||
unsigned int i;
|
||||
unsigned int i, n_stops;
|
||||
|
||||
function = _cairo_pdf_surface_new_object (surface);
|
||||
|
||||
|
@ -1472,6 +1462,7 @@ _cairo_pdf_surface_get_font_options (void *abstract_surface,
|
|||
|
||||
cairo_font_options_set_hint_style (options, CAIRO_HINT_STYLE_NONE);
|
||||
cairo_font_options_set_hint_metrics (options, CAIRO_HINT_METRICS_OFF);
|
||||
cairo_font_options_set_antialias (options, CAIRO_ANTIALIAS_GRAY);
|
||||
}
|
||||
|
||||
static cairo_pdf_resource_t
|
||||
|
@ -1587,31 +1578,22 @@ _cairo_pdf_surface_write_pages (cairo_pdf_surface_t *surface)
|
|||
}
|
||||
|
||||
static cairo_status_t
|
||||
_cairo_pdf_surface_emit_type1_font_subset (cairo_pdf_surface_t *surface,
|
||||
cairo_scaled_font_subset_t *font_subset)
|
||||
_cairo_pdf_surface_emit_type1_font (cairo_pdf_surface_t *surface,
|
||||
cairo_scaled_font_subset_t *font_subset,
|
||||
cairo_type1_subset_t *subset)
|
||||
{
|
||||
cairo_pdf_resource_t stream, descriptor, subset_resource;
|
||||
cairo_status_t status;
|
||||
cairo_pdf_font_t font;
|
||||
cairo_type1_subset_t subset;
|
||||
unsigned long length, compressed_length;
|
||||
char *compressed;
|
||||
int i;
|
||||
char name[64];
|
||||
unsigned int i;
|
||||
|
||||
snprintf (name, sizeof name, "CairoFont-%d-%d",
|
||||
font_subset->font_id, font_subset->subset_id);
|
||||
status = _cairo_type1_subset_init (&subset, name, font_subset);
|
||||
if (status)
|
||||
return status;
|
||||
|
||||
/* We ignore the zero-trailer and set Length3 to 0. */
|
||||
length = subset.header_length + subset.data_length;
|
||||
compressed = compress_dup (subset.data, length, &compressed_length);
|
||||
if (compressed == NULL) {
|
||||
_cairo_type1_subset_fini (&subset);
|
||||
length = subset->header_length + subset->data_length;
|
||||
compressed = compress_dup (subset->data, length, &compressed_length);
|
||||
if (compressed == NULL)
|
||||
return CAIRO_STATUS_NO_MEMORY;
|
||||
}
|
||||
|
||||
stream = _cairo_pdf_surface_new_object (surface);
|
||||
_cairo_output_stream_printf (surface->output,
|
||||
|
@ -1625,8 +1607,8 @@ _cairo_pdf_surface_emit_type1_font_subset (cairo_pdf_surface_t *surface,
|
|||
"stream\r\n",
|
||||
stream.id,
|
||||
compressed_length,
|
||||
subset.header_length,
|
||||
subset.data_length);
|
||||
subset->header_length,
|
||||
subset->data_length);
|
||||
_cairo_output_stream_write (surface->output, compressed, compressed_length);
|
||||
_cairo_output_stream_printf (surface->output,
|
||||
"\r\n"
|
||||
|
@ -1651,13 +1633,13 @@ _cairo_pdf_surface_emit_type1_font_subset (cairo_pdf_surface_t *surface,
|
|||
">>\r\n"
|
||||
"endobj\r\n",
|
||||
descriptor.id,
|
||||
subset.base_font,
|
||||
subset.x_min,
|
||||
subset.y_min,
|
||||
subset.x_max,
|
||||
subset.y_max,
|
||||
subset.ascent,
|
||||
subset.descent,
|
||||
subset->base_font,
|
||||
subset->x_min,
|
||||
subset->y_min,
|
||||
subset->x_max,
|
||||
subset->y_max,
|
||||
subset->ascent,
|
||||
subset->descent,
|
||||
stream.id);
|
||||
|
||||
subset_resource = _cairo_pdf_surface_new_object (surface);
|
||||
|
@ -1671,14 +1653,14 @@ _cairo_pdf_surface_emit_type1_font_subset (cairo_pdf_surface_t *surface,
|
|||
" /FontDescriptor %d 0 R\r\n"
|
||||
" /Widths [",
|
||||
subset_resource.id,
|
||||
subset.base_font,
|
||||
font_subset->num_glyphs,
|
||||
subset->base_font,
|
||||
font_subset->num_glyphs - 1,
|
||||
descriptor.id);
|
||||
|
||||
for (i = 0; i < font_subset->num_glyphs; i++)
|
||||
_cairo_output_stream_printf (surface->output,
|
||||
" %d",
|
||||
subset.widths[i]);
|
||||
subset->widths[i]);
|
||||
|
||||
_cairo_output_stream_printf (surface->output,
|
||||
" ]\r\n"
|
||||
|
@ -1690,11 +1672,51 @@ _cairo_pdf_surface_emit_type1_font_subset (cairo_pdf_surface_t *surface,
|
|||
font.subset_resource = subset_resource;
|
||||
_cairo_array_append (&surface->fonts, &font);
|
||||
|
||||
_cairo_type1_subset_fini (&subset);
|
||||
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
#if CAIRO_HAS_FT_FONT
|
||||
static cairo_status_t
|
||||
_cairo_pdf_surface_emit_type1_font_subset (cairo_pdf_surface_t *surface,
|
||||
cairo_scaled_font_subset_t *font_subset)
|
||||
{
|
||||
cairo_status_t status;
|
||||
cairo_type1_subset_t subset;
|
||||
char name[64];
|
||||
|
||||
snprintf (name, sizeof name, "CairoFont-%d-%d",
|
||||
font_subset->font_id, font_subset->subset_id);
|
||||
status = _cairo_type1_subset_init (&subset, name, font_subset, FALSE);
|
||||
if (status)
|
||||
return status;
|
||||
|
||||
status = _cairo_pdf_surface_emit_type1_font (surface, font_subset, &subset);
|
||||
|
||||
_cairo_type1_subset_fini (&subset);
|
||||
return status;
|
||||
}
|
||||
#endif
|
||||
|
||||
static cairo_status_t
|
||||
_cairo_pdf_surface_emit_type1_fallback_font (cairo_pdf_surface_t *surface,
|
||||
cairo_scaled_font_subset_t *font_subset)
|
||||
{
|
||||
cairo_status_t status;
|
||||
cairo_type1_subset_t subset;
|
||||
char name[64];
|
||||
|
||||
snprintf (name, sizeof name, "CairoFont-%d-%d",
|
||||
font_subset->font_id, font_subset->subset_id);
|
||||
status = _cairo_type1_fallback_init (&subset, name, font_subset);
|
||||
if (status)
|
||||
return status;
|
||||
|
||||
status = _cairo_pdf_surface_emit_type1_font (surface, font_subset, &subset);
|
||||
|
||||
_cairo_type1_fallback_fini (&subset);
|
||||
return status;
|
||||
}
|
||||
|
||||
static cairo_status_t
|
||||
_cairo_pdf_surface_emit_truetype_font_subset (cairo_pdf_surface_t *surface,
|
||||
cairo_scaled_font_subset_t *font_subset)
|
||||
|
@ -1705,7 +1727,7 @@ _cairo_pdf_surface_emit_truetype_font_subset (cairo_pdf_surface_t *surface,
|
|||
cairo_truetype_subset_t subset;
|
||||
unsigned long compressed_length;
|
||||
char *compressed;
|
||||
int i;
|
||||
unsigned int i;
|
||||
|
||||
status = _cairo_truetype_subset_init (&subset, font_subset);
|
||||
if (status)
|
||||
|
@ -1774,7 +1796,7 @@ _cairo_pdf_surface_emit_truetype_font_subset (cairo_pdf_surface_t *surface,
|
|||
" /Widths [",
|
||||
subset_resource.id,
|
||||
subset.base_font,
|
||||
font_subset->num_glyphs,
|
||||
font_subset->num_glyphs - 1,
|
||||
descriptor.id);
|
||||
|
||||
for (i = 0; i < font_subset->num_glyphs; i++)
|
||||
|
@ -1864,7 +1886,11 @@ _cairo_pdf_surface_emit_bitmap_glyph (cairo_pdf_surface_t *surface,
|
|||
return status;
|
||||
|
||||
image = scaled_glyph->surface;
|
||||
assert (image->format == CAIRO_FORMAT_A1);
|
||||
if (image->format != CAIRO_FORMAT_A1) {
|
||||
image = _cairo_image_surface_clone (image, CAIRO_FORMAT_A1);
|
||||
if (cairo_surface_status (&image->base))
|
||||
return cairo_surface_status (&image->base);
|
||||
}
|
||||
|
||||
*glyph_ret = _cairo_pdf_surface_open_stream (surface, NULL);
|
||||
|
||||
|
@ -1906,6 +1932,9 @@ _cairo_pdf_surface_emit_bitmap_glyph (cairo_pdf_surface_t *surface,
|
|||
|
||||
_cairo_pdf_surface_close_stream (surface);
|
||||
|
||||
if (image != scaled_glyph->surface)
|
||||
cairo_surface_destroy (&image->base);
|
||||
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
|
@ -1938,7 +1967,7 @@ _cairo_pdf_surface_emit_type3_font_subset (cairo_pdf_surface_t *surface,
|
|||
cairo_pdf_resource_t *glyphs, encoding, char_procs, subset_resource;
|
||||
cairo_pdf_font_t font;
|
||||
cairo_matrix_t matrix;
|
||||
int i;
|
||||
unsigned int i;
|
||||
|
||||
glyphs = malloc (font_subset->num_glyphs * sizeof (cairo_pdf_resource_t));
|
||||
if (glyphs == NULL) {
|
||||
|
@ -1978,6 +2007,8 @@ _cairo_pdf_surface_emit_type3_font_subset (cairo_pdf_surface_t *surface,
|
|||
">>\r\n"
|
||||
"endobj\r\n");
|
||||
|
||||
free (glyphs);
|
||||
|
||||
subset_resource = _cairo_pdf_surface_new_object (surface);
|
||||
matrix = font_subset->scaled_font->scale;
|
||||
cairo_matrix_invert (&matrix);
|
||||
|
@ -2026,14 +2057,20 @@ _cairo_pdf_surface_emit_font_subset (cairo_scaled_font_subset_t *font_subset,
|
|||
cairo_pdf_surface_t *surface = closure;
|
||||
cairo_status_t status;
|
||||
|
||||
#if CAIRO_HAS_FT_FONT
|
||||
status = _cairo_pdf_surface_emit_type1_font_subset (surface, font_subset);
|
||||
if (status != CAIRO_INT_STATUS_UNSUPPORTED)
|
||||
return;
|
||||
#endif
|
||||
|
||||
status = _cairo_pdf_surface_emit_truetype_font_subset (surface, font_subset);
|
||||
if (status != CAIRO_INT_STATUS_UNSUPPORTED)
|
||||
return;
|
||||
|
||||
status = _cairo_pdf_surface_emit_type1_fallback_font (surface, font_subset);
|
||||
if (status != CAIRO_INT_STATUS_UNSUPPORTED)
|
||||
return;
|
||||
|
||||
status = _cairo_pdf_surface_emit_type3_font_subset (surface, font_subset);
|
||||
if (status != CAIRO_INT_STATUS_UNSUPPORTED)
|
||||
return;
|
||||
|
@ -2451,12 +2488,14 @@ _cairo_pdf_surface_emit_stroke_style (cairo_pdf_surface_t *surface,
|
|||
_cairo_pdf_line_join (style->line_join));
|
||||
|
||||
if (style->num_dashes) {
|
||||
int d;
|
||||
unsigned int d;
|
||||
_cairo_output_stream_printf (surface->output, "[");
|
||||
for (d = 0; d < style->num_dashes; d++)
|
||||
_cairo_output_stream_printf (surface->output, " %f", style->dash[d]);
|
||||
_cairo_output_stream_printf (surface->output, "] %f d\r\n",
|
||||
style->dash_offset);
|
||||
} else {
|
||||
_cairo_output_stream_printf (surface->output, "[] 0.0 d\r\n");
|
||||
}
|
||||
|
||||
_cairo_output_stream_printf (surface->output,
|
||||
|
@ -2577,7 +2616,7 @@ _cairo_pdf_surface_show_glyphs (void *abstract_surface,
|
|||
cairo_scaled_font_t *scaled_font)
|
||||
{
|
||||
cairo_pdf_surface_t *surface = abstract_surface;
|
||||
int current_subset_id = -1;
|
||||
unsigned int current_subset_id = (unsigned int)-1;
|
||||
unsigned int font_id, subset_id, subset_glyph_index;
|
||||
cairo_status_t status;
|
||||
int i;
|
||||
|
@ -2636,7 +2675,7 @@ _cairo_pdf_surface_set_paginated_mode (void *abstract_surface,
|
|||
|
||||
static const cairo_surface_backend_t cairo_pdf_surface_backend = {
|
||||
CAIRO_SURFACE_TYPE_PDF,
|
||||
_cairo_pdf_surface_create_similar,
|
||||
NULL, /* create_similar */
|
||||
_cairo_pdf_surface_finish,
|
||||
NULL, /* acquire_source_image */
|
||||
NULL, /* release_source_image */
|
||||
|
|
|
@ -54,7 +54,7 @@ cairo_pdf_surface_create_for_stream (cairo_write_func_t write_func,
|
|||
double width_in_points,
|
||||
double height_in_points);
|
||||
|
||||
void
|
||||
cairo_public void
|
||||
cairo_pdf_surface_set_size (cairo_surface_t *surface,
|
||||
double width_in_points,
|
||||
double height_in_points);
|
||||
|
|
|
@ -47,7 +47,7 @@
|
|||
#define CVISIBILITY_HIDDEN
|
||||
#endif
|
||||
|
||||
// In libxul builds we don't ever want to export cairo symbols
|
||||
/* In libxul builds we don't ever want to export cairo symbols */
|
||||
#define cairo_public extern CVISIBILITY_HIDDEN
|
||||
#define CCALLBACK
|
||||
#define CCALLBACK_DECL
|
||||
|
|
|
@ -35,15 +35,15 @@
|
|||
* Kristian Høgsberg <krh@redhat.com>
|
||||
*/
|
||||
|
||||
#include <png.h>
|
||||
#include <errno.h>
|
||||
#include "cairoint.h"
|
||||
#include <png.h>
|
||||
|
||||
/* Unpremultiplies data and converts native endian ARGB => RGBA bytes */
|
||||
static void
|
||||
unpremultiply_data (png_structp png, png_row_infop row_info, png_bytep data)
|
||||
{
|
||||
int i;
|
||||
unsigned int i;
|
||||
|
||||
for (i = 0; i < row_info->rowbytes; i += 4) {
|
||||
uint8_t *b = &data[i];
|
||||
|
@ -67,7 +67,7 @@ unpremultiply_data (png_structp png, png_row_infop row_info, png_bytep data)
|
|||
static void
|
||||
convert_data_to_bytes (png_structp png, png_row_infop row_info, png_bytep data)
|
||||
{
|
||||
int i;
|
||||
unsigned int i;
|
||||
|
||||
for (i = 0; i < row_info->rowbytes; i += 4) {
|
||||
uint8_t *b = &data[i];
|
||||
|
@ -88,7 +88,7 @@ write_png (cairo_surface_t *surface,
|
|||
void *closure)
|
||||
{
|
||||
int i;
|
||||
cairo_status_t status = CAIRO_STATUS_SUCCESS;
|
||||
volatile cairo_status_t status = CAIRO_STATUS_SUCCESS;
|
||||
cairo_image_surface_t *image;
|
||||
void *image_extra;
|
||||
png_struct *png;
|
||||
|
@ -287,6 +287,7 @@ cairo_surface_write_to_png_stream (cairo_surface_t *surface,
|
|||
|
||||
return write_png (surface, stream_write_func, &png_closure);
|
||||
}
|
||||
slim_hidden_def (cairo_surface_write_to_png_stream);
|
||||
|
||||
static INLINE int
|
||||
multiply_alpha (int alpha, int color)
|
||||
|
@ -301,7 +302,7 @@ premultiply_data (png_structp png,
|
|||
png_row_infop row_info,
|
||||
png_bytep data)
|
||||
{
|
||||
int i;
|
||||
unsigned int i;
|
||||
|
||||
for (i = 0; i < row_info->rowbytes; i += 4) {
|
||||
uint8_t *base = &data[i];
|
||||
|
@ -332,7 +333,7 @@ read_png (png_rw_ptr read_func,
|
|||
{
|
||||
cairo_surface_t *surface = (cairo_surface_t*) &_cairo_surface_nil;
|
||||
png_byte *data = NULL;
|
||||
int i;
|
||||
unsigned int i;
|
||||
png_struct *png = NULL;
|
||||
png_info *info;
|
||||
png_uint_32 png_width, png_height, stride;
|
||||
|
|
|
@ -43,9 +43,9 @@
|
|||
#include "cairo-scaled-font-subsets-private.h"
|
||||
#include "cairo-paginated-surface-private.h"
|
||||
#include "cairo-meta-surface-private.h"
|
||||
#include "cairo-ft-private.h"
|
||||
#include "cairo-output-stream-private.h"
|
||||
|
||||
#include <ctype.h>
|
||||
#include <time.h>
|
||||
#include <zlib.h>
|
||||
|
||||
|
@ -313,6 +313,8 @@ _cairo_ps_surface_emit_path (cairo_ps_surface_t *surface,
|
|||
_cairo_ps_surface_path_close_path,
|
||||
&path_info);
|
||||
|
||||
if (status == CAIRO_STATUS_SUCCESS)
|
||||
status = _cairo_output_stream_get_status (word_wrap);
|
||||
_cairo_output_stream_destroy (word_wrap);
|
||||
|
||||
return status;
|
||||
|
@ -385,6 +387,7 @@ _cairo_ps_surface_emit_header (cairo_ps_surface_t *surface)
|
|||
}
|
||||
}
|
||||
|
||||
#if CAIRO_HAS_FT_FONT
|
||||
static cairo_status_t
|
||||
_cairo_ps_surface_emit_type1_font_subset (cairo_ps_surface_t *surface,
|
||||
cairo_scaled_font_subset_t *font_subset)
|
||||
|
@ -398,7 +401,7 @@ _cairo_ps_surface_emit_type1_font_subset (cairo_ps_surface_t *surface,
|
|||
|
||||
snprintf (name, sizeof name, "CairoFont-%d-%d",
|
||||
font_subset->font_id, font_subset->subset_id);
|
||||
status = _cairo_type1_subset_init (&subset, name, font_subset);
|
||||
status = _cairo_type1_subset_init (&subset, name, font_subset, TRUE);
|
||||
if (status)
|
||||
return status;
|
||||
|
||||
|
@ -414,6 +417,35 @@ _cairo_ps_surface_emit_type1_font_subset (cairo_ps_surface_t *surface,
|
|||
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
#endif
|
||||
|
||||
static cairo_status_t
|
||||
_cairo_ps_surface_emit_type1_font_fallback (cairo_ps_surface_t *surface,
|
||||
cairo_scaled_font_subset_t *font_subset)
|
||||
{
|
||||
cairo_type1_subset_t subset;
|
||||
cairo_status_t status;
|
||||
int length;
|
||||
char name[64];
|
||||
|
||||
snprintf (name, sizeof name, "CairoFont-%d-%d",
|
||||
font_subset->font_id, font_subset->subset_id);
|
||||
status = _cairo_type1_fallback_init (&subset, name, font_subset);
|
||||
if (status)
|
||||
return status;
|
||||
|
||||
/* FIXME: Figure out document structure convention for fonts */
|
||||
|
||||
_cairo_output_stream_printf (surface->final_stream,
|
||||
"%% _cairo_ps_surface_emit_type1_font_subset\n");
|
||||
|
||||
length = subset.header_length + subset.data_length + subset.trailer_length;
|
||||
_cairo_output_stream_write (surface->final_stream, subset.data, length);
|
||||
|
||||
_cairo_type1_fallback_fini (&subset);
|
||||
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
static cairo_status_t
|
||||
_cairo_ps_surface_emit_truetype_font_subset (cairo_ps_surface_t *surface,
|
||||
|
@ -423,7 +455,7 @@ _cairo_ps_surface_emit_truetype_font_subset (cairo_ps_surface_t *surface,
|
|||
{
|
||||
cairo_truetype_subset_t subset;
|
||||
cairo_status_t status;
|
||||
int i;
|
||||
unsigned int i, begin, end;
|
||||
|
||||
status = _cairo_truetype_subset_init (&subset, font_subset);
|
||||
if (status)
|
||||
|
@ -464,17 +496,27 @@ _cairo_ps_surface_emit_truetype_font_subset (cairo_ps_surface_t *surface,
|
|||
_cairo_output_stream_printf (surface->final_stream,
|
||||
"end readonly def\n");
|
||||
|
||||
/* FIXME: We need to break up fonts bigger than 64k so we don't
|
||||
* exceed string size limitation. At glyph boundaries. Stupid
|
||||
* postscript. */
|
||||
_cairo_output_stream_printf (surface->final_stream,
|
||||
"/sfnts [<");
|
||||
|
||||
_cairo_output_stream_write_hex_string (surface->final_stream,
|
||||
subset.data, subset.data_length);
|
||||
"/sfnts [\n");
|
||||
begin = 0;
|
||||
end = 0;
|
||||
for (i = 0; i < subset.num_string_offsets; i++) {
|
||||
end = subset.string_offsets[i];
|
||||
_cairo_output_stream_printf (surface->final_stream,"<");
|
||||
_cairo_output_stream_write_hex_string (surface->final_stream,
|
||||
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,
|
||||
subset.data + end, subset.data_length - end);
|
||||
_cairo_output_stream_printf (surface->final_stream,"00>\n");
|
||||
}
|
||||
|
||||
_cairo_output_stream_printf (surface->final_stream,
|
||||
">] def\n"
|
||||
"] def\n"
|
||||
"FontName currentdict end definefont pop\n");
|
||||
|
||||
_cairo_truetype_subset_fini (&subset);
|
||||
|
@ -535,7 +577,11 @@ _cairo_ps_surface_emit_bitmap_glyph_data (cairo_ps_surface_t *surface,
|
|||
&scaled_glyph);
|
||||
|
||||
image = scaled_glyph->surface;
|
||||
assert (image->format == CAIRO_FORMAT_A1);
|
||||
if (image->format != CAIRO_FORMAT_A1) {
|
||||
image = _cairo_image_surface_clone (image, CAIRO_FORMAT_A1);
|
||||
if (cairo_surface_status (&image->base))
|
||||
return cairo_surface_status (&image->base);
|
||||
}
|
||||
|
||||
_cairo_output_stream_printf (surface->final_stream,
|
||||
"0 0 %f %f %f %f setcachedevice\n",
|
||||
|
@ -554,12 +600,12 @@ _cairo_ps_surface_emit_bitmap_glyph_data (cairo_ps_surface_t *surface,
|
|||
" /BitsPerComponent 1\n",
|
||||
image->width,
|
||||
image->height,
|
||||
image->base.device_transform.xx,
|
||||
image->base.device_transform.yx,
|
||||
image->base.device_transform.xy,
|
||||
image->base.device_transform.yy,
|
||||
image->base.device_transform.x0,
|
||||
- image->base.device_transform.y0);
|
||||
image->base.device_transform_inverse.xx,
|
||||
image->base.device_transform_inverse.yx,
|
||||
image->base.device_transform_inverse.xy,
|
||||
image->base.device_transform_inverse.yy,
|
||||
image->base.device_transform_inverse.x0,
|
||||
image->base.device_transform_inverse.y0);
|
||||
|
||||
_cairo_output_stream_printf (surface->final_stream,
|
||||
" /DataSource {<");
|
||||
|
@ -579,6 +625,9 @@ _cairo_ps_surface_emit_bitmap_glyph_data (cairo_ps_surface_t *surface,
|
|||
_cairo_output_stream_printf (surface->final_stream,
|
||||
"imagemask\n");
|
||||
|
||||
if (image != scaled_glyph->surface)
|
||||
cairo_surface_destroy (&image->base);
|
||||
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
|
@ -615,7 +664,7 @@ _cairo_ps_surface_emit_type3_font_subset (cairo_ps_surface_t *surface,
|
|||
|
||||
{
|
||||
cairo_matrix_t matrix;
|
||||
int i;
|
||||
unsigned int i;
|
||||
|
||||
_cairo_output_stream_printf (surface->final_stream,
|
||||
"%% _cairo_ps_surface_emit_type3_font_subset\n");
|
||||
|
@ -663,14 +712,20 @@ _cairo_ps_surface_emit_font_subset (cairo_scaled_font_subset_t *font_subset,
|
|||
cairo_ps_surface_t *surface = closure;
|
||||
cairo_status_t status;
|
||||
|
||||
#if CAIRO_HAS_FT_FONT
|
||||
status = _cairo_ps_surface_emit_type1_font_subset (surface, font_subset);
|
||||
if (status != CAIRO_INT_STATUS_UNSUPPORTED)
|
||||
return;
|
||||
#endif
|
||||
|
||||
status = _cairo_ps_surface_emit_truetype_font_subset (surface, font_subset);
|
||||
if (status != CAIRO_INT_STATUS_UNSUPPORTED)
|
||||
return;
|
||||
|
||||
status = _cairo_ps_surface_emit_type1_font_fallback (surface, font_subset);
|
||||
if (status != CAIRO_INT_STATUS_UNSUPPORTED)
|
||||
return;
|
||||
|
||||
status = _cairo_ps_surface_emit_type3_font_subset (surface, font_subset);
|
||||
if (status != CAIRO_INT_STATUS_UNSUPPORTED)
|
||||
return;
|
||||
|
@ -1126,19 +1181,6 @@ cairo_ps_surface_dsc_begin_page_setup (cairo_surface_t *surface)
|
|||
}
|
||||
}
|
||||
|
||||
static cairo_surface_t *
|
||||
_cairo_ps_surface_create_similar (void *abstract_src,
|
||||
cairo_content_t content,
|
||||
int width,
|
||||
int height)
|
||||
{
|
||||
cairo_format_t format = _cairo_format_from_content (content);
|
||||
|
||||
/* Just return an image for now, until PS surface can be used
|
||||
* as source. */
|
||||
return cairo_image_surface_create (format, width, height);
|
||||
}
|
||||
|
||||
static cairo_status_t
|
||||
_cairo_ps_surface_finish (void *abstract_surface)
|
||||
{
|
||||
|
@ -1474,7 +1516,7 @@ static cairo_status_t
|
|||
emit_image (cairo_ps_surface_t *surface,
|
||||
cairo_image_surface_t *image,
|
||||
cairo_matrix_t *matrix,
|
||||
char *name)
|
||||
const char *name)
|
||||
{
|
||||
cairo_status_t status;
|
||||
unsigned char *rgb, *compressed;
|
||||
|
@ -1788,6 +1830,7 @@ _cairo_ps_surface_get_font_options (void *abstract_surface,
|
|||
|
||||
cairo_font_options_set_hint_style (options, CAIRO_HINT_STYLE_NONE);
|
||||
cairo_font_options_set_hint_metrics (options, CAIRO_HINT_METRICS_OFF);
|
||||
cairo_font_options_set_antialias (options, CAIRO_ANTIALIAS_GRAY);
|
||||
}
|
||||
|
||||
static cairo_int_status_t
|
||||
|
@ -2056,7 +2099,7 @@ _cairo_ps_surface_show_glyphs (void *abstract_surface,
|
|||
{
|
||||
cairo_ps_surface_t *surface = abstract_surface;
|
||||
cairo_output_stream_t *stream = surface->stream;
|
||||
int current_subset_id = -1;
|
||||
unsigned int current_subset_id = -1;
|
||||
unsigned int font_id, subset_id, subset_glyph_index;
|
||||
cairo_status_t status;
|
||||
int i;
|
||||
|
@ -2113,7 +2156,7 @@ _cairo_ps_surface_set_paginated_mode (void *abstract_surface,
|
|||
|
||||
static const cairo_surface_backend_t cairo_ps_surface_backend = {
|
||||
CAIRO_SURFACE_TYPE_PS,
|
||||
_cairo_ps_surface_create_similar,
|
||||
NULL, /* create_similar */
|
||||
_cairo_ps_surface_finish,
|
||||
NULL, /* acquire_source_image */
|
||||
NULL, /* release_source_image */
|
||||
|
|
|
@ -44,15 +44,11 @@ typedef struct cairo_quartz_surface {
|
|||
|
||||
CGContextRef context;
|
||||
|
||||
cairo_bool_t flipped;
|
||||
cairo_bool_t y_grows_down;
|
||||
|
||||
int width;
|
||||
int height;
|
||||
cairo_rectangle_int16_t extents;
|
||||
|
||||
cairo_image_surface_t *image;
|
||||
pixman_region16_t *clip_region;
|
||||
|
||||
CGImageRef cgImage;
|
||||
pixman_region16_t *clip_region;
|
||||
} cairo_quartz_surface_t;
|
||||
|
||||
cairo_bool_t
|
||||
|
|
|
@ -37,28 +37,14 @@
|
|||
#include "cairo-private.h"
|
||||
#include "cairo-quartz-private.h"
|
||||
|
||||
static void
|
||||
ImageDataReleaseFunc(void *info, const void *data, size_t size)
|
||||
{
|
||||
if (data != NULL) {
|
||||
free((void *) data);
|
||||
}
|
||||
}
|
||||
|
||||
static cairo_status_t
|
||||
_cairo_quartz_surface_finish(void *abstract_surface)
|
||||
{
|
||||
cairo_quartz_surface_t *surface = abstract_surface;
|
||||
|
||||
if (surface->image)
|
||||
cairo_surface_destroy(&surface->image->base);
|
||||
if (surface->clip_region)
|
||||
pixman_region_destroy (surface->clip_region);
|
||||
|
||||
if (surface->cgImage)
|
||||
CGImageRelease(surface->cgImage);
|
||||
|
||||
if (surface->clip_region)
|
||||
pixman_region_destroy (surface->clip_region);
|
||||
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
|
@ -67,117 +53,127 @@ _cairo_quartz_surface_acquire_source_image(void *abstract_surface,
|
|||
cairo_image_surface_t **image_out,
|
||||
void **image_extra)
|
||||
{
|
||||
cairo_quartz_surface_t *surface = abstract_surface;
|
||||
CGColorSpaceRef colorSpace;
|
||||
void *imageData;
|
||||
UInt32 imageDataSize, rowBytes;
|
||||
CGDataProviderRef dataProvider;
|
||||
cairo_quartz_surface_t *surface = abstract_surface;
|
||||
|
||||
/* We keep a cached (cairo_image_surface_t *) in the cairo_quartz_surface_t
|
||||
* struct. If the window is ever drawn to without going through Cairo, then
|
||||
* we would need to refetch the pixel data from the window into the cached
|
||||
* image surface.
|
||||
*/
|
||||
if (surface->image) {
|
||||
cairo_surface_reference(&surface->image->base);
|
||||
if (CGBitmapContextGetBitmapInfo (surface->context) != 0) {
|
||||
/* XXX: We can create an image out of the bitmap here */
|
||||
}
|
||||
|
||||
*image_out = surface->image;
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
colorSpace = CGColorSpaceCreateDeviceRGB();
|
||||
|
||||
|
||||
rowBytes = surface->width * 4;
|
||||
imageDataSize = rowBytes * surface->height;
|
||||
imageData = malloc(imageDataSize);
|
||||
|
||||
dataProvider =
|
||||
CGDataProviderCreateWithData(NULL, imageData, imageDataSize,
|
||||
ImageDataReleaseFunc);
|
||||
|
||||
surface->cgImage = CGImageCreate(surface->width,
|
||||
surface->height,
|
||||
8,
|
||||
32,
|
||||
rowBytes,
|
||||
colorSpace,
|
||||
kCGImageAlphaPremultipliedFirst,
|
||||
dataProvider,
|
||||
NULL,
|
||||
false, kCGRenderingIntentDefault);
|
||||
|
||||
CGColorSpaceRelease(colorSpace);
|
||||
CGDataProviderRelease(dataProvider);
|
||||
|
||||
surface->image = (cairo_image_surface_t *)
|
||||
cairo_image_surface_create_for_data(imageData,
|
||||
CAIRO_FORMAT_ARGB32,
|
||||
surface->width,
|
||||
surface->height, rowBytes);
|
||||
if (surface->image->base.status) {
|
||||
if (surface->cgImage)
|
||||
CGImageRelease(surface->cgImage);
|
||||
return CAIRO_STATUS_NO_MEMORY;
|
||||
}
|
||||
|
||||
*image_out = surface->image;
|
||||
*image_extra = NULL;
|
||||
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
return CAIRO_INT_STATUS_UNSUPPORTED;
|
||||
}
|
||||
|
||||
static cairo_status_t
|
||||
_cairo_quartz_surface_acquire_dest_image(void *abstract_surface,
|
||||
cairo_rectangle_int16_t * interest_rect,
|
||||
cairo_image_surface_t **
|
||||
image_out,
|
||||
cairo_rectangle_int16_t * image_rect,
|
||||
void **image_extra)
|
||||
_cairo_quartz_surface_acquire_dest_image(void *abstract_surface,
|
||||
cairo_rectangle_int16_t *interest_rect,
|
||||
cairo_image_surface_t **image_out,
|
||||
cairo_rectangle_int16_t *image_rect,
|
||||
void **image_extra)
|
||||
{
|
||||
cairo_quartz_surface_t *surface = abstract_surface;
|
||||
cairo_surface_t *image_surface;
|
||||
unsigned char *data;
|
||||
int x1, y1, x2, y2;
|
||||
|
||||
image_rect->x = 0;
|
||||
image_rect->y = 0;
|
||||
image_rect->width = surface->image->width;
|
||||
image_rect->height = surface->image->height;
|
||||
x1 = surface->extents.x;
|
||||
x2 = surface->extents.x + surface->extents.width;
|
||||
y1 = surface->extents.y;
|
||||
y2 = surface->extents.y + surface->extents.height;
|
||||
|
||||
*image_out = surface->image;
|
||||
if (image_extra)
|
||||
if (interest_rect->x > x1)
|
||||
x1 = interest_rect->x;
|
||||
if (interest_rect->y > y1)
|
||||
y1 = interest_rect->y;
|
||||
if (interest_rect->x + interest_rect->width < x2)
|
||||
x2 = interest_rect->x + interest_rect->width;
|
||||
if (interest_rect->y + interest_rect->height < y2)
|
||||
y2 = interest_rect->y + interest_rect->height;
|
||||
|
||||
if (x1 >= x2 || y1 >= y2) {
|
||||
*image_out = NULL;
|
||||
*image_extra = NULL;
|
||||
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
image_rect->x = x1;
|
||||
image_rect->y = y1;
|
||||
image_rect->width = x2 - x1;
|
||||
image_rect->height = y2 - y1;
|
||||
|
||||
data = calloc (image_rect->width * image_rect->height * 4, 1);
|
||||
image_surface = cairo_image_surface_create_for_data (data,
|
||||
CAIRO_FORMAT_ARGB32,
|
||||
image_rect->width,
|
||||
image_rect->height,
|
||||
image_rect->width * 4);
|
||||
|
||||
*image_out = (cairo_image_surface_t *)image_surface;
|
||||
*image_extra = data;
|
||||
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
|
||||
return CAIRO_INT_STATUS_UNSUPPORTED;
|
||||
}
|
||||
|
||||
static CGImageRef
|
||||
create_image_from_surface (cairo_image_surface_t *image_surface, void *data)
|
||||
{
|
||||
CGImageRef image;
|
||||
CGColorSpaceRef color_space;
|
||||
CGDataProviderRef data_provider;
|
||||
int width, height;
|
||||
|
||||
width = cairo_image_surface_get_width ((cairo_surface_t *)image_surface);
|
||||
height = cairo_image_surface_get_height ((cairo_surface_t *)image_surface);
|
||||
|
||||
color_space = CGColorSpaceCreateDeviceRGB();
|
||||
data_provider = CGDataProviderCreateWithData (NULL, data,
|
||||
width * height * 4, NULL);
|
||||
image = CGImageCreate (width, height,
|
||||
8, 32,
|
||||
width * 4,
|
||||
color_space,
|
||||
kCGImageAlphaPremultipliedFirst,
|
||||
data_provider,
|
||||
NULL,
|
||||
FALSE, kCGRenderingIntentDefault);
|
||||
|
||||
CGColorSpaceRelease (color_space);
|
||||
CGDataProviderRelease (data_provider);
|
||||
|
||||
return image;
|
||||
}
|
||||
|
||||
static void
|
||||
_cairo_quartz_surface_release_dest_image(void *abstract_surface,
|
||||
cairo_rectangle_int16_t *
|
||||
intersect_rect,
|
||||
cairo_image_surface_t * image,
|
||||
cairo_rectangle_int16_t * image_rect,
|
||||
void *image_extra)
|
||||
_cairo_quartz_surface_release_dest_image(void *abstract_surface,
|
||||
cairo_rectangle_int16_t *intersect_rect,
|
||||
cairo_image_surface_t *image,
|
||||
cairo_rectangle_int16_t *image_rect,
|
||||
void *image_extra)
|
||||
{
|
||||
cairo_quartz_surface_t *surface = abstract_surface;
|
||||
CGImageRef image_ref;
|
||||
CGRect rect;
|
||||
|
||||
if (surface->image == image) {
|
||||
CGRect rect;
|
||||
image_ref = create_image_from_surface (image, image_extra);
|
||||
|
||||
rect = CGRectMake(0, 0, surface->width, surface->height);
|
||||
rect = CGRectMake (image_rect->x, image_rect->y, image_rect->width, image_rect->height);
|
||||
|
||||
if (surface->flipped) {
|
||||
CGContextSaveGState (surface->context);
|
||||
CGContextTranslateCTM (surface->context, 0, surface->height);
|
||||
CGContextScaleCTM (surface->context, 1, -1);
|
||||
}
|
||||
|
||||
CGContextDrawImage(surface->context, rect, surface->cgImage);
|
||||
|
||||
if (surface->flipped)
|
||||
CGContextRestoreGState (surface->context);
|
||||
|
||||
memset(surface->image->data, 0, surface->width * surface->height * 4);
|
||||
if (surface->y_grows_down) {
|
||||
CGContextSaveGState (surface->context);
|
||||
CGContextTranslateCTM (surface->context, 0, image_rect->height + 2 * image_rect->y);
|
||||
CGContextScaleCTM (surface->context, 1, -1);
|
||||
}
|
||||
|
||||
CGContextDrawImage(surface->context, rect, image_ref);
|
||||
CFRelease (image_ref);
|
||||
|
||||
if (surface->y_grows_down) {
|
||||
CGContextRestoreGState (surface->context);
|
||||
}
|
||||
|
||||
cairo_surface_destroy ((cairo_surface_t *)image);
|
||||
free (image_extra);
|
||||
}
|
||||
|
||||
static cairo_int_status_t
|
||||
|
@ -185,33 +181,26 @@ _cairo_quartz_surface_set_clip_region(void *abstract_surface,
|
|||
pixman_region16_t * region)
|
||||
{
|
||||
cairo_quartz_surface_t *surface = abstract_surface;
|
||||
unsigned int serial;
|
||||
|
||||
serial = _cairo_surface_allocate_clip_serial (&surface->image->base);
|
||||
if (surface->clip_region)
|
||||
pixman_region_destroy (surface->clip_region);
|
||||
|
||||
if (surface->clip_region)
|
||||
pixman_region_destroy (surface->clip_region);
|
||||
|
||||
if (region) {
|
||||
surface->clip_region = pixman_region_create ();
|
||||
pixman_region_copy (surface->clip_region, region);
|
||||
} else
|
||||
surface->clip_region = NULL;
|
||||
|
||||
return _cairo_surface_set_clip_region(&surface->image->base,
|
||||
region, serial);
|
||||
if (region) {
|
||||
surface->clip_region = pixman_region_create ();
|
||||
pixman_region_copy (surface->clip_region, region);
|
||||
} else
|
||||
surface->clip_region = NULL;
|
||||
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
static cairo_int_status_t
|
||||
_cairo_quartz_surface_get_extents (void *abstract_surface,
|
||||
cairo_rectangle_int16_t * rectangle)
|
||||
_cairo_quartz_surface_get_extents (void *abstract_surface,
|
||||
cairo_rectangle_int16_t *rectangle)
|
||||
{
|
||||
cairo_quartz_surface_t *surface = abstract_surface;
|
||||
|
||||
rectangle->x = 0;
|
||||
rectangle->y = 0;
|
||||
rectangle->width = surface->width;
|
||||
rectangle->height = surface->height;
|
||||
*rectangle = surface->extents;
|
||||
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
|
@ -236,12 +225,13 @@ static const struct _cairo_surface_backend cairo_quartz_surface_backend = {
|
|||
NULL /* old_show_glyphs */
|
||||
};
|
||||
|
||||
|
||||
cairo_surface_t *cairo_quartz_surface_create(CGContextRef context,
|
||||
cairo_bool_t flipped,
|
||||
int width, int height)
|
||||
int width,
|
||||
int height,
|
||||
cairo_bool_t y_grows_down)
|
||||
{
|
||||
cairo_quartz_surface_t *surface;
|
||||
CGRect clip_box;
|
||||
|
||||
surface = malloc(sizeof(cairo_quartz_surface_t));
|
||||
if (surface == NULL) {
|
||||
|
@ -249,20 +239,19 @@ cairo_surface_t *cairo_quartz_surface_create(CGContextRef context,
|
|||
return (cairo_surface_t*) &_cairo_surface_nil;
|
||||
}
|
||||
|
||||
/* XXX: The content value here might be totally wrong. */
|
||||
_cairo_surface_init(&surface->base, &cairo_quartz_surface_backend,
|
||||
CAIRO_CONTENT_COLOR_ALPHA);
|
||||
CAIRO_CONTENT_COLOR_ALPHA);
|
||||
|
||||
surface->context = context;
|
||||
surface->width = width;
|
||||
surface->height = height;
|
||||
surface->image = NULL;
|
||||
surface->cgImage = NULL;
|
||||
surface->clip_region = NULL;
|
||||
surface->flipped = flipped;
|
||||
surface->clip_region = NULL;
|
||||
surface->y_grows_down = y_grows_down;
|
||||
|
||||
/* Set up the image surface which Cairo draws into and we blit to & from. */
|
||||
void *foo;
|
||||
_cairo_quartz_surface_acquire_source_image(surface, &surface->image, &foo);
|
||||
clip_box = CGContextGetClipBoundingBox (context);
|
||||
surface->extents.x = clip_box.origin.x;
|
||||
surface->extents.y = clip_box.origin.y;
|
||||
surface->extents.width = clip_box.size.width;
|
||||
surface->extents.height = clip_box.size.height;
|
||||
|
||||
return (cairo_surface_t *) surface;
|
||||
}
|
||||
|
|
|
@ -1,3 +1,8 @@
|
|||
#define _cairo_pdf_test_force_fallbacks _moz__cairo_pdf_test_force_fallbacks
|
||||
#define _cairo_ps_test_force_fallbacks _moz__cairo_ps_test_force_fallbacks
|
||||
#define _cairo_scaled_font_test_set_max_glyphs_cached_per_font _moz__cairo_scaled_font_test_set_max_glyphs_cached_per_font
|
||||
#define _cairo_svg_test_force_fallbacks _moz__cairo_svg_test_force_fallbacks
|
||||
#define _cairo_xlib_test_disable_render _moz__cairo_xlib_test_disable_render
|
||||
#define cairo_append_path _moz_cairo_append_path
|
||||
#define cairo_arc _moz_cairo_arc
|
||||
#define cairo_arc_negative _moz_cairo_arc_negative
|
||||
|
@ -6,8 +11,10 @@
|
|||
#define cairo_beos_surface_create _moz_cairo_beos_surface_create
|
||||
#define cairo_beos_surface_create_for_bitmap _moz_cairo_beos_surface_create_for_bitmap
|
||||
#define cairo_clip _moz_cairo_clip
|
||||
#define cairo_clip_extents _moz_cairo_clip_extents
|
||||
#define cairo_clip_preserve _moz_cairo_clip_preserve
|
||||
#define cairo_close_path _moz_cairo_close_path
|
||||
#define cairo_copy_clip_rectangles _moz_cairo_copy_clip_rectangles
|
||||
#define cairo_copy_page _moz_cairo_copy_page
|
||||
#define cairo_copy_path _moz_cairo_copy_path
|
||||
#define cairo_copy_path_flat _moz_cairo_copy_path_flat
|
||||
|
@ -22,7 +29,7 @@
|
|||
#define cairo_destroy _moz_cairo_destroy
|
||||
#define cairo_device_to_user _moz_cairo_device_to_user
|
||||
#define cairo_device_to_user_distance _moz_cairo_device_to_user_distance
|
||||
#define cairo_extract_clip_rectangles _moz_cairo_extract_clip_rectangles
|
||||
#define cairo_directfb_surface_create _moz_cairo_directfb_surface_create
|
||||
#define cairo_fill _moz_cairo_fill
|
||||
#define cairo_fill_extents _moz_cairo_fill_extents
|
||||
#define cairo_fill_preserve _moz_cairo_fill_preserve
|
||||
|
@ -55,6 +62,8 @@
|
|||
#define cairo_ft_scaled_font_unlock_face _moz_cairo_ft_scaled_font_unlock_face
|
||||
#define cairo_get_antialias _moz_cairo_get_antialias
|
||||
#define cairo_get_current_point _moz_cairo_get_current_point
|
||||
#define cairo_get_dash _moz_cairo_get_dash
|
||||
#define cairo_get_dash_count _moz_cairo_get_dash_count
|
||||
#define cairo_get_fill_rule _moz_cairo_get_fill_rule
|
||||
#define cairo_get_font_face _moz_cairo_get_font_face
|
||||
#define cairo_get_font_matrix _moz_cairo_get_font_matrix
|
||||
|
@ -72,7 +81,6 @@
|
|||
#define cairo_glitz_surface_create _moz_cairo_glitz_surface_create
|
||||
#define cairo_glyph_extents _moz_cairo_glyph_extents
|
||||
#define cairo_glyph_path _moz_cairo_glyph_path
|
||||
#define cairo_has_clip _moz_cairo_has_clip
|
||||
#define cairo_identity_matrix _moz_cairo_identity_matrix
|
||||
#define cairo_image_surface_create _moz_cairo_image_surface_create
|
||||
#define cairo_image_surface_create_for_data _moz_cairo_image_surface_create_for_data
|
||||
|
@ -103,6 +111,18 @@
|
|||
#define cairo_move_to _moz_cairo_move_to
|
||||
#define cairo_new_path _moz_cairo_new_path
|
||||
#define cairo_new_sub_path _moz_cairo_new_sub_path
|
||||
#define cairo_nquartz_surface_create _moz_cairo_nquartz_surface_create
|
||||
#define cairo_nquartz_surface_create_for_agl_context _moz_cairo_nquartz_surface_create_for_agl_context
|
||||
#define cairo_nquartz_surface_create_for_cg_context _moz_cairo_nquartz_surface_create_for_cg_context
|
||||
#define cairo_nquartz_surface_get_cg_context _moz_cairo_nquartz_surface_get_cg_context
|
||||
#define cairo_os2_fini _moz_cairo_os2_fini
|
||||
#define cairo_os2_init _moz_cairo_os2_init
|
||||
#define cairo_os2_surface_create _moz_cairo_os2_surface_create
|
||||
#define cairo_os2_surface_get_manual_window_refresh _moz_cairo_os2_surface_get_manual_window_refresh
|
||||
#define cairo_os2_surface_refresh_window _moz_cairo_os2_surface_refresh_window
|
||||
#define cairo_os2_surface_set_hwnd _moz_cairo_os2_surface_set_hwnd
|
||||
#define cairo_os2_surface_set_manual_window_refresh _moz_cairo_os2_surface_set_manual_window_refresh
|
||||
#define cairo_os2_surface_set_size _moz_cairo_os2_surface_set_size
|
||||
#define cairo_paint _moz_cairo_paint
|
||||
#define cairo_paint_with_alpha _moz_cairo_paint_with_alpha
|
||||
#define cairo_path_destroy _moz_cairo_path_destroy
|
||||
|
@ -114,9 +134,15 @@
|
|||
#define cairo_pattern_create_rgb _moz_cairo_pattern_create_rgb
|
||||
#define cairo_pattern_create_rgba _moz_cairo_pattern_create_rgba
|
||||
#define cairo_pattern_destroy _moz_cairo_pattern_destroy
|
||||
#define cairo_pattern_get_color_stop_count _moz_cairo_pattern_get_color_stop_count
|
||||
#define cairo_pattern_get_color_stop_rgba _moz_cairo_pattern_get_color_stop_rgba
|
||||
#define cairo_pattern_get_extend _moz_cairo_pattern_get_extend
|
||||
#define cairo_pattern_get_filter _moz_cairo_pattern_get_filter
|
||||
#define cairo_pattern_get_linear_points _moz_cairo_pattern_get_linear_points
|
||||
#define cairo_pattern_get_matrix _moz_cairo_pattern_get_matrix
|
||||
#define cairo_pattern_get_radial_circles _moz_cairo_pattern_get_radial_circles
|
||||
#define cairo_pattern_get_rgba _moz_cairo_pattern_get_rgba
|
||||
#define cairo_pattern_get_surface _moz_cairo_pattern_get_surface
|
||||
#define cairo_pattern_get_type _moz_cairo_pattern_get_type
|
||||
#define cairo_pattern_reference _moz_cairo_pattern_reference
|
||||
#define cairo_pattern_set_extend _moz_cairo_pattern_set_extend
|
||||
|
@ -125,6 +151,7 @@
|
|||
#define cairo_pattern_status _moz_cairo_pattern_status
|
||||
#define cairo_pdf_surface_create _moz_cairo_pdf_surface_create
|
||||
#define cairo_pdf_surface_create_for_stream _moz_cairo_pdf_surface_create_for_stream
|
||||
#define cairo_pdf_surface_set_size _moz_cairo_pdf_surface_set_size
|
||||
#define cairo_pop_group _moz_cairo_pop_group
|
||||
#define cairo_pop_group_to_source _moz_cairo_pop_group_to_source
|
||||
#define cairo_profile_surface_create _moz_cairo_profile_surface_create
|
||||
|
@ -139,6 +166,7 @@
|
|||
#define cairo_push_group_with_content _moz_cairo_push_group_with_content
|
||||
#define cairo_quartz_surface_create _moz_cairo_quartz_surface_create
|
||||
#define cairo_rectangle _moz_cairo_rectangle
|
||||
#define cairo_rectangle_list_destroy _moz_cairo_rectangle_list_destroy
|
||||
#define cairo_reference _moz_cairo_reference
|
||||
#define cairo_rel_curve_to _moz_cairo_rel_curve_to
|
||||
#define cairo_rel_line_to _moz_cairo_rel_line_to
|
||||
|
@ -198,6 +226,7 @@
|
|||
#define cairo_surface_get_font_options _moz_cairo_surface_get_font_options
|
||||
#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_is_nquartz _moz_cairo_surface_is_nquartz
|
||||
#define cairo_surface_is_profile _moz_cairo_surface_is_profile
|
||||
#define cairo_surface_mark_dirty _moz_cairo_surface_mark_dirty
|
||||
#define cairo_surface_mark_dirty_rectangle _moz_cairo_surface_mark_dirty_rectangle
|
||||
|
|
|
@ -50,7 +50,7 @@ typedef struct _cairo_scaled_font_subset {
|
|||
* Value of glyphs array is scaled_font_glyph_index.
|
||||
*/
|
||||
unsigned long *glyphs;
|
||||
int num_glyphs;
|
||||
unsigned int num_glyphs;
|
||||
} cairo_scaled_font_subset_t;
|
||||
|
||||
/**
|
||||
|
@ -187,6 +187,8 @@ typedef struct _cairo_truetype_subset {
|
|||
long ascent, descent;
|
||||
char *data;
|
||||
unsigned long data_length;
|
||||
unsigned long *string_offsets;
|
||||
unsigned long num_string_offsets;
|
||||
} cairo_truetype_subset_t;
|
||||
|
||||
/**
|
||||
|
@ -237,6 +239,7 @@ typedef struct _cairo_type1_subset {
|
|||
* _cairo_type1_subset_init:
|
||||
* @type1_subset: a #cairo_type1_subset_t to initialize
|
||||
* @font_subset: the #cairo_scaled_font_subset_t to initialize from
|
||||
* @hex_encode: if true the encrypted portion of the font is hex encoded
|
||||
*
|
||||
* If possible (depending on the format of the underlying
|
||||
* cairo_scaled_font_t and the font backend in use) generate a type1
|
||||
|
@ -251,7 +254,8 @@ typedef struct _cairo_type1_subset {
|
|||
cairo_private cairo_status_t
|
||||
_cairo_type1_subset_init (cairo_type1_subset_t *type_subset,
|
||||
const char *name,
|
||||
cairo_scaled_font_subset_t *font_subset);
|
||||
cairo_scaled_font_subset_t *font_subset,
|
||||
cairo_bool_t hex_encode);
|
||||
|
||||
/**
|
||||
* _cairo_type1_subset_fini:
|
||||
|
@ -264,4 +268,35 @@ _cairo_type1_subset_init (cairo_type1_subset_t *type_subset,
|
|||
cairo_private void
|
||||
_cairo_type1_subset_fini (cairo_type1_subset_t *subset);
|
||||
|
||||
/**
|
||||
* _cairo_type1_fallback_init:
|
||||
* @type1_subset: a #cairo_type1_subset_t to initialize
|
||||
* @font_subset: the #cairo_scaled_font_subset_t to initialize from
|
||||
*
|
||||
* If possible (depending on the format of the underlying
|
||||
* cairo_scaled_font_t and the font backend in use) generate a type1
|
||||
* file corresponding to @font_subset and initialize @type1_subset
|
||||
* with information about the subset and the type1 data.
|
||||
*
|
||||
* Return value: CAIRO_STATUS_SUCCESS if successful,
|
||||
* CAIRO_INT_STATUS_UNSUPPORTED if the font can't be subset as a type1
|
||||
* file, or an non-zero value indicating an error. Possible errors
|
||||
* include CAIRO_STATUS_NO_MEMORY.
|
||||
**/
|
||||
cairo_private cairo_status_t
|
||||
_cairo_type1_fallback_init (cairo_type1_subset_t *type_subset,
|
||||
const char *name,
|
||||
cairo_scaled_font_subset_t *font_subset);
|
||||
|
||||
/**
|
||||
* _cairo_type1_fallback_fini:
|
||||
* @type1_subset: a #cairo_type1_subset_t
|
||||
*
|
||||
* Free all resources associated with @type1_subset. After this call,
|
||||
* @type1_subset should not be used again without a subsequent call to
|
||||
* _cairo_truetype_type1_init() again first.
|
||||
**/
|
||||
cairo_private void
|
||||
_cairo_type1_fallback_fini (cairo_type1_subset_t *subset);
|
||||
|
||||
#endif /* CAIRO_SCALED_FONT_SUBSETS_PRIVATE_H */
|
||||
|
|
|
@ -73,9 +73,9 @@ typedef struct _cairo_sub_font_glyph {
|
|||
|
||||
typedef struct _cairo_sub_font_collection {
|
||||
unsigned long *glyphs; /* scaled_font_glyph_index */
|
||||
int glyphs_size;
|
||||
int max_glyph;
|
||||
int num_glyphs;
|
||||
unsigned int glyphs_size;
|
||||
unsigned int max_glyph;
|
||||
unsigned int num_glyphs;
|
||||
|
||||
unsigned int subset_id;
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $Id: cairo-scaled-font.c,v 1.10 2006/07/13 20:19:37 vladimir%pobox.com Exp $
|
||||
/* $Id: cairo-scaled-font.c,v 1.11 2006/09/26 22:21:55 vladimir%pobox.com Exp $
|
||||
*
|
||||
* Copyright © 2005 Keith Packard
|
||||
*
|
||||
|
@ -74,7 +74,7 @@ _cairo_scaled_glyph_destroy (void *abstract_glyph)
|
|||
static const cairo_scaled_font_t _cairo_scaled_font_nil = {
|
||||
{ 0 }, /* hash_entry */
|
||||
CAIRO_STATUS_NO_MEMORY, /* status */
|
||||
-1, /* ref_count */
|
||||
CAIRO_REF_COUNT_INVALID, /* ref_count */
|
||||
NULL, /* font_face */
|
||||
{ 1., 0., 0., 1., 0, 0}, /* font_matrix */
|
||||
{ 1., 0., 0., 1., 0, 0}, /* ctm */
|
||||
|
@ -123,7 +123,10 @@ _cairo_scaled_font_set_error (cairo_scaled_font_t *scaled_font,
|
|||
* cairo_scaled_font_get_type:
|
||||
* @scaled_font: a #cairo_scaled_font_t
|
||||
*
|
||||
* Return value: The type of @scaled_font. See #cairo_font_type_t.
|
||||
* This function returns the type of the backend used to create
|
||||
* a scaled font. See #cairo_font_type_t for available types.
|
||||
*
|
||||
* Return value: The type of @scaled_font.
|
||||
*
|
||||
* Since: 1.2
|
||||
**/
|
||||
|
@ -223,13 +226,15 @@ void
|
|||
_cairo_scaled_font_map_destroy (void)
|
||||
{
|
||||
int i;
|
||||
cairo_scaled_font_map_t *font_map = cairo_scaled_font_map;
|
||||
cairo_scaled_font_map_t *font_map;
|
||||
cairo_scaled_font_t *scaled_font;
|
||||
|
||||
if (font_map == NULL)
|
||||
return;
|
||||
CAIRO_MUTEX_LOCK (cairo_scaled_font_map_mutex);
|
||||
|
||||
CAIRO_MUTEX_UNLOCK (cairo_scaled_font_map_mutex);
|
||||
font_map = cairo_scaled_font_map;
|
||||
if (font_map == NULL) {
|
||||
goto CLEANUP_MUTEX_LOCK;
|
||||
}
|
||||
|
||||
for (i = 0; i < font_map->num_holdovers; i++) {
|
||||
scaled_font = font_map->holdovers[i];
|
||||
|
@ -247,6 +252,9 @@ _cairo_scaled_font_map_destroy (void)
|
|||
|
||||
free (cairo_scaled_font_map);
|
||||
cairo_scaled_font_map = NULL;
|
||||
|
||||
CLEANUP_MUTEX_LOCK:
|
||||
CAIRO_MUTEX_UNLOCK (cairo_scaled_font_map_mutex);
|
||||
}
|
||||
|
||||
/* Fowler / Noll / Vo (FNV) Hash (http://www.isthe.com/chongo/tech/comp/fnv/)
|
||||
|
@ -490,6 +498,7 @@ UNWIND_FONT_MAP_LOCK:
|
|||
UNWIND:
|
||||
return NULL;
|
||||
}
|
||||
slim_hidden_def (cairo_scaled_font_create);
|
||||
|
||||
/**
|
||||
* cairo_scaled_font_reference:
|
||||
|
@ -510,7 +519,7 @@ cairo_scaled_font_reference (cairo_scaled_font_t *scaled_font)
|
|||
if (scaled_font == NULL)
|
||||
return NULL;
|
||||
|
||||
if (scaled_font->ref_count == (unsigned int)-1)
|
||||
if (scaled_font->ref_count == CAIRO_REF_COUNT_INVALID)
|
||||
return scaled_font;
|
||||
|
||||
/* We would normally assert (scaled_font->ref_count > 0) here, but
|
||||
|
@ -548,6 +557,7 @@ cairo_scaled_font_reference (cairo_scaled_font_t *scaled_font)
|
|||
|
||||
return scaled_font;
|
||||
}
|
||||
slim_hidden_def (cairo_scaled_font_reference);
|
||||
|
||||
/**
|
||||
* cairo_scaled_font_destroy:
|
||||
|
@ -565,7 +575,7 @@ cairo_scaled_font_destroy (cairo_scaled_font_t *scaled_font)
|
|||
if (scaled_font == NULL)
|
||||
return;
|
||||
|
||||
if (scaled_font->ref_count == (unsigned int)-1)
|
||||
if (scaled_font->ref_count == CAIRO_REF_COUNT_INVALID)
|
||||
return;
|
||||
|
||||
/* cairo_scaled_font_t objects are cached and shared between
|
||||
|
@ -608,6 +618,7 @@ cairo_scaled_font_destroy (cairo_scaled_font_t *scaled_font)
|
|||
}
|
||||
_cairo_scaled_font_map_unlock ();
|
||||
}
|
||||
slim_hidden_def (cairo_scaled_font_destroy);
|
||||
|
||||
/* Public font API follows. */
|
||||
|
||||
|
@ -624,6 +635,7 @@ cairo_scaled_font_extents (cairo_scaled_font_t *scaled_font,
|
|||
{
|
||||
*extents = scaled_font->extents;
|
||||
}
|
||||
slim_hidden_def (cairo_scaled_font_extents);
|
||||
|
||||
/**
|
||||
* cairo_scaled_font_text_extents:
|
||||
|
@ -749,6 +761,7 @@ cairo_scaled_font_glyph_extents (cairo_scaled_font_t *scaled_font,
|
|||
extents->x_advance = x_pos - glyphs[0].x;
|
||||
extents->y_advance = y_pos - glyphs[0].y;
|
||||
}
|
||||
slim_hidden_def (cairo_scaled_font_glyph_extents);
|
||||
|
||||
cairo_status_t
|
||||
_cairo_scaled_font_text_to_glyphs (cairo_scaled_font_t *scaled_font,
|
||||
|
@ -758,7 +771,7 @@ _cairo_scaled_font_text_to_glyphs (cairo_scaled_font_t *scaled_font,
|
|||
cairo_glyph_t **glyphs,
|
||||
int *num_glyphs)
|
||||
{
|
||||
size_t i;
|
||||
int i;
|
||||
uint32_t *ucs4 = NULL;
|
||||
cairo_status_t status = CAIRO_STATUS_SUCCESS;
|
||||
cairo_scaled_glyph_t *scaled_glyph;
|
||||
|
@ -1049,6 +1062,74 @@ _scaled_glyph_path_close_path (void *abstract_closure)
|
|||
return _cairo_path_fixed_close_path (closure->path);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* _trace_mask_to_path:
|
||||
* @bitmap: An alpha mask (either CAIRO_FORMAT_A1 or _A8)
|
||||
* @path: An initialized path to hold the result
|
||||
*
|
||||
* Given a mask surface, (an alpha image), fill out the provided path
|
||||
* so that when filled it would result in something that approximates
|
||||
* the mask.
|
||||
*
|
||||
* Note: The current tracing code here is extremely primitive. It
|
||||
* operates only on an A1 surface, (converting an A8 surface to A1 if
|
||||
* necessary), and performs the tracing by drawing a little square
|
||||
* around each pixel that is on in the mask. We do not pretend that
|
||||
* this is a high-quality result. But we are leaving it up to somone
|
||||
* who cares enough about getting a better result to implement
|
||||
* something more sophisticated.
|
||||
**/
|
||||
static cairo_status_t
|
||||
_trace_mask_to_path (cairo_image_surface_t *mask,
|
||||
cairo_path_fixed_t *path)
|
||||
{
|
||||
cairo_image_surface_t *a1_mask;
|
||||
unsigned char *row, *byte_ptr, byte;
|
||||
int rows, cols, bytes_per_row;
|
||||
int x, y, bit;
|
||||
double xoff, yoff;
|
||||
|
||||
if (mask->format == CAIRO_FORMAT_A1)
|
||||
a1_mask = mask;
|
||||
else
|
||||
a1_mask = _cairo_image_surface_clone (mask, CAIRO_FORMAT_A1);
|
||||
|
||||
if (cairo_surface_status (&a1_mask->base))
|
||||
return cairo_surface_status (&a1_mask->base);
|
||||
|
||||
cairo_surface_get_device_offset (&mask->base, &xoff, &yoff);
|
||||
|
||||
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--) {
|
||||
byte = CAIRO_BITSWAP8_IF_LITTLE_ENDIAN (*byte_ptr);
|
||||
for (bit = 7; bit >= 0 && x < a1_mask->width; bit--, x++) {
|
||||
if (byte & (1 << bit)) {
|
||||
_cairo_path_fixed_move_to (path,
|
||||
_cairo_fixed_from_int (x + xoff),
|
||||
_cairo_fixed_from_int (y + yoff));
|
||||
_cairo_path_fixed_rel_line_to (path,
|
||||
_cairo_fixed_from_int (1),
|
||||
_cairo_fixed_from_int (0));
|
||||
_cairo_path_fixed_rel_line_to (path,
|
||||
_cairo_fixed_from_int (0),
|
||||
_cairo_fixed_from_int (1));
|
||||
_cairo_path_fixed_rel_line_to (path,
|
||||
_cairo_fixed_from_int (-1),
|
||||
_cairo_fixed_from_int (0));
|
||||
_cairo_path_fixed_close_path (path);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (a1_mask != mask)
|
||||
cairo_surface_destroy (&a1_mask->base);
|
||||
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
cairo_status_t
|
||||
_cairo_scaled_font_glyph_path (cairo_scaled_font_t *scaled_font,
|
||||
const cairo_glyph_t *glyphs,
|
||||
|
@ -1058,6 +1139,7 @@ _cairo_scaled_font_glyph_path (cairo_scaled_font_t *scaled_font,
|
|||
cairo_status_t status;
|
||||
int i;
|
||||
cairo_scaled_glyph_path_closure_t closure;
|
||||
cairo_path_fixed_t *glyph_path;
|
||||
|
||||
if (scaled_font->status)
|
||||
return scaled_font->status;
|
||||
|
@ -1070,19 +1152,42 @@ _cairo_scaled_font_glyph_path (cairo_scaled_font_t *scaled_font,
|
|||
glyphs[i].index,
|
||||
CAIRO_SCALED_GLYPH_INFO_PATH,
|
||||
&scaled_glyph);
|
||||
if (status)
|
||||
if (status == CAIRO_STATUS_SUCCESS)
|
||||
glyph_path = scaled_glyph->path;
|
||||
else if (status != CAIRO_INT_STATUS_UNSUPPORTED)
|
||||
return status;
|
||||
|
||||
/* If the font is incapable of providing a path, then we'll
|
||||
* have to trace our own from a surface. */
|
||||
if (status == CAIRO_INT_STATUS_UNSUPPORTED) {
|
||||
status = _cairo_scaled_glyph_lookup (scaled_font,
|
||||
glyphs[i].index,
|
||||
CAIRO_SCALED_GLYPH_INFO_SURFACE,
|
||||
&scaled_glyph);
|
||||
|
||||
glyph_path = _cairo_path_fixed_create ();
|
||||
if (glyph_path == NULL)
|
||||
return CAIRO_STATUS_NO_MEMORY;
|
||||
|
||||
status = _trace_mask_to_path (scaled_glyph->surface, glyph_path);
|
||||
if (status) {
|
||||
_cairo_path_fixed_destroy (glyph_path);
|
||||
return status;
|
||||
}
|
||||
}
|
||||
|
||||
closure.offset.x = _cairo_fixed_from_double (glyphs[i].x);
|
||||
closure.offset.y = _cairo_fixed_from_double (glyphs[i].y);
|
||||
|
||||
status = _cairo_path_fixed_interpret (scaled_glyph->path,
|
||||
status = _cairo_path_fixed_interpret (glyph_path,
|
||||
CAIRO_DIRECTION_FORWARD,
|
||||
_scaled_glyph_path_move_to,
|
||||
_scaled_glyph_path_line_to,
|
||||
_scaled_glyph_path_curve_to,
|
||||
_scaled_glyph_path_close_path,
|
||||
&closure);
|
||||
if (glyph_path != scaled_glyph->path)
|
||||
_cairo_path_fixed_destroy (glyph_path);
|
||||
}
|
||||
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
|
@ -1152,9 +1257,9 @@ _cairo_scaled_glyph_set_metrics (cairo_scaled_glyph_t *scaled_glyph,
|
|||
|
||||
scaled_glyph->metrics.x_advance = fs_metrics->x_advance;
|
||||
scaled_glyph->metrics.y_advance = fs_metrics->y_advance;
|
||||
cairo_matrix_transform_point (&scaled_font->font_matrix,
|
||||
&scaled_glyph->metrics.x_advance,
|
||||
&scaled_glyph->metrics.y_advance);
|
||||
cairo_matrix_transform_distance (&scaled_font->font_matrix,
|
||||
&scaled_glyph->metrics.x_advance,
|
||||
&scaled_glyph->metrics.y_advance);
|
||||
|
||||
scaled_glyph->bbox.p1.x = _cairo_fixed_from_double (min_device_x);
|
||||
scaled_glyph->bbox.p1.y = _cairo_fixed_from_double (min_device_y);
|
||||
|
@ -1298,6 +1403,8 @@ _cairo_scaled_glyph_lookup (cairo_scaled_font_t *scaled_font,
|
|||
* cairo_scaled_font_get_font_face:
|
||||
* @scaled_font: a #cairo_scaled_font_t
|
||||
*
|
||||
* Gets the font face that this scaled font was created for.
|
||||
*
|
||||
* Return value: The #cairo_font_face_t with which @scaled_font was
|
||||
* created.
|
||||
*
|
||||
|
@ -1311,6 +1418,7 @@ cairo_scaled_font_get_font_face (cairo_scaled_font_t *scaled_font)
|
|||
|
||||
return scaled_font->font_face;
|
||||
}
|
||||
slim_hidden_def (cairo_scaled_font_get_font_face);
|
||||
|
||||
/**
|
||||
* cairo_scaled_font_get_font_matrix:
|
||||
|
@ -1333,6 +1441,7 @@ cairo_scaled_font_get_font_matrix (cairo_scaled_font_t *scaled_font,
|
|||
|
||||
*font_matrix = scaled_font->font_matrix;
|
||||
}
|
||||
slim_hidden_def (cairo_scaled_font_get_font_matrix);
|
||||
|
||||
/**
|
||||
* cairo_scaled_font_get_ctm:
|
||||
|
@ -1354,6 +1463,7 @@ cairo_scaled_font_get_ctm (cairo_scaled_font_t *scaled_font,
|
|||
|
||||
*ctm = scaled_font->ctm;
|
||||
}
|
||||
slim_hidden_def (cairo_scaled_font_get_ctm);
|
||||
|
||||
/**
|
||||
* cairo_scaled_font_get_font_options:
|
||||
|
@ -1376,3 +1486,4 @@ cairo_scaled_font_get_font_options (cairo_scaled_font_t *scaled_font,
|
|||
|
||||
_cairo_font_options_init_copy (options, &scaled_font->options);
|
||||
}
|
||||
slim_hidden_def (cairo_scaled_font_get_font_options);
|
||||
|
|
|
@ -45,7 +45,7 @@ const cairo_surface_t _cairo_surface_nil = {
|
|||
&cairo_image_surface_backend, /* backend */
|
||||
CAIRO_SURFACE_TYPE_IMAGE,
|
||||
CAIRO_CONTENT_COLOR,
|
||||
-1, /* ref_count */
|
||||
CAIRO_REF_COUNT_INVALID, /* ref_count */
|
||||
CAIRO_STATUS_NO_MEMORY, /* status */
|
||||
FALSE, /* finished */
|
||||
{ 0, /* size */
|
||||
|
@ -63,15 +63,23 @@ const cairo_surface_t _cairo_surface_nil = {
|
|||
}, /* device_transform_inverse */
|
||||
0.0, /* x_fallback_resolution */
|
||||
0.0, /* y_fallback_resolution */
|
||||
NULL, /* clip */
|
||||
0, /* next_clip_serial */
|
||||
0 /* current_clip_serial */
|
||||
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
|
||||
} /* font_options */
|
||||
};
|
||||
|
||||
const cairo_surface_t _cairo_surface_nil_file_not_found = {
|
||||
&cairo_image_surface_backend, /* backend */
|
||||
CAIRO_SURFACE_TYPE_IMAGE,
|
||||
CAIRO_CONTENT_COLOR,
|
||||
-1, /* ref_count */
|
||||
CAIRO_REF_COUNT_INVALID, /* ref_count */
|
||||
CAIRO_STATUS_FILE_NOT_FOUND, /* status */
|
||||
FALSE, /* finished */
|
||||
{ 0, /* size */
|
||||
|
@ -89,15 +97,23 @@ const cairo_surface_t _cairo_surface_nil_file_not_found = {
|
|||
}, /* device_transform_inverse */
|
||||
0.0, /* x_fallback_resolution */
|
||||
0.0, /* y_fallback_resolution */
|
||||
NULL, /* clip */
|
||||
0, /* next_clip_serial */
|
||||
0 /* current_clip_serial */
|
||||
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
|
||||
} /* font_options */
|
||||
};
|
||||
|
||||
const cairo_surface_t _cairo_surface_nil_read_error = {
|
||||
&cairo_image_surface_backend, /* backend */
|
||||
CAIRO_SURFACE_TYPE_IMAGE,
|
||||
CAIRO_CONTENT_COLOR,
|
||||
-1, /* ref_count */
|
||||
CAIRO_REF_COUNT_INVALID, /* ref_count */
|
||||
CAIRO_STATUS_READ_ERROR, /* status */
|
||||
FALSE, /* finished */
|
||||
{ 0, /* size */
|
||||
|
@ -115,8 +131,16 @@ const cairo_surface_t _cairo_surface_nil_read_error = {
|
|||
}, /* device_transform_inverse */
|
||||
0.0, /* x_fallback_resolution */
|
||||
0.0, /* y_fallback_resolution */
|
||||
NULL, /* clip */
|
||||
0, /* next_clip_serial */
|
||||
0 /* current_clip_serial */
|
||||
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
|
||||
} /* font_options */
|
||||
};
|
||||
|
||||
static void
|
||||
|
@ -157,7 +181,10 @@ _cairo_surface_set_error (cairo_surface_t *surface,
|
|||
* cairo_surface_get_type:
|
||||
* @surface: a #cairo_surface_t
|
||||
*
|
||||
* Return value: The type of @surface. See #cairo_surface_type_t.
|
||||
* This function returns the type of the backend used to create
|
||||
* a surface. See #cairo_surface_type_t for available types.
|
||||
*
|
||||
* Return value: The type of @surface.
|
||||
*
|
||||
* Since: 1.2
|
||||
**/
|
||||
|
@ -170,6 +197,7 @@ cairo_surface_get_type (cairo_surface_t *surface)
|
|||
* surface. */
|
||||
return surface->type;
|
||||
}
|
||||
slim_hidden_def (cairo_surface_get_type);
|
||||
|
||||
/**
|
||||
* cairo_surface_get_content:
|
||||
|
@ -205,6 +233,7 @@ cairo_surface_status (cairo_surface_t *surface)
|
|||
{
|
||||
return surface->status;
|
||||
}
|
||||
slim_hidden_def (cairo_surface_status);
|
||||
|
||||
void
|
||||
_cairo_surface_init (cairo_surface_t *surface,
|
||||
|
@ -234,6 +263,8 @@ _cairo_surface_init (cairo_surface_t *surface,
|
|||
surface->current_clip_serial = 0;
|
||||
|
||||
surface->is_snapshot = FALSE;
|
||||
|
||||
surface->has_font_options = FALSE;
|
||||
}
|
||||
|
||||
cairo_surface_t *
|
||||
|
@ -242,15 +273,28 @@ _cairo_surface_create_similar_scratch (cairo_surface_t *other,
|
|||
int width,
|
||||
int height)
|
||||
{
|
||||
cairo_surface_t *surface = NULL;
|
||||
cairo_font_options_t options;
|
||||
|
||||
cairo_format_t format = _cairo_format_from_content (content);
|
||||
|
||||
if (other->status)
|
||||
return (cairo_surface_t*) &_cairo_surface_nil;
|
||||
|
||||
if (other->backend->create_similar)
|
||||
return other->backend->create_similar (other, content, width, height);
|
||||
else
|
||||
return cairo_image_surface_create (format, width, height);
|
||||
surface = other->backend->create_similar (other, content, width, height);
|
||||
|
||||
if (!surface)
|
||||
surface = cairo_image_surface_create (format, width, height);
|
||||
|
||||
cairo_surface_get_font_options (other, &options);
|
||||
_cairo_surface_set_font_options (surface, &options);
|
||||
|
||||
cairo_surface_set_fallback_resolution (surface,
|
||||
other->x_fallback_resolution,
|
||||
other->y_fallback_resolution);
|
||||
|
||||
return surface;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -261,9 +305,12 @@ _cairo_surface_create_similar_scratch (cairo_surface_t *other,
|
|||
* @height: height of the new surface (in device-space units)
|
||||
*
|
||||
* Create a new surface that is as compatible as possible with an
|
||||
* existing surface. The new surface will use the same backend as
|
||||
* @other unless that is not possible for some reason. The type of the
|
||||
* returned surface may be examined with cairo_surface_get_type().
|
||||
* existing surface. For example the new surface will have the same
|
||||
* fallback resolution and font options as @other. Generally, the new
|
||||
* surface will also use the same backend as @other, unless that is
|
||||
* not possible for some reason. The type of the returned surface may
|
||||
* be examined with cairo_surface_get_type().
|
||||
*
|
||||
* Initially the surface contents are all 0 (transparent if contents
|
||||
* have transparency, black otherwise.)
|
||||
*
|
||||
|
@ -293,6 +340,7 @@ cairo_surface_create_similar (cairo_surface_t *other,
|
|||
width, height,
|
||||
CAIRO_COLOR_TRANSPARENT);
|
||||
}
|
||||
slim_hidden_def (cairo_surface_create_similar);
|
||||
|
||||
cairo_surface_t *
|
||||
_cairo_surface_create_similar_solid (cairo_surface_t *other,
|
||||
|
@ -362,7 +410,7 @@ cairo_surface_reference (cairo_surface_t *surface)
|
|||
if (surface == NULL)
|
||||
return NULL;
|
||||
|
||||
if (surface->ref_count == (unsigned int)-1)
|
||||
if (surface->ref_count == CAIRO_REF_COUNT_INVALID)
|
||||
return surface;
|
||||
|
||||
assert (surface->ref_count > 0);
|
||||
|
@ -371,6 +419,7 @@ cairo_surface_reference (cairo_surface_t *surface)
|
|||
|
||||
return surface;
|
||||
}
|
||||
slim_hidden_def (cairo_surface_reference);
|
||||
|
||||
/**
|
||||
* cairo_surface_destroy:
|
||||
|
@ -386,7 +435,7 @@ cairo_surface_destroy (cairo_surface_t *surface)
|
|||
if (surface == NULL)
|
||||
return;
|
||||
|
||||
if (surface->ref_count == (unsigned int)-1)
|
||||
if (surface->ref_count == CAIRO_REF_COUNT_INVALID)
|
||||
return;
|
||||
|
||||
assert (surface->ref_count > 0);
|
||||
|
@ -452,6 +501,7 @@ cairo_surface_finish (cairo_surface_t *surface)
|
|||
|
||||
surface->finished = TRUE;
|
||||
}
|
||||
slim_hidden_def (cairo_surface_finish);
|
||||
|
||||
/**
|
||||
* cairo_surface_get_user_data:
|
||||
|
@ -495,13 +545,40 @@ cairo_surface_set_user_data (cairo_surface_t *surface,
|
|||
void *user_data,
|
||||
cairo_destroy_func_t destroy)
|
||||
{
|
||||
if (surface->ref_count == -1)
|
||||
if (surface->ref_count == CAIRO_REF_COUNT_INVALID)
|
||||
return CAIRO_STATUS_NO_MEMORY;
|
||||
|
||||
return _cairo_user_data_array_set_data (&surface->user_data,
|
||||
key, user_data, destroy);
|
||||
}
|
||||
|
||||
/**
|
||||
* _cairo_surface_set_font_options:
|
||||
* @surface: a #cairo_surface_t
|
||||
* @options: a #cairo_font_options_t object that contains the
|
||||
* options to use for this surface instead of backend's default
|
||||
* font options.
|
||||
*
|
||||
* Sets the default font rendering options for the surface.
|
||||
* This is useful to correctly propagate default font options when
|
||||
* falling back to an image surface in a backend implementation.
|
||||
* This affects the options returned in cairo_surface_get_font_options().
|
||||
*
|
||||
* If @options is %NULL the surface options are reset to those of
|
||||
* the backend default.
|
||||
**/
|
||||
void
|
||||
_cairo_surface_set_font_options (cairo_surface_t *surface,
|
||||
cairo_font_options_t *options)
|
||||
{
|
||||
if (options) {
|
||||
surface->has_font_options = TRUE;
|
||||
_cairo_font_options_init_copy (&surface->font_options, options);
|
||||
} else {
|
||||
surface->has_font_options = FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* cairo_surface_get_font_options:
|
||||
* @surface: a #cairo_surface_t
|
||||
|
@ -518,12 +595,19 @@ void
|
|||
cairo_surface_get_font_options (cairo_surface_t *surface,
|
||||
cairo_font_options_t *options)
|
||||
{
|
||||
if (!surface->finished && surface->backend->get_font_options) {
|
||||
surface->backend->get_font_options (surface, options);
|
||||
} else {
|
||||
_cairo_font_options_init_default (options);
|
||||
if (!surface->has_font_options) {
|
||||
surface->has_font_options = TRUE;
|
||||
|
||||
if (!surface->finished && surface->backend->get_font_options) {
|
||||
surface->backend->get_font_options (surface, &surface->font_options);
|
||||
} else {
|
||||
_cairo_font_options_init_default (&surface->font_options);
|
||||
}
|
||||
}
|
||||
|
||||
_cairo_font_options_init_copy (options, &surface->font_options);
|
||||
}
|
||||
slim_hidden_def (cairo_surface_get_font_options);
|
||||
|
||||
/**
|
||||
* cairo_surface_flush:
|
||||
|
@ -630,6 +714,7 @@ cairo_surface_mark_dirty_rectangle (cairo_surface_t *surface,
|
|||
_cairo_surface_set_error (surface, status);
|
||||
}
|
||||
}
|
||||
slim_hidden_def (cairo_surface_mark_dirty_rectangle);
|
||||
|
||||
/**
|
||||
* _cairo_surface_set_device_scale:
|
||||
|
@ -712,6 +797,7 @@ cairo_surface_set_device_offset (cairo_surface_t *surface,
|
|||
surface->device_transform_inverse.x0 = - x_offset;
|
||||
surface->device_transform_inverse.y0 = - y_offset;
|
||||
}
|
||||
slim_hidden_def (cairo_surface_set_device_offset);
|
||||
|
||||
/**
|
||||
* cairo_surface_get_device_offset:
|
||||
|
@ -732,6 +818,7 @@ cairo_surface_get_device_offset (cairo_surface_t *surface,
|
|||
*x_offset = surface->device_transform.x0;
|
||||
*y_offset = surface->device_transform.y0;
|
||||
}
|
||||
slim_hidden_def (cairo_surface_get_device_offset);
|
||||
|
||||
/**
|
||||
* cairo_surface_set_fallback_resolution:
|
||||
|
@ -771,6 +858,7 @@ cairo_surface_set_fallback_resolution (cairo_surface_t *surface,
|
|||
surface->x_fallback_resolution = x_pixels_per_inch;
|
||||
surface->y_fallback_resolution = y_pixels_per_inch;
|
||||
}
|
||||
slim_hidden_def (cairo_surface_set_fallback_resolution);
|
||||
|
||||
cairo_bool_t
|
||||
_cairo_surface_has_device_transform (cairo_surface_t *surface)
|
||||
|
@ -1702,9 +1790,9 @@ _cairo_surface_show_glyphs (cairo_surface_t *surface,
|
|||
cairo_scaled_font_t *scaled_font)
|
||||
{
|
||||
cairo_status_t status;
|
||||
cairo_glyph_t *dev_glyphs = (cairo_glyph_t*) glyphs;
|
||||
cairo_scaled_font_t *dev_scaled_font = scaled_font;
|
||||
cairo_pattern_union_t dev_source;
|
||||
cairo_matrix_t font_matrix;
|
||||
|
||||
assert (! surface->is_snapshot);
|
||||
|
||||
|
@ -1718,60 +1806,44 @@ _cairo_surface_show_glyphs (cairo_surface_t *surface,
|
|||
surface,
|
||||
&dev_source.base);
|
||||
|
||||
if (_cairo_surface_has_device_transform (surface))
|
||||
cairo_scaled_font_get_font_matrix (scaled_font, &font_matrix);
|
||||
|
||||
if (_cairo_surface_has_device_transform (surface) &&
|
||||
! _cairo_matrix_is_integer_translation (&surface->device_transform, NULL, NULL))
|
||||
{
|
||||
int i;
|
||||
cairo_font_options_t *font_options;
|
||||
cairo_matrix_t dev_ctm;
|
||||
|
||||
dev_glyphs = malloc (sizeof(cairo_glyph_t) * num_glyphs);
|
||||
if (!dev_glyphs)
|
||||
return CAIRO_STATUS_NO_MEMORY;
|
||||
font_options = cairo_font_options_create ();
|
||||
|
||||
for (i = 0; i < num_glyphs; i++) {
|
||||
dev_glyphs[i].index = glyphs[i].index;
|
||||
dev_glyphs[i].x = glyphs[i].x;
|
||||
dev_glyphs[i].y = glyphs[i].y;
|
||||
cairo_matrix_transform_point (&surface->device_transform,
|
||||
&dev_glyphs[i].x,
|
||||
&dev_glyphs[i].y);
|
||||
}
|
||||
|
||||
if (! _cairo_matrix_is_integer_translation (&surface->device_transform, NULL, NULL)) {
|
||||
cairo_font_options_t *font_options;
|
||||
cairo_matrix_t font_matrix, dev_ctm;
|
||||
|
||||
font_options = cairo_font_options_create ();
|
||||
|
||||
cairo_scaled_font_get_font_matrix (scaled_font, &font_matrix);
|
||||
cairo_scaled_font_get_ctm (scaled_font, &dev_ctm);
|
||||
cairo_matrix_multiply (&dev_ctm, &dev_ctm, &surface->device_transform);
|
||||
cairo_scaled_font_get_font_options (scaled_font, font_options);
|
||||
dev_scaled_font = cairo_scaled_font_create (cairo_scaled_font_get_font_face (scaled_font),
|
||||
&font_matrix,
|
||||
&dev_ctm,
|
||||
font_options);
|
||||
cairo_font_options_destroy (font_options);
|
||||
}
|
||||
cairo_scaled_font_get_ctm (scaled_font, &dev_ctm);
|
||||
cairo_matrix_multiply (&dev_ctm, &dev_ctm, &surface->device_transform);
|
||||
cairo_scaled_font_get_font_options (scaled_font, font_options);
|
||||
dev_scaled_font = cairo_scaled_font_create (cairo_scaled_font_get_font_face (scaled_font),
|
||||
&font_matrix,
|
||||
&dev_ctm,
|
||||
font_options);
|
||||
cairo_font_options_destroy (font_options);
|
||||
}
|
||||
|
||||
if (surface->backend->show_glyphs) {
|
||||
status = surface->backend->show_glyphs (surface, op, &dev_source.base,
|
||||
dev_glyphs, num_glyphs,
|
||||
glyphs, num_glyphs,
|
||||
dev_scaled_font);
|
||||
if (status != CAIRO_INT_STATUS_UNSUPPORTED)
|
||||
goto FINISH;
|
||||
}
|
||||
|
||||
status = _cairo_surface_fallback_show_glyphs (surface, op, &dev_source.base,
|
||||
dev_glyphs, num_glyphs,
|
||||
glyphs, num_glyphs,
|
||||
dev_scaled_font);
|
||||
|
||||
FINISH:
|
||||
if (dev_glyphs != glyphs)
|
||||
free (dev_glyphs);
|
||||
|
||||
if (dev_scaled_font != scaled_font)
|
||||
cairo_scaled_font_destroy (dev_scaled_font);
|
||||
|
||||
_cairo_pattern_fini (&dev_source.base);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
|
|
|
@ -42,7 +42,6 @@
|
|||
#include "cairo-svg.h"
|
||||
#include "cairo-svg-test.h"
|
||||
#include "cairo-path-fixed-private.h"
|
||||
#include "cairo-ft-private.h"
|
||||
#include "cairo-meta-surface-private.h"
|
||||
#include "cairo-paginated-surface-private.h"
|
||||
#include "cairo-scaled-font-subsets-private.h"
|
||||
|
@ -290,7 +289,7 @@ cairo_svg_surface_restrict_to_version (cairo_surface_t *abstract_surface,
|
|||
return;
|
||||
}
|
||||
|
||||
if (version >= 0 && version < CAIRO_SVG_VERSION_LAST)
|
||||
if (version < CAIRO_SVG_VERSION_LAST)
|
||||
surface->document->svg_version = version;
|
||||
}
|
||||
|
||||
|
@ -330,7 +329,7 @@ cairo_svg_get_versions (cairo_svg_version_t const **versions,
|
|||
const char *
|
||||
cairo_svg_version_to_string (cairo_svg_version_t version)
|
||||
{
|
||||
if (version < 0 || version >= CAIRO_SVG_VERSION_LAST)
|
||||
if (version >= CAIRO_SVG_VERSION_LAST)
|
||||
return NULL;
|
||||
|
||||
return _cairo_svg_version_strings[version];
|
||||
|
@ -574,7 +573,11 @@ _cairo_svg_document_emit_bitmap_glyph_data (cairo_svg_document_t *document,
|
|||
return status;
|
||||
|
||||
image = scaled_glyph->surface;
|
||||
assert (image->format == CAIRO_FORMAT_A1);
|
||||
if (image->format != CAIRO_FORMAT_A1) {
|
||||
image = _cairo_image_surface_clone (image, CAIRO_FORMAT_A1);
|
||||
if (cairo_surface_status (&image->base))
|
||||
return cairo_surface_status (&image->base);
|
||||
}
|
||||
|
||||
_cairo_output_stream_printf (document->xml_node_glyphs, "<g");
|
||||
emit_transform (document->xml_node_glyphs, " transform", ">/n", &image->base.device_transform);
|
||||
|
@ -593,6 +596,10 @@ _cairo_svg_document_emit_bitmap_glyph_data (cairo_svg_document_t *document,
|
|||
}
|
||||
}
|
||||
_cairo_output_stream_printf (document->xml_node_glyphs, "</g>\n");
|
||||
|
||||
if (image != scaled_glyph->surface)
|
||||
cairo_surface_destroy (&image->base);
|
||||
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
|
@ -626,7 +633,7 @@ _cairo_svg_document_emit_font_subset (cairo_scaled_font_subset_t *font_subset,
|
|||
void *closure)
|
||||
{
|
||||
cairo_svg_document_t *document = closure;
|
||||
int i;
|
||||
unsigned int i;
|
||||
|
||||
for (i = 0; i < font_subset->num_glyphs; i++) {
|
||||
_cairo_svg_document_emit_glyph (document,
|
||||
|
@ -898,7 +905,7 @@ emit_meta_surface (cairo_svg_document_t *document,
|
|||
cairo_output_stream_t *contents;
|
||||
cairo_meta_surface_t *meta;
|
||||
cairo_meta_snapshot_t *snapshot;
|
||||
int num_elements;
|
||||
unsigned int num_elements;
|
||||
unsigned int i, id;
|
||||
|
||||
num_elements = document->meta_snapshots.num_elements;
|
||||
|
@ -1100,7 +1107,7 @@ emit_pattern_stops (cairo_output_stream_t *output,
|
|||
double start_offset)
|
||||
{
|
||||
double offset;
|
||||
int i;
|
||||
unsigned int i;
|
||||
|
||||
for (i = 0; i < pattern->n_stops; i++) {
|
||||
offset = start_offset + (1 - start_offset ) *
|
||||
|
@ -1602,7 +1609,7 @@ _cairo_svg_surface_intersect_clip_path (void *dst,
|
|||
cairo_svg_surface_t *surface = dst;
|
||||
cairo_svg_document_t *document = surface->document;
|
||||
cairo_status_t status;
|
||||
int i;
|
||||
unsigned int i;
|
||||
|
||||
if (path == NULL) {
|
||||
for (i = 0; i < surface->clip_level; i++)
|
||||
|
@ -1638,10 +1645,11 @@ static void
|
|||
_cairo_svg_surface_get_font_options (void *abstract_surface,
|
||||
cairo_font_options_t *options)
|
||||
{
|
||||
_cairo_font_options_init_default (options);
|
||||
_cairo_font_options_init_default (options);
|
||||
|
||||
cairo_font_options_set_hint_style (options, CAIRO_HINT_STYLE_NONE);
|
||||
cairo_font_options_set_hint_metrics (options, CAIRO_HINT_METRICS_OFF);
|
||||
cairo_font_options_set_hint_style (options, CAIRO_HINT_STYLE_NONE);
|
||||
cairo_font_options_set_hint_metrics (options, CAIRO_HINT_METRICS_OFF);
|
||||
cairo_font_options_set_antialias (options, CAIRO_ANTIALIAS_GRAY);
|
||||
}
|
||||
|
||||
static const cairo_surface_backend_t cairo_svg_surface_backend = {
|
||||
|
@ -1795,8 +1803,7 @@ _cairo_svg_document_finish (cairo_svg_document_t *document)
|
|||
_cairo_output_stream_destroy (document->xml_node_glyphs);
|
||||
_cairo_output_stream_destroy (document->xml_node_defs);
|
||||
|
||||
status = _cairo_output_stream_get_status (output);
|
||||
_cairo_output_stream_destroy (output);
|
||||
status = _cairo_output_stream_destroy (output);
|
||||
|
||||
for (i = 0; i < document->meta_snapshots.num_elements; i++) {
|
||||
snapshot = _cairo_array_index (&document->meta_snapshots, i);
|
||||
|
|
|
@ -0,0 +1,170 @@
|
|||
/* cairo - a vector graphics library with display and print output
|
||||
*
|
||||
* Copyright © 2006 Red Hat, Inc
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it either under the terms of the GNU Lesser General Public
|
||||
* License version 2.1 as published by the Free Software Foundation
|
||||
* (the "LGPL") or, at your option, under the terms of the Mozilla
|
||||
* Public License Version 1.1 (the "MPL"). If you do not alter this
|
||||
* notice, a recipient may use your version of this file under either
|
||||
* the MPL or the LGPL.
|
||||
*
|
||||
* You should have received a copy of the LGPL along with this library
|
||||
* in the file COPYING-LGPL-2.1; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
* You should have received a copy of the MPL along with this library
|
||||
* in the file COPYING-MPL-1.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License
|
||||
* Version 1.1 (the "License"); you may not use this file except in
|
||||
* compliance with the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY
|
||||
* OF ANY KIND, either express or implied. See the LGPL or the MPL for
|
||||
* the specific language governing rights and limitations.
|
||||
*
|
||||
* The Original Code is the cairo graphics library.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Red Hat, Inc.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Kristian Høgsberg <krh@redhat.com>
|
||||
* Adrian Johnson <ajohnson@redneon.com>
|
||||
*/
|
||||
|
||||
#ifndef CAIRO_TRUETYPE_SUBSET_PRIVATE_H
|
||||
#define CAIRO_TRUETYPE_SUBSET_PRIVATE_H
|
||||
|
||||
#include "cairoint.h"
|
||||
|
||||
/* 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
|
||||
* "FIXED" in the TT spec are broken into two *_1 and *_2 16-bit
|
||||
* parts, and 64-bit members are broken into four.
|
||||
*
|
||||
* The test truetype-tables in the test suite makes sure that
|
||||
* these tables have the right size. Please update that test
|
||||
* if you add new tables/structs that should be packed.
|
||||
*/
|
||||
|
||||
#define MAKE_TT_TAG(a, b, c, d) (a<<24 | b<<16 | c<<8 | d)
|
||||
#define TT_TAG_cmap MAKE_TT_TAG('c','m','a','p')
|
||||
#define TT_TAG_cvt MAKE_TT_TAG('c','v','t',' ')
|
||||
#define TT_TAG_fpgm MAKE_TT_TAG('f','p','g','m')
|
||||
#define TT_TAG_glyf MAKE_TT_TAG('g','l','y','f')
|
||||
#define TT_TAG_head MAKE_TT_TAG('h','e','a','d')
|
||||
#define TT_TAG_hhea MAKE_TT_TAG('h','h','e','a')
|
||||
#define TT_TAG_hmtx MAKE_TT_TAG('h','m','t','x')
|
||||
#define TT_TAG_loca MAKE_TT_TAG('l','o','c','a')
|
||||
#define TT_TAG_maxp MAKE_TT_TAG('m','a','x','p')
|
||||
#define TT_TAG_name MAKE_TT_TAG('n','a','m','e')
|
||||
#define TT_TAG_prep MAKE_TT_TAG('p','r','e','p')
|
||||
|
||||
/* All tt_* structs are big-endian */
|
||||
typedef struct _tt_head {
|
||||
int16_t version_1;
|
||||
int16_t version_2;
|
||||
int16_t revision_1;
|
||||
int16_t revision_2;
|
||||
uint16_t checksum_1;
|
||||
uint16_t checksum_2;
|
||||
uint16_t magic_1;
|
||||
uint16_t magic_2;
|
||||
uint16_t flags;
|
||||
uint16_t units_per_em;
|
||||
int16_t created_1;
|
||||
int16_t created_2;
|
||||
int16_t created_3;
|
||||
int16_t created_4;
|
||||
int16_t modified_1;
|
||||
int16_t modified_2;
|
||||
int16_t modified_3;
|
||||
int16_t modified_4;
|
||||
int16_t x_min; /* FWORD */
|
||||
int16_t y_min; /* FWORD */
|
||||
int16_t x_max; /* FWORD */
|
||||
int16_t y_max; /* FWORD */
|
||||
uint16_t mac_style;
|
||||
uint16_t lowest_rec_pppem;
|
||||
int16_t font_direction_hint;
|
||||
int16_t index_to_loc_format;
|
||||
int16_t glyph_data_format;
|
||||
} tt_head_t;
|
||||
|
||||
typedef struct _tt_hhea {
|
||||
int16_t version_1;
|
||||
int16_t version_2;
|
||||
int16_t ascender; /* FWORD */
|
||||
int16_t descender; /* FWORD */
|
||||
int16_t line_gap; /* FWORD */
|
||||
uint16_t advance_max_width; /* UFWORD */
|
||||
int16_t min_left_side_bearing; /* FWORD */
|
||||
int16_t min_right_side_bearing; /* FWORD */
|
||||
int16_t x_max_extent; /* FWORD */
|
||||
int16_t caret_slope_rise;
|
||||
int16_t caret_slope_run;
|
||||
int16_t reserved[5];
|
||||
int16_t metric_data_format;
|
||||
uint16_t num_hmetrics;
|
||||
} tt_hhea_t;
|
||||
|
||||
typedef struct _tt_maxp {
|
||||
int16_t version_1;
|
||||
int16_t version_2;
|
||||
uint16_t num_glyphs;
|
||||
uint16_t max_points;
|
||||
uint16_t max_contours;
|
||||
uint16_t max_composite_points;
|
||||
uint16_t max_composite_contours;
|
||||
uint16_t max_zones;
|
||||
uint16_t max_twilight_points;
|
||||
uint16_t max_storage;
|
||||
uint16_t max_function_defs;
|
||||
uint16_t max_instruction_defs;
|
||||
uint16_t max_stack_elements;
|
||||
uint16_t max_size_of_instructions;
|
||||
uint16_t max_component_elements;
|
||||
uint16_t max_component_depth;
|
||||
} tt_maxp_t;
|
||||
|
||||
typedef struct _tt_name_record {
|
||||
uint16_t platform;
|
||||
uint16_t encoding;
|
||||
uint16_t language;
|
||||
uint16_t name;
|
||||
uint16_t length;
|
||||
uint16_t offset;
|
||||
} tt_name_record_t;
|
||||
|
||||
typedef struct _tt_name {
|
||||
uint16_t format;
|
||||
uint16_t num_records;
|
||||
uint16_t strings_offset;
|
||||
tt_name_record_t records[1];
|
||||
} tt_name_t;
|
||||
|
||||
|
||||
|
||||
/* composite_glyph_t flags */
|
||||
#define TT_ARG_1_AND_2_ARE_WORDS 0x0001
|
||||
#define TT_WE_HAVE_A_SCALE 0x0008
|
||||
#define TT_MORE_COMPONENTS 0x0020
|
||||
#define TT_WE_HAVE_AN_X_AND_Y_SCALE 0x0040
|
||||
#define TT_WE_HAVE_A_TWO_BY_TWO 0x0080
|
||||
|
||||
typedef struct _tt_composite_glyph {
|
||||
uint16_t flags;
|
||||
uint16_t index;
|
||||
uint16_t args[7]; /* 1 to 7 arguments depending on value of flags */
|
||||
} tt_composite_glyph_t;
|
||||
|
||||
typedef struct _tt_glyph_data {
|
||||
int16_t num_contours;
|
||||
int8_t data[8];
|
||||
tt_composite_glyph_t glyph;
|
||||
} tt_glyph_data_t;
|
||||
|
||||
#endif /* CAIRO_TRUETYPE_SUBSET_PRIVATE_H */
|
|
@ -0,0 +1,883 @@
|
|||
/* cairo - a vector graphics library with display and print output
|
||||
*
|
||||
* Copyright © 2004 Red Hat, Inc
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it either under the terms of the GNU Lesser General Public
|
||||
* License version 2.1 as published by the Free Software Foundation
|
||||
* (the "LGPL") or, at your option, under the terms of the Mozilla
|
||||
* Public License Version 1.1 (the "MPL"). If you do not alter this
|
||||
* notice, a recipient may use your version of this file under either
|
||||
* the MPL or the LGPL.
|
||||
*
|
||||
* You should have received a copy of the LGPL along with this library
|
||||
* in the file COPYING-LGPL-2.1; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
* You should have received a copy of the MPL along with this library
|
||||
* in the file COPYING-MPL-1.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License
|
||||
* Version 1.1 (the "License"); you may not use this file except in
|
||||
* compliance with the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY
|
||||
* OF ANY KIND, either express or implied. See the LGPL or the MPL for
|
||||
* the specific language governing rights and limitations.
|
||||
*
|
||||
* The Original Code is the cairo graphics library.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Red Hat, Inc.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Kristian Høgsberg <krh@redhat.com>
|
||||
* Adrian Johnson <ajohnson@redneon.com>
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
#include "cairoint.h"
|
||||
#include "cairo-scaled-font-subsets-private.h"
|
||||
#include "cairo-truetype-subset-private.h"
|
||||
|
||||
|
||||
typedef struct subset_glyph subset_glyph_t;
|
||||
struct subset_glyph {
|
||||
int parent_index;
|
||||
unsigned long location;
|
||||
};
|
||||
|
||||
typedef struct _cairo_truetype_font {
|
||||
|
||||
cairo_scaled_font_subset_t *scaled_font_subset;
|
||||
|
||||
struct {
|
||||
char *base_font;
|
||||
unsigned int num_glyphs;
|
||||
int *widths;
|
||||
long x_min, y_min, x_max, y_max;
|
||||
long ascent, descent;
|
||||
} base;
|
||||
|
||||
subset_glyph_t *glyphs;
|
||||
const cairo_scaled_font_backend_t *backend;
|
||||
int num_glyphs_in_face;
|
||||
int checksum_index;
|
||||
cairo_array_t output;
|
||||
cairo_array_t string_offsets;
|
||||
unsigned long last_offset;
|
||||
unsigned long last_boundary;
|
||||
int *parent_to_subset;
|
||||
cairo_status_t status;
|
||||
|
||||
} cairo_truetype_font_t;
|
||||
|
||||
static int
|
||||
cairo_truetype_font_use_glyph (cairo_truetype_font_t *font, int glyph);
|
||||
|
||||
#define ARRAY_LENGTH(a) ( (sizeof (a)) / (sizeof ((a)[0])) )
|
||||
|
||||
#define SFNT_VERSION 0x00010000
|
||||
#define SFNT_STRING_MAX_LENGTH 65535
|
||||
|
||||
#ifdef WORDS_BIGENDIAN
|
||||
|
||||
#define cpu_to_be16(v) (v)
|
||||
#define be16_to_cpu(v) (v)
|
||||
#define cpu_to_be32(v) (v)
|
||||
#define be32_to_cpu(v) (v)
|
||||
|
||||
#else
|
||||
|
||||
static inline uint16_t
|
||||
cpu_to_be16(uint16_t v)
|
||||
{
|
||||
return (v << 8) | (v >> 8);
|
||||
}
|
||||
|
||||
static inline uint16_t
|
||||
be16_to_cpu(uint16_t v)
|
||||
{
|
||||
return cpu_to_be16 (v);
|
||||
}
|
||||
|
||||
static inline uint32_t
|
||||
cpu_to_be32(uint32_t v)
|
||||
{
|
||||
return (cpu_to_be16 (v) << 16) | cpu_to_be16 (v >> 16);
|
||||
}
|
||||
|
||||
static inline uint32_t
|
||||
be32_to_cpu(uint32_t v)
|
||||
{
|
||||
return cpu_to_be32 (v);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
static cairo_status_t
|
||||
_cairo_truetype_font_create (cairo_scaled_font_subset_t *scaled_font_subset,
|
||||
cairo_truetype_font_t **font_return)
|
||||
{
|
||||
cairo_status_t status = CAIRO_STATUS_NO_MEMORY;
|
||||
cairo_truetype_font_t *font;
|
||||
const cairo_scaled_font_backend_t *backend;
|
||||
tt_head_t head;
|
||||
tt_hhea_t hhea;
|
||||
tt_maxp_t maxp;
|
||||
tt_name_t *name;
|
||||
tt_name_record_t *record;
|
||||
unsigned long size;
|
||||
int i, j;
|
||||
|
||||
backend = scaled_font_subset->scaled_font->backend;
|
||||
if (!backend->load_truetype_table)
|
||||
return CAIRO_INT_STATUS_UNSUPPORTED;
|
||||
|
||||
/* FIXME: We should either support subsetting vertical fonts, or fail on
|
||||
* vertical. Currently font_options_t doesn't have vertical flag, but
|
||||
* it should be added in the future. For now, the freetype backend
|
||||
* returns UNSUPPORTED in load_truetype_table if the font is vertical.
|
||||
*
|
||||
* if (cairo_font_options_get_vertical_layout (scaled_font_subset->scaled_font))
|
||||
* return CAIRO_INT_STATUS_UNSUPPORTED;
|
||||
*/
|
||||
|
||||
size = sizeof (tt_head_t);
|
||||
if (backend->load_truetype_table (scaled_font_subset->scaled_font,
|
||||
TT_TAG_head, 0, (unsigned char *) &head,
|
||||
&size) != CAIRO_STATUS_SUCCESS)
|
||||
return CAIRO_INT_STATUS_UNSUPPORTED;
|
||||
|
||||
size = sizeof (tt_maxp_t);
|
||||
if (backend->load_truetype_table (scaled_font_subset->scaled_font,
|
||||
TT_TAG_maxp, 0, (unsigned char *) &maxp,
|
||||
&size) != CAIRO_STATUS_SUCCESS)
|
||||
return CAIRO_INT_STATUS_UNSUPPORTED;
|
||||
|
||||
size = sizeof (tt_hhea_t);
|
||||
if (backend->load_truetype_table (scaled_font_subset->scaled_font,
|
||||
TT_TAG_hhea, 0, (unsigned char *) &hhea,
|
||||
&size) != CAIRO_STATUS_SUCCESS)
|
||||
return CAIRO_INT_STATUS_UNSUPPORTED;
|
||||
|
||||
size = 0;
|
||||
if (backend->load_truetype_table (scaled_font_subset->scaled_font,
|
||||
TT_TAG_name, 0, NULL,
|
||||
&size) != CAIRO_STATUS_SUCCESS)
|
||||
return CAIRO_INT_STATUS_UNSUPPORTED;
|
||||
name = malloc(size);
|
||||
if (name == NULL)
|
||||
return CAIRO_STATUS_NO_MEMORY;
|
||||
backend->load_truetype_table (scaled_font_subset->scaled_font,
|
||||
TT_TAG_name, 0, (unsigned char *) name,
|
||||
&size);
|
||||
|
||||
font = malloc (sizeof (cairo_truetype_font_t));
|
||||
if (font == NULL)
|
||||
goto fail0;
|
||||
|
||||
font->backend = backend;
|
||||
font->num_glyphs_in_face = be16_to_cpu (maxp.num_glyphs);
|
||||
font->scaled_font_subset = scaled_font_subset;
|
||||
|
||||
font->last_offset = 0;
|
||||
font->last_boundary = 0;
|
||||
_cairo_array_init (&font->output, sizeof (char));
|
||||
if (_cairo_array_grow_by (&font->output, 4096) != CAIRO_STATUS_SUCCESS)
|
||||
goto fail1;
|
||||
font->glyphs = calloc (font->num_glyphs_in_face + 1, sizeof (subset_glyph_t));
|
||||
if (font->glyphs == NULL)
|
||||
goto fail2;
|
||||
|
||||
font->parent_to_subset = calloc (font->num_glyphs_in_face, sizeof (int));
|
||||
if (font->parent_to_subset == NULL)
|
||||
goto fail3;
|
||||
|
||||
font->base.num_glyphs = 0;
|
||||
font->base.x_min = be16_to_cpu (head.x_min);
|
||||
font->base.y_min = be16_to_cpu (head.y_min);
|
||||
font->base.x_max = be16_to_cpu (head.x_max);
|
||||
font->base.y_max = be16_to_cpu (head.y_max);
|
||||
font->base.ascent = be16_to_cpu (hhea.ascender);
|
||||
font->base.descent = be16_to_cpu (hhea.descender);
|
||||
|
||||
/* Extract the font name from the name table. At present this
|
||||
* just looks for the Mac platform/Roman encoded font name. It
|
||||
* should be extended to use any suitable font name in the
|
||||
* name table. If the mac/roman font name is not found a
|
||||
* CairoFont-x-y name is created.
|
||||
*/
|
||||
font->base.base_font = NULL;
|
||||
for (i = 0; i < be16_to_cpu(name->num_records); i++) {
|
||||
record = &(name->records[i]);
|
||||
if ((be16_to_cpu (record->platform) == 1) &&
|
||||
(be16_to_cpu (record->encoding) == 0) &&
|
||||
(be16_to_cpu (record->name) == 4)) {
|
||||
font->base.base_font = malloc (be16_to_cpu(record->length) + 1);
|
||||
if (font->base.base_font) {
|
||||
strncpy(font->base.base_font,
|
||||
((char*)name) + be16_to_cpu (name->strings_offset) + be16_to_cpu (record->offset),
|
||||
be16_to_cpu (record->length));
|
||||
font->base.base_font[be16_to_cpu (record->length)] = 0;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
free (name);
|
||||
name = NULL;
|
||||
|
||||
if (font->base.base_font == NULL) {
|
||||
font->base.base_font = malloc (30);
|
||||
if (font->base.base_font == NULL)
|
||||
goto fail4;
|
||||
snprintf(font->base.base_font, 30, "CairoFont-%u-%u",
|
||||
scaled_font_subset->font_id,
|
||||
scaled_font_subset->subset_id);
|
||||
}
|
||||
|
||||
for (i = 0, j = 0; font->base.base_font[j]; j++) {
|
||||
if (font->base.base_font[j] == ' ')
|
||||
continue;
|
||||
font->base.base_font[i++] = font->base.base_font[j];
|
||||
}
|
||||
font->base.base_font[i] = '\0';
|
||||
|
||||
font->base.widths = calloc (font->num_glyphs_in_face, sizeof (int));
|
||||
if (font->base.widths == NULL)
|
||||
goto fail5;
|
||||
|
||||
_cairo_array_init (&font->string_offsets, sizeof (unsigned long));
|
||||
if (_cairo_array_grow_by (&font->string_offsets, 10) != CAIRO_STATUS_SUCCESS)
|
||||
goto fail6;
|
||||
|
||||
font->status = CAIRO_STATUS_SUCCESS;
|
||||
|
||||
*font_return = font;
|
||||
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
|
||||
fail6:
|
||||
free (font->base.widths);
|
||||
fail5:
|
||||
free (font->base.base_font);
|
||||
fail4:
|
||||
free (font->parent_to_subset);
|
||||
fail3:
|
||||
free (font->glyphs);
|
||||
fail2:
|
||||
_cairo_array_fini (&font->output);
|
||||
fail1:
|
||||
free (font);
|
||||
fail0:
|
||||
if (name)
|
||||
free (name);
|
||||
return status;
|
||||
}
|
||||
|
||||
static void
|
||||
cairo_truetype_font_destroy (cairo_truetype_font_t *font)
|
||||
{
|
||||
_cairo_array_fini (&font->string_offsets);
|
||||
free (font->base.widths);
|
||||
free (font->base.base_font);
|
||||
free (font->parent_to_subset);
|
||||
free (font->glyphs);
|
||||
_cairo_array_fini (&font->output);
|
||||
free (font);
|
||||
}
|
||||
|
||||
static cairo_status_t
|
||||
cairo_truetype_font_allocate_write_buffer (cairo_truetype_font_t *font,
|
||||
size_t length,
|
||||
unsigned char **buffer)
|
||||
{
|
||||
cairo_status_t status;
|
||||
|
||||
status = _cairo_array_allocate (&font->output, length, (void **) buffer);
|
||||
if (status)
|
||||
return status;
|
||||
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
static cairo_status_t
|
||||
cairo_truetype_font_write (cairo_truetype_font_t *font,
|
||||
const void *data,
|
||||
size_t length)
|
||||
{
|
||||
cairo_status_t status;
|
||||
|
||||
status = _cairo_array_append_multiple (&font->output, data, length);
|
||||
if (status)
|
||||
return status;
|
||||
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
static void
|
||||
cairo_truetype_font_write_be16 (cairo_truetype_font_t *font,
|
||||
uint16_t value)
|
||||
{
|
||||
uint16_t be16_value;
|
||||
|
||||
be16_value = cpu_to_be16 (value);
|
||||
cairo_truetype_font_write (font, &be16_value, sizeof be16_value);
|
||||
}
|
||||
|
||||
static void
|
||||
cairo_truetype_font_write_be32 (cairo_truetype_font_t *font,
|
||||
uint32_t value)
|
||||
{
|
||||
uint32_t be32_value;
|
||||
|
||||
be32_value = cpu_to_be32 (value);
|
||||
cairo_truetype_font_write (font, &be32_value, sizeof be32_value);
|
||||
}
|
||||
|
||||
static unsigned long
|
||||
cairo_truetype_font_align_output (cairo_truetype_font_t *font)
|
||||
{
|
||||
int length, aligned, pad;
|
||||
unsigned char *padding;
|
||||
|
||||
length = _cairo_array_num_elements (&font->output);
|
||||
aligned = (length + 3) & ~3;
|
||||
pad = aligned - length;
|
||||
|
||||
if (pad) {
|
||||
cairo_truetype_font_allocate_write_buffer (font, pad, &padding);
|
||||
memset (padding, 0, pad);
|
||||
}
|
||||
|
||||
return aligned;
|
||||
}
|
||||
|
||||
static void
|
||||
cairo_truetype_font_check_boundary (cairo_truetype_font_t *font,
|
||||
unsigned long boundary)
|
||||
{
|
||||
if (boundary - font->last_offset > SFNT_STRING_MAX_LENGTH)
|
||||
{
|
||||
_cairo_array_append(&font->string_offsets, &font->last_boundary);
|
||||
font->last_offset = font->last_boundary;
|
||||
}
|
||||
font->last_boundary = boundary;
|
||||
}
|
||||
|
||||
static int
|
||||
cairo_truetype_font_write_cmap_table (cairo_truetype_font_t *font,
|
||||
unsigned long tag)
|
||||
{
|
||||
unsigned int i;
|
||||
|
||||
cairo_truetype_font_write_be16 (font, 0);
|
||||
cairo_truetype_font_write_be16 (font, 1);
|
||||
|
||||
cairo_truetype_font_write_be16 (font, 1);
|
||||
cairo_truetype_font_write_be16 (font, 0);
|
||||
cairo_truetype_font_write_be32 (font, 12);
|
||||
|
||||
/* Output a format 6 encoding table. */
|
||||
|
||||
cairo_truetype_font_write_be16 (font, 6);
|
||||
cairo_truetype_font_write_be16 (font, 10 + 2 * (font->base.num_glyphs - 1));
|
||||
cairo_truetype_font_write_be16 (font, 0);
|
||||
cairo_truetype_font_write_be16 (font, 1); /* First glyph */
|
||||
cairo_truetype_font_write_be16 (font, font->base.num_glyphs - 1);
|
||||
for (i = 1; i < font->base.num_glyphs; i++)
|
||||
cairo_truetype_font_write_be16 (font, i);
|
||||
|
||||
return font->status;
|
||||
}
|
||||
|
||||
static int
|
||||
cairo_truetype_font_write_generic_table (cairo_truetype_font_t *font,
|
||||
unsigned long tag)
|
||||
{
|
||||
cairo_status_t status;
|
||||
unsigned char *buffer;
|
||||
unsigned long size;
|
||||
|
||||
size = 0;
|
||||
if (font->backend->load_truetype_table( font->scaled_font_subset->scaled_font,
|
||||
tag, 0, NULL, &size) != CAIRO_STATUS_SUCCESS) {
|
||||
font->status = CAIRO_INT_STATUS_UNSUPPORTED;
|
||||
return font->status;
|
||||
}
|
||||
status = cairo_truetype_font_allocate_write_buffer (font, size, &buffer);
|
||||
/* XXX: Need to check status here. */
|
||||
font->backend->load_truetype_table (font->scaled_font_subset->scaled_font,
|
||||
tag, 0, buffer, &size);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
cairo_truetype_font_remap_composite_glyph (cairo_truetype_font_t *font,
|
||||
unsigned char *buffer)
|
||||
{
|
||||
tt_glyph_data_t *glyph_data;
|
||||
tt_composite_glyph_t *composite_glyph;
|
||||
int num_args;
|
||||
int has_more_components;
|
||||
unsigned short flags;
|
||||
unsigned short index;
|
||||
|
||||
glyph_data = (tt_glyph_data_t *) buffer;
|
||||
if ((int16_t)be16_to_cpu (glyph_data->num_contours) >= 0)
|
||||
return;
|
||||
|
||||
composite_glyph = &glyph_data->glyph;
|
||||
do {
|
||||
flags = be16_to_cpu (composite_glyph->flags);
|
||||
has_more_components = flags & TT_MORE_COMPONENTS;
|
||||
index = cairo_truetype_font_use_glyph (font, be16_to_cpu (composite_glyph->index));
|
||||
composite_glyph->index = cpu_to_be16 (index);
|
||||
num_args = 1;
|
||||
if (flags & TT_ARG_1_AND_2_ARE_WORDS)
|
||||
num_args += 1;
|
||||
if (flags & TT_WE_HAVE_A_SCALE)
|
||||
num_args += 1;
|
||||
else if (flags & TT_WE_HAVE_AN_X_AND_Y_SCALE)
|
||||
num_args += 2;
|
||||
else if (flags & TT_WE_HAVE_A_TWO_BY_TWO)
|
||||
num_args += 3;
|
||||
composite_glyph = (tt_composite_glyph_t *) &(composite_glyph->args[num_args]);
|
||||
} while (has_more_components);
|
||||
}
|
||||
|
||||
static int
|
||||
cairo_truetype_font_write_glyf_table (cairo_truetype_font_t *font,
|
||||
unsigned long tag)
|
||||
{
|
||||
cairo_status_t status;
|
||||
unsigned long start_offset, index, size, next;
|
||||
tt_head_t header;
|
||||
unsigned long begin, end;
|
||||
unsigned char *buffer;
|
||||
unsigned int i;
|
||||
union {
|
||||
unsigned char *bytes;
|
||||
uint16_t *short_offsets;
|
||||
uint32_t *long_offsets;
|
||||
} u;
|
||||
|
||||
size = sizeof (tt_head_t);
|
||||
font->backend->load_truetype_table (font->scaled_font_subset->scaled_font,
|
||||
TT_TAG_head, 0, (unsigned char*) &header, &size);
|
||||
|
||||
if (be16_to_cpu (header.index_to_loc_format) == 0)
|
||||
size = sizeof (int16_t) * (font->num_glyphs_in_face + 1);
|
||||
else
|
||||
size = sizeof (int32_t) * (font->num_glyphs_in_face + 1);
|
||||
|
||||
u.bytes = malloc (size);
|
||||
if (u.bytes == NULL) {
|
||||
font->status = CAIRO_STATUS_NO_MEMORY;
|
||||
return font->status;
|
||||
}
|
||||
if (font->backend->load_truetype_table (font->scaled_font_subset->scaled_font,
|
||||
TT_TAG_loca, 0, u.bytes, &size) != CAIRO_STATUS_SUCCESS) {
|
||||
font->status = CAIRO_INT_STATUS_UNSUPPORTED;
|
||||
return font->status;
|
||||
}
|
||||
|
||||
start_offset = _cairo_array_num_elements (&font->output);
|
||||
for (i = 0; i < font->base.num_glyphs; i++) {
|
||||
index = font->glyphs[i].parent_index;
|
||||
if (be16_to_cpu (header.index_to_loc_format) == 0) {
|
||||
begin = be16_to_cpu (u.short_offsets[index]) * 2;
|
||||
end = be16_to_cpu (u.short_offsets[index + 1]) * 2;
|
||||
}
|
||||
else {
|
||||
begin = be32_to_cpu (u.long_offsets[index]);
|
||||
end = be32_to_cpu (u.long_offsets[index + 1]);
|
||||
}
|
||||
|
||||
size = end - begin;
|
||||
|
||||
next = cairo_truetype_font_align_output (font);
|
||||
cairo_truetype_font_check_boundary (font, next);
|
||||
font->glyphs[i].location = next - start_offset;
|
||||
|
||||
status = cairo_truetype_font_allocate_write_buffer (font, size, &buffer);
|
||||
if (status)
|
||||
break;
|
||||
if (size != 0) {
|
||||
font->backend->load_truetype_table (font->scaled_font_subset->scaled_font,
|
||||
TT_TAG_glyf, begin, buffer, &size);
|
||||
cairo_truetype_font_remap_composite_glyph (font, buffer);
|
||||
}
|
||||
}
|
||||
|
||||
font->glyphs[i].location =
|
||||
cairo_truetype_font_align_output (font) - start_offset;
|
||||
|
||||
free (u.bytes);
|
||||
|
||||
return font->status;
|
||||
}
|
||||
|
||||
static int
|
||||
cairo_truetype_font_write_head_table (cairo_truetype_font_t *font,
|
||||
unsigned long tag)
|
||||
{
|
||||
unsigned char *buffer;
|
||||
unsigned long size;
|
||||
|
||||
size = 0;
|
||||
font->backend->load_truetype_table (font->scaled_font_subset->scaled_font,
|
||||
tag, 0, NULL, &size);
|
||||
font->checksum_index = _cairo_array_num_elements (&font->output) + 8;
|
||||
font->status = cairo_truetype_font_allocate_write_buffer (font, size, &buffer);
|
||||
font->backend->load_truetype_table( font->scaled_font_subset->scaled_font,
|
||||
tag, 0, buffer, &size);
|
||||
return font->status;
|
||||
}
|
||||
|
||||
static int cairo_truetype_font_write_hhea_table (cairo_truetype_font_t *font, unsigned long tag)
|
||||
{
|
||||
tt_hhea_t *hhea;
|
||||
unsigned long size;
|
||||
|
||||
size = sizeof (tt_hhea_t);
|
||||
font->status = cairo_truetype_font_allocate_write_buffer (font, size, (unsigned char **) &hhea);
|
||||
font->backend->load_truetype_table (font->scaled_font_subset->scaled_font,
|
||||
tag, 0, (unsigned char *) hhea, &size);
|
||||
hhea->num_hmetrics = cpu_to_be16 ((uint16_t)(font->base.num_glyphs));
|
||||
return font->status;
|
||||
}
|
||||
|
||||
static int
|
||||
cairo_truetype_font_write_hmtx_table (cairo_truetype_font_t *font,
|
||||
unsigned long tag)
|
||||
{
|
||||
cairo_status_t status;
|
||||
unsigned long size;
|
||||
unsigned long long_entry_size;
|
||||
unsigned long short_entry_size;
|
||||
short *p;
|
||||
unsigned int i;
|
||||
tt_hhea_t hhea;
|
||||
int num_hmetrics;
|
||||
|
||||
size = sizeof (tt_hhea_t);
|
||||
font->backend->load_truetype_table (font->scaled_font_subset->scaled_font,
|
||||
TT_TAG_hhea, 0, (unsigned char*) &hhea, &size);
|
||||
num_hmetrics = be16_to_cpu(hhea.num_hmetrics);
|
||||
|
||||
for (i = 0; i < font->base.num_glyphs; i++) {
|
||||
long_entry_size = 2 * sizeof (int16_t);
|
||||
short_entry_size = sizeof (int16_t);
|
||||
status = cairo_truetype_font_allocate_write_buffer (font, long_entry_size,
|
||||
(unsigned char **) &p);
|
||||
if (font->glyphs[i].parent_index < num_hmetrics) {
|
||||
if (font->backend->load_truetype_table (font->scaled_font_subset->scaled_font,
|
||||
TT_TAG_hmtx,
|
||||
font->glyphs[i].parent_index * long_entry_size,
|
||||
(unsigned char *) p, &long_entry_size) != CAIRO_STATUS_SUCCESS) {
|
||||
font->status = CAIRO_INT_STATUS_UNSUPPORTED;
|
||||
return font->status;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (font->backend->load_truetype_table (font->scaled_font_subset->scaled_font,
|
||||
TT_TAG_hmtx,
|
||||
(num_hmetrics - 1) * long_entry_size,
|
||||
(unsigned char *) p, &short_entry_size) != CAIRO_STATUS_SUCCESS) {
|
||||
font->status = CAIRO_INT_STATUS_UNSUPPORTED;
|
||||
return font->status;
|
||||
}
|
||||
font->backend->load_truetype_table (font->scaled_font_subset->scaled_font,
|
||||
TT_TAG_hmtx,
|
||||
(num_hmetrics - 1) * long_entry_size +
|
||||
(font->glyphs[i].parent_index - num_hmetrics)
|
||||
* short_entry_size,
|
||||
(unsigned char *) (p+1), &short_entry_size);
|
||||
}
|
||||
font->base.widths[i] = be16_to_cpu (p[0]);
|
||||
}
|
||||
|
||||
return font->status;
|
||||
}
|
||||
|
||||
static int
|
||||
cairo_truetype_font_write_loca_table (cairo_truetype_font_t *font,
|
||||
unsigned long tag)
|
||||
{
|
||||
unsigned int i;
|
||||
tt_head_t header;
|
||||
unsigned long size;
|
||||
|
||||
size = sizeof(tt_head_t);
|
||||
font->backend->load_truetype_table (font->scaled_font_subset->scaled_font,
|
||||
TT_TAG_head, 0, (unsigned char*) &header, &size);
|
||||
|
||||
if (be16_to_cpu (header.index_to_loc_format) == 0)
|
||||
{
|
||||
for (i = 0; i < font->base.num_glyphs + 1; i++)
|
||||
cairo_truetype_font_write_be16 (font, font->glyphs[i].location / 2);
|
||||
} else {
|
||||
for (i = 0; i < font->base.num_glyphs + 1; i++)
|
||||
cairo_truetype_font_write_be32 (font, font->glyphs[i].location);
|
||||
}
|
||||
|
||||
return font->status;
|
||||
}
|
||||
|
||||
static int
|
||||
cairo_truetype_font_write_maxp_table (cairo_truetype_font_t *font,
|
||||
unsigned long tag)
|
||||
{
|
||||
tt_maxp_t *maxp;
|
||||
unsigned long size;
|
||||
|
||||
size = sizeof (tt_maxp_t);
|
||||
font->status = cairo_truetype_font_allocate_write_buffer (font, size, (unsigned char **) &maxp);
|
||||
font->backend->load_truetype_table (font->scaled_font_subset->scaled_font,
|
||||
tag, 0, (unsigned char *) maxp, &size);
|
||||
maxp->num_glyphs = cpu_to_be16 (font->base.num_glyphs);
|
||||
return font->status;
|
||||
}
|
||||
|
||||
typedef struct table table_t;
|
||||
struct table {
|
||||
unsigned long tag;
|
||||
int (*write) (cairo_truetype_font_t *font, unsigned long tag);
|
||||
};
|
||||
|
||||
static const table_t truetype_tables[] = {
|
||||
/* As we write out the glyf table we remap composite glyphs.
|
||||
* Remapping composite glyphs will reference the sub glyphs the
|
||||
* composite glyph is made up of. That needs to be done first so
|
||||
* we have all the glyphs in the subset before going further. */
|
||||
{ TT_TAG_glyf, cairo_truetype_font_write_glyf_table },
|
||||
{ TT_TAG_cmap, cairo_truetype_font_write_cmap_table },
|
||||
{ TT_TAG_cvt, cairo_truetype_font_write_generic_table },
|
||||
{ TT_TAG_fpgm, cairo_truetype_font_write_generic_table },
|
||||
{ TT_TAG_head, cairo_truetype_font_write_head_table },
|
||||
{ TT_TAG_hhea, cairo_truetype_font_write_hhea_table },
|
||||
{ TT_TAG_hmtx, cairo_truetype_font_write_hmtx_table },
|
||||
{ TT_TAG_loca, cairo_truetype_font_write_loca_table },
|
||||
{ TT_TAG_maxp, cairo_truetype_font_write_maxp_table },
|
||||
{ TT_TAG_name, cairo_truetype_font_write_generic_table },
|
||||
{ TT_TAG_prep, cairo_truetype_font_write_generic_table },
|
||||
};
|
||||
|
||||
static cairo_status_t
|
||||
cairo_truetype_font_write_offset_table (cairo_truetype_font_t *font)
|
||||
{
|
||||
cairo_status_t status;
|
||||
unsigned char *table_buffer;
|
||||
size_t table_buffer_length;
|
||||
unsigned short search_range, entry_selector, range_shift;
|
||||
int num_tables;
|
||||
|
||||
num_tables = ARRAY_LENGTH (truetype_tables);
|
||||
search_range = 1;
|
||||
entry_selector = 0;
|
||||
while (search_range * 2 <= num_tables) {
|
||||
search_range *= 2;
|
||||
entry_selector++;
|
||||
}
|
||||
search_range *= 16;
|
||||
range_shift = num_tables * 16 - search_range;
|
||||
|
||||
cairo_truetype_font_write_be32 (font, SFNT_VERSION);
|
||||
cairo_truetype_font_write_be16 (font, num_tables);
|
||||
cairo_truetype_font_write_be16 (font, search_range);
|
||||
cairo_truetype_font_write_be16 (font, entry_selector);
|
||||
cairo_truetype_font_write_be16 (font, range_shift);
|
||||
|
||||
/* Allocate space for the table directory. Each directory entry
|
||||
* will be filled in by cairo_truetype_font_update_entry() after
|
||||
* the table is written. */
|
||||
table_buffer_length = ARRAY_LENGTH (truetype_tables) * 16;
|
||||
status = cairo_truetype_font_allocate_write_buffer (font, table_buffer_length,
|
||||
&table_buffer);
|
||||
if (status)
|
||||
return status;
|
||||
|
||||
return font->status;
|
||||
}
|
||||
|
||||
static uint32_t
|
||||
cairo_truetype_font_calculate_checksum (cairo_truetype_font_t *font,
|
||||
unsigned long start,
|
||||
unsigned long end)
|
||||
{
|
||||
uint32_t *padded_end;
|
||||
uint32_t *p;
|
||||
uint32_t checksum;
|
||||
char *data;
|
||||
|
||||
checksum = 0;
|
||||
data = _cairo_array_index (&font->output, 0);
|
||||
p = (uint32_t *) (data + start);
|
||||
padded_end = (uint32_t *) (data + ((end + 3) & ~3));
|
||||
while (p < padded_end)
|
||||
checksum += *p++;
|
||||
|
||||
return checksum;
|
||||
}
|
||||
|
||||
static void
|
||||
cairo_truetype_font_update_entry (cairo_truetype_font_t *font,
|
||||
int index,
|
||||
unsigned long tag,
|
||||
unsigned long start,
|
||||
unsigned long end)
|
||||
{
|
||||
uint32_t *entry;
|
||||
|
||||
entry = _cairo_array_index (&font->output, 12 + 16 * index);
|
||||
entry[0] = cpu_to_be32 ((uint32_t)tag);
|
||||
entry[1] = cpu_to_be32 (cairo_truetype_font_calculate_checksum (font, start, end));
|
||||
entry[2] = cpu_to_be32 ((uint32_t)start);
|
||||
entry[3] = cpu_to_be32 ((uint32_t)(end - start));
|
||||
}
|
||||
|
||||
static cairo_status_t
|
||||
cairo_truetype_font_generate (cairo_truetype_font_t *font,
|
||||
const char **data,
|
||||
unsigned long *length,
|
||||
const unsigned long **string_offsets,
|
||||
unsigned long *num_strings)
|
||||
{
|
||||
unsigned long start, end, next;
|
||||
uint32_t checksum, *checksum_location;
|
||||
unsigned int i;
|
||||
|
||||
if (cairo_truetype_font_write_offset_table (font))
|
||||
goto fail;
|
||||
|
||||
start = cairo_truetype_font_align_output (font);
|
||||
end = start;
|
||||
|
||||
end = 0;
|
||||
for (i = 0; i < ARRAY_LENGTH (truetype_tables); i++) {
|
||||
if (truetype_tables[i].write (font, truetype_tables[i].tag))
|
||||
goto fail;
|
||||
|
||||
end = _cairo_array_num_elements (&font->output);
|
||||
next = cairo_truetype_font_align_output (font);
|
||||
cairo_truetype_font_update_entry (font, i, truetype_tables[i].tag,
|
||||
start, end);
|
||||
cairo_truetype_font_check_boundary (font, next);
|
||||
start = next;
|
||||
}
|
||||
|
||||
checksum =
|
||||
0xb1b0afba - cairo_truetype_font_calculate_checksum (font, 0, end);
|
||||
checksum_location = _cairo_array_index (&font->output, font->checksum_index);
|
||||
*checksum_location = cpu_to_be32 (checksum);
|
||||
|
||||
*data = _cairo_array_index (&font->output, 0);
|
||||
*length = _cairo_array_num_elements (&font->output);
|
||||
*num_strings = _cairo_array_num_elements (&font->string_offsets);
|
||||
if (*num_strings != 0)
|
||||
*string_offsets = _cairo_array_index (&font->string_offsets, 0);
|
||||
else
|
||||
*string_offsets = NULL;
|
||||
|
||||
fail:
|
||||
return font->status;
|
||||
}
|
||||
|
||||
static int
|
||||
cairo_truetype_font_use_glyph (cairo_truetype_font_t *font, int glyph)
|
||||
{
|
||||
if (font->parent_to_subset[glyph] == 0) {
|
||||
font->parent_to_subset[glyph] = font->base.num_glyphs;
|
||||
font->glyphs[font->base.num_glyphs].parent_index = glyph;
|
||||
font->base.num_glyphs++;
|
||||
}
|
||||
|
||||
return font->parent_to_subset[glyph];
|
||||
}
|
||||
|
||||
cairo_status_t
|
||||
_cairo_truetype_subset_init (cairo_truetype_subset_t *truetype_subset,
|
||||
cairo_scaled_font_subset_t *font_subset)
|
||||
{
|
||||
cairo_truetype_font_t *font;
|
||||
cairo_status_t status;
|
||||
const char *data = NULL; /* squelch bogus compiler warning */
|
||||
unsigned long length = 0; /* squelch bogus compiler warning */
|
||||
unsigned long parent_glyph, offsets_length;
|
||||
unsigned int i;
|
||||
const unsigned long *string_offsets = NULL;
|
||||
unsigned long num_strings = 0;
|
||||
|
||||
status = _cairo_truetype_font_create (font_subset, &font);
|
||||
if (status)
|
||||
return status;
|
||||
|
||||
for (i = 0; i < font->scaled_font_subset->num_glyphs; i++) {
|
||||
parent_glyph = font->scaled_font_subset->glyphs[i];
|
||||
cairo_truetype_font_use_glyph (font, parent_glyph);
|
||||
}
|
||||
|
||||
status = cairo_truetype_font_generate (font, &data, &length,
|
||||
&string_offsets, &num_strings);
|
||||
if (status)
|
||||
goto fail1;
|
||||
|
||||
truetype_subset->base_font = strdup (font->base.base_font);
|
||||
if (truetype_subset->base_font == NULL)
|
||||
goto fail1;
|
||||
|
||||
truetype_subset->widths = calloc (sizeof (int), font->base.num_glyphs);
|
||||
if (truetype_subset->widths == NULL)
|
||||
goto fail2;
|
||||
for (i = 0; i < font->base.num_glyphs; i++)
|
||||
truetype_subset->widths[i] = font->base.widths[i];
|
||||
|
||||
truetype_subset->x_min = font->base.x_min;
|
||||
truetype_subset->y_min = font->base.y_min;
|
||||
truetype_subset->x_max = font->base.x_max;
|
||||
truetype_subset->y_max = font->base.y_max;
|
||||
truetype_subset->ascent = font->base.ascent;
|
||||
truetype_subset->descent = font->base.descent;
|
||||
|
||||
truetype_subset->data = malloc (length);
|
||||
if (truetype_subset->data == NULL)
|
||||
goto fail3;
|
||||
|
||||
memcpy (truetype_subset->data, data, length);
|
||||
truetype_subset->data_length = length;
|
||||
|
||||
offsets_length = num_strings * sizeof (unsigned long);
|
||||
truetype_subset->string_offsets = malloc (offsets_length);
|
||||
if (truetype_subset->string_offsets == NULL)
|
||||
goto fail4;
|
||||
|
||||
memcpy (truetype_subset->string_offsets, string_offsets, offsets_length);
|
||||
truetype_subset->num_string_offsets = num_strings;
|
||||
|
||||
cairo_truetype_font_destroy (font);
|
||||
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
|
||||
fail4:
|
||||
free (truetype_subset->data);
|
||||
fail3:
|
||||
free (truetype_subset->widths);
|
||||
fail2:
|
||||
free (truetype_subset->base_font);
|
||||
fail1:
|
||||
cairo_truetype_font_destroy (font);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
void
|
||||
_cairo_truetype_subset_fini (cairo_truetype_subset_t *subset)
|
||||
{
|
||||
free (subset->base_font);
|
||||
free (subset->widths);
|
||||
free (subset->data);
|
||||
free (subset->string_offsets);
|
||||
}
|
||||
|
|
@ -0,0 +1,746 @@
|
|||
/* cairo - a vector graphics library with display and print output
|
||||
*
|
||||
* Copyright © 2006 Red Hat, Inc
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it either under the terms of the GNU Lesser General Public
|
||||
* License version 2.1 as published by the Free Software Foundation
|
||||
* (the "LGPL") or, at your option, under the terms of the Mozilla
|
||||
* Public License Version 1.1 (the "MPL"). If you do not alter this
|
||||
* notice, a recipient may use your version of this file under either
|
||||
* the MPL or the LGPL.
|
||||
*
|
||||
* You should have received a copy of the LGPL along with this library
|
||||
* in the file COPYING-LGPL-2.1; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
* You should have received a copy of the MPL along with this library
|
||||
* in the file COPYING-MPL-1.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License
|
||||
* Version 1.1 (the "License"); you may not use this file except in
|
||||
* compliance with the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY
|
||||
* OF ANY KIND, either express or implied. See the LGPL or the MPL for
|
||||
* the specific language governing rights and limitations.
|
||||
*
|
||||
* The Original Code is the cairo graphics library.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Red Hat, Inc.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Adrian Johnson <ajohnson@redneon.com>
|
||||
*/
|
||||
|
||||
#include "cairoint.h"
|
||||
#include "cairo-scaled-font-subsets-private.h"
|
||||
#include "cairo-path-fixed-private.h"
|
||||
#include "cairo-output-stream-private.h"
|
||||
|
||||
typedef struct _cairo_type1_font {
|
||||
int *widths;
|
||||
|
||||
cairo_scaled_font_subset_t *scaled_font_subset;
|
||||
cairo_scaled_font_t *type1_scaled_font;
|
||||
|
||||
cairo_array_t contents;
|
||||
|
||||
double x_min, y_min, x_max, y_max;
|
||||
|
||||
const char *data;
|
||||
unsigned long header_size;
|
||||
unsigned long data_size;
|
||||
unsigned long trailer_size;
|
||||
int bbox_position;
|
||||
int bbox_max_chars;
|
||||
|
||||
cairo_output_stream_t *output;
|
||||
|
||||
unsigned short eexec_key;
|
||||
cairo_bool_t hex_encode;
|
||||
int hex_column;
|
||||
} cairo_type1_font_t;
|
||||
|
||||
static cairo_status_t
|
||||
cairo_type1_font_create (cairo_scaled_font_subset_t *scaled_font_subset,
|
||||
cairo_type1_font_t **subset_return)
|
||||
{
|
||||
cairo_type1_font_t *font;
|
||||
cairo_font_face_t *font_face;
|
||||
cairo_matrix_t font_matrix;
|
||||
cairo_matrix_t ctm;
|
||||
cairo_font_options_t font_options;
|
||||
|
||||
font = calloc (1, sizeof (cairo_type1_font_t));
|
||||
if (font == NULL)
|
||||
return CAIRO_STATUS_NO_MEMORY;
|
||||
|
||||
font->widths = calloc (scaled_font_subset->num_glyphs,
|
||||
sizeof (int));
|
||||
if (font->widths == NULL) {
|
||||
free (font);
|
||||
return CAIRO_STATUS_NO_MEMORY;
|
||||
}
|
||||
|
||||
font->scaled_font_subset = scaled_font_subset;
|
||||
|
||||
font_face = cairo_scaled_font_get_font_face (scaled_font_subset->scaled_font);
|
||||
|
||||
cairo_matrix_init_scale (&font_matrix, 1000, 1000);
|
||||
cairo_matrix_init_identity (&ctm);
|
||||
|
||||
_cairo_font_options_init_default (&font_options);
|
||||
cairo_font_options_set_hint_style (&font_options, CAIRO_HINT_STYLE_NONE);
|
||||
cairo_font_options_set_hint_metrics (&font_options, CAIRO_HINT_METRICS_OFF);
|
||||
|
||||
font->type1_scaled_font = cairo_scaled_font_create (font_face,
|
||||
&font_matrix,
|
||||
&ctm,
|
||||
&font_options);
|
||||
|
||||
_cairo_array_init (&font->contents, sizeof (unsigned char));
|
||||
|
||||
*subset_return = font;
|
||||
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
/* Magic constants for the type1 eexec encryption */
|
||||
static const unsigned short encrypt_c1 = 52845, encrypt_c2 = 22719;
|
||||
static const unsigned short private_dict_key = 55665;
|
||||
static const unsigned short charstring_key = 4330;
|
||||
|
||||
/* Charstring commands. If the high byte is 0 the command is encoded
|
||||
* with a single byte. */
|
||||
#define CHARSTRING_sbw 0x0c07
|
||||
#define CHARSTRING_rmoveto 0x0015
|
||||
#define CHARSTRING_rlineto 0x0005
|
||||
#define CHARSTRING_rcurveto 0x0008
|
||||
#define CHARSTRING_closepath 0x0009
|
||||
#define CHARSTRING_endchar 0x000e
|
||||
|
||||
/* Before calling this function, the caller must allocate sufficient
|
||||
* space in data (see _cairo_array_grow_by). The maxium number of
|
||||
* bytes that will be used is 2.
|
||||
*/
|
||||
static void
|
||||
charstring_encode_command (cairo_array_t *data, int command)
|
||||
{
|
||||
cairo_status_t status;
|
||||
int orig_size;
|
||||
unsigned char buf[5];
|
||||
unsigned char *p = buf;
|
||||
|
||||
if (command & 0xff00)
|
||||
*p++ = command >> 8;
|
||||
*p++ = command & 0x00ff;
|
||||
|
||||
/* Ensure the array doesn't grow, which allows this function to
|
||||
* have no possibility of failure. */
|
||||
orig_size = _cairo_array_size (data);
|
||||
status = _cairo_array_append_multiple (data, buf, p - buf);
|
||||
|
||||
assert (status == CAIRO_STATUS_SUCCESS);
|
||||
assert (_cairo_array_size (data) == orig_size);
|
||||
}
|
||||
|
||||
/* Before calling this function, the caller must allocate sufficient
|
||||
* space in data (see _cairo_array_grow_by). The maxium number of
|
||||
* bytes that will be used is 5.
|
||||
*/
|
||||
static void
|
||||
charstring_encode_integer (cairo_array_t *data, int i)
|
||||
{
|
||||
cairo_status_t status;
|
||||
int orig_size;
|
||||
unsigned char buf[10];
|
||||
unsigned char *p = buf;
|
||||
|
||||
if (i >= -107 && i <= 107) {
|
||||
*p++ = i + 139;
|
||||
} else if (i >= 108 && i <= 1131) {
|
||||
i -= 108;
|
||||
*p++ = (i >> 8)+ 247;
|
||||
*p++ = i & 0xff;
|
||||
} else if (i >= -1131 && i <= -108) {
|
||||
i = -i - 108;
|
||||
*p++ = (i >> 8)+ 251;
|
||||
*p++ = i & 0xff;
|
||||
} else {
|
||||
*p++ = 0xff;
|
||||
*p++ = i >> 24;
|
||||
*p++ = (i >> 16) & 0xff;
|
||||
*p++ = (i >> 8) & 0xff;
|
||||
*p++ = i & 0xff;
|
||||
}
|
||||
|
||||
/* Ensure the array doesn't grow, which allows this function to
|
||||
* have no possibility of failure. */
|
||||
orig_size = _cairo_array_size (data);
|
||||
status = _cairo_array_append_multiple (data, buf, p - buf);
|
||||
|
||||
assert (status == CAIRO_STATUS_SUCCESS);
|
||||
assert (_cairo_array_size (data) == orig_size);
|
||||
}
|
||||
|
||||
typedef struct _ps_path_info {
|
||||
cairo_array_t *data;
|
||||
int current_x, current_y;
|
||||
} t1_path_info_t;
|
||||
|
||||
static cairo_status_t
|
||||
_charstring_move_to (void *closure,
|
||||
cairo_point_t *point)
|
||||
{
|
||||
t1_path_info_t *path_info = (t1_path_info_t *) closure;
|
||||
int dx, dy;
|
||||
cairo_status_t status;
|
||||
|
||||
status = _cairo_array_grow_by (path_info->data, 12);
|
||||
if (status)
|
||||
return status;
|
||||
|
||||
dx = _cairo_fixed_integer_part (point->x) - path_info->current_x;
|
||||
dy = _cairo_fixed_integer_part (point->y) - path_info->current_y;
|
||||
charstring_encode_integer (path_info->data, dx);
|
||||
charstring_encode_integer (path_info->data, dy);
|
||||
path_info->current_x += dx;
|
||||
path_info->current_y += dy;
|
||||
|
||||
charstring_encode_command (path_info->data, CHARSTRING_rmoveto);
|
||||
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
static cairo_status_t
|
||||
_charstring_line_to (void *closure,
|
||||
cairo_point_t *point)
|
||||
{
|
||||
t1_path_info_t *path_info = (t1_path_info_t *) closure;
|
||||
int dx, dy;
|
||||
cairo_status_t status;
|
||||
|
||||
status = _cairo_array_grow_by (path_info->data, 12);
|
||||
if (status)
|
||||
return status;
|
||||
|
||||
dx = _cairo_fixed_integer_part (point->x) - path_info->current_x;
|
||||
dy = _cairo_fixed_integer_part (point->y) - path_info->current_y;
|
||||
charstring_encode_integer (path_info->data, dx);
|
||||
charstring_encode_integer (path_info->data, dy);
|
||||
path_info->current_x += dx;
|
||||
path_info->current_y += dy;
|
||||
|
||||
charstring_encode_command (path_info->data, CHARSTRING_rlineto);
|
||||
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
static cairo_status_t
|
||||
_charstring_curve_to (void *closure,
|
||||
cairo_point_t *point1,
|
||||
cairo_point_t *point2,
|
||||
cairo_point_t *point3)
|
||||
{
|
||||
t1_path_info_t *path_info = (t1_path_info_t *) closure;
|
||||
int dx1, dy1, dx2, dy2, dx3, dy3;
|
||||
cairo_status_t status;
|
||||
|
||||
status = _cairo_array_grow_by (path_info->data, 32);
|
||||
if (status)
|
||||
return status;
|
||||
|
||||
dx1 = _cairo_fixed_integer_part (point1->x) - path_info->current_x;
|
||||
dy1 = _cairo_fixed_integer_part (point1->y) - path_info->current_y;
|
||||
dx2 = _cairo_fixed_integer_part (point2->x) - path_info->current_x - dx1;
|
||||
dy2 = _cairo_fixed_integer_part (point2->y) - path_info->current_y - dy1;
|
||||
dx3 = _cairo_fixed_integer_part (point3->x) - path_info->current_x - dx1 - dx2;
|
||||
dy3 = _cairo_fixed_integer_part (point3->y) - path_info->current_y - dy1 - dy2;
|
||||
charstring_encode_integer (path_info->data, dx1);
|
||||
charstring_encode_integer (path_info->data, dy1);
|
||||
charstring_encode_integer (path_info->data, dx2);
|
||||
charstring_encode_integer (path_info->data, dy2);
|
||||
charstring_encode_integer (path_info->data, dx3);
|
||||
charstring_encode_integer (path_info->data, dy3);
|
||||
path_info->current_x += dx1 + dx2 + dx3;
|
||||
path_info->current_y += dy1 + dy2 + dy3;
|
||||
charstring_encode_command (path_info->data, CHARSTRING_rcurveto);
|
||||
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
static cairo_status_t
|
||||
_charstring_close_path (void *closure)
|
||||
{
|
||||
cairo_status_t status;
|
||||
t1_path_info_t *path_info = (t1_path_info_t *) closure;
|
||||
|
||||
status = _cairo_array_grow_by (path_info->data, 2);
|
||||
if (status)
|
||||
return status;
|
||||
|
||||
charstring_encode_command (path_info->data, CHARSTRING_closepath);
|
||||
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
static void
|
||||
charstring_encrypt (cairo_array_t *data)
|
||||
{
|
||||
unsigned char *d, *end;
|
||||
uint16_t c, p, r;
|
||||
|
||||
r = charstring_key;
|
||||
d = (unsigned char *) _cairo_array_index (data, 0);
|
||||
end = d + _cairo_array_num_elements (data);
|
||||
while (d < end) {
|
||||
p = *d;
|
||||
c = p ^ (r >> 8);
|
||||
r = (c + r) * encrypt_c1 + encrypt_c2;
|
||||
*d++ = c;
|
||||
}
|
||||
}
|
||||
|
||||
static cairo_int_status_t
|
||||
create_notdef_charstring (cairo_array_t *data)
|
||||
{
|
||||
cairo_status_t status;
|
||||
|
||||
/* We're passing constants below, so we know the 0 values will
|
||||
* only use 1 byte each, and the 500 values will use 2 bytes
|
||||
* each. Then 2 more for each of the commands is 10 total. */
|
||||
status = _cairo_array_grow_by (data, 10);
|
||||
if (status)
|
||||
return status;
|
||||
|
||||
charstring_encode_integer (data, 0);
|
||||
charstring_encode_integer (data, 0);
|
||||
|
||||
/* The width and height is arbitrary. */
|
||||
charstring_encode_integer (data, 500);
|
||||
charstring_encode_integer (data, 500);
|
||||
charstring_encode_command (data, CHARSTRING_sbw);
|
||||
|
||||
charstring_encode_command (data, CHARSTRING_endchar);
|
||||
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
static cairo_int_status_t
|
||||
cairo_type1_font_create_charstring (cairo_type1_font_t *font,
|
||||
int subset_index,
|
||||
int glyph_index,
|
||||
cairo_array_t *data)
|
||||
{
|
||||
cairo_int_status_t status;
|
||||
cairo_scaled_glyph_t *scaled_glyph;
|
||||
t1_path_info_t path_info;
|
||||
cairo_text_extents_t *metrics;
|
||||
|
||||
/* This call may return CAIRO_INT_STATUS_UNSUPPORTED for bitmap fonts. */
|
||||
status = _cairo_scaled_glyph_lookup (font->type1_scaled_font,
|
||||
glyph_index,
|
||||
CAIRO_SCALED_GLYPH_INFO_METRICS|
|
||||
CAIRO_SCALED_GLYPH_INFO_PATH,
|
||||
&scaled_glyph);
|
||||
if (status)
|
||||
return status;
|
||||
|
||||
metrics = &scaled_glyph->metrics;
|
||||
if (subset_index == 0) {
|
||||
font->x_min = metrics->x_bearing;
|
||||
font->y_min = metrics->y_bearing;
|
||||
font->x_max = metrics->x_bearing + metrics->width;
|
||||
font->y_max = metrics->y_bearing + metrics->height;
|
||||
} else {
|
||||
if (metrics->x_bearing < font->x_min)
|
||||
font->x_min = metrics->x_bearing;
|
||||
if (metrics->y_bearing < font->y_min)
|
||||
font->y_min = metrics->y_bearing;
|
||||
if (metrics->x_bearing + metrics->width > font->x_max)
|
||||
font->x_max = metrics->x_bearing + metrics->width;
|
||||
if (metrics->y_bearing + metrics->height > font->y_max)
|
||||
font->y_max = metrics->y_bearing + metrics->height;
|
||||
}
|
||||
font->widths[subset_index] = metrics->width;
|
||||
|
||||
status = _cairo_array_grow_by (data, 30);
|
||||
if (status)
|
||||
return status;
|
||||
|
||||
charstring_encode_integer (data, (int) scaled_glyph->metrics.x_bearing);
|
||||
charstring_encode_integer (data, (int) scaled_glyph->metrics.y_bearing);
|
||||
charstring_encode_integer (data, (int) scaled_glyph->metrics.width);
|
||||
charstring_encode_integer (data, (int) scaled_glyph->metrics.height);
|
||||
charstring_encode_command (data, CHARSTRING_sbw);
|
||||
|
||||
path_info.data = data;
|
||||
path_info.current_x = (int) scaled_glyph->metrics.x_bearing;
|
||||
path_info.current_y = (int) scaled_glyph->metrics.y_bearing;
|
||||
_cairo_path_fixed_interpret (scaled_glyph->path,
|
||||
CAIRO_DIRECTION_FORWARD,
|
||||
_charstring_move_to,
|
||||
_charstring_line_to,
|
||||
_charstring_curve_to,
|
||||
_charstring_close_path,
|
||||
&path_info);
|
||||
|
||||
charstring_encode_command (path_info.data, CHARSTRING_endchar);
|
||||
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
static cairo_int_status_t
|
||||
cairo_type1_font_write_charstrings (cairo_type1_font_t *font,
|
||||
cairo_output_stream_t *encrypted_output)
|
||||
{
|
||||
cairo_status_t status = CAIRO_STATUS_SUCCESS;
|
||||
unsigned char zeros[] = { 0, 0, 0, 0 };
|
||||
cairo_array_t data;
|
||||
unsigned int i;
|
||||
int length;
|
||||
|
||||
_cairo_array_init (&data, sizeof (unsigned char));
|
||||
status = _cairo_array_grow_by (&data, 1024);
|
||||
if (status)
|
||||
goto fail;
|
||||
|
||||
_cairo_output_stream_printf (encrypted_output,
|
||||
"2 index /CharStrings %d dict dup begin\n",
|
||||
font->scaled_font_subset->num_glyphs + 1);
|
||||
|
||||
for (i = 0; i < font->scaled_font_subset->num_glyphs; i++) {
|
||||
_cairo_array_truncate (&data, 0);
|
||||
/* four "random" bytes required by encryption algorithm */
|
||||
_cairo_array_append_multiple (&data, zeros, 4);
|
||||
status = cairo_type1_font_create_charstring (font, i,
|
||||
font->scaled_font_subset->glyphs[i],
|
||||
&data);
|
||||
if (status)
|
||||
goto fail;
|
||||
charstring_encrypt (&data);
|
||||
length = _cairo_array_num_elements (&data);
|
||||
_cairo_output_stream_printf (encrypted_output, "/g%d %d RD ", i, length);
|
||||
_cairo_output_stream_write (encrypted_output,
|
||||
_cairo_array_index (&data, 0),
|
||||
length);
|
||||
_cairo_output_stream_printf (encrypted_output, " ND\n");
|
||||
}
|
||||
|
||||
/* All type 1 fonts must have a /.notdef charstring */
|
||||
|
||||
_cairo_array_truncate (&data, 0);
|
||||
/* four "random" bytes required by encryption algorithm */
|
||||
_cairo_array_append_multiple (&data, zeros, 4);
|
||||
create_notdef_charstring (&data);
|
||||
charstring_encrypt (&data);
|
||||
length = _cairo_array_num_elements (&data);
|
||||
_cairo_output_stream_printf (encrypted_output, "/.notdef %d RD ", length);
|
||||
_cairo_output_stream_write (encrypted_output,
|
||||
_cairo_array_index (&data, 0),
|
||||
length);
|
||||
_cairo_output_stream_printf (encrypted_output, " ND\n");
|
||||
|
||||
fail:
|
||||
_cairo_array_fini (&data);
|
||||
return status;
|
||||
}
|
||||
|
||||
static cairo_status_t
|
||||
cairo_type1_font_write_header (cairo_type1_font_t *font,
|
||||
const char *name)
|
||||
{
|
||||
cairo_matrix_t matrix;
|
||||
unsigned int i;
|
||||
const char spaces[50] = " ";
|
||||
|
||||
matrix = font->type1_scaled_font->scale;
|
||||
matrix.xy = -matrix.xy;
|
||||
matrix.yy = -matrix.yy;
|
||||
cairo_matrix_invert (&matrix);
|
||||
|
||||
_cairo_output_stream_printf (font->output,
|
||||
"%%!FontType1-1.1 %s 1.0\n"
|
||||
"11 dict begin\n"
|
||||
"/FontName /%s def\n"
|
||||
"/PaintType 0 def\n"
|
||||
"/FontType 1 def\n"
|
||||
"/FontMatrix [%f %f %f %f 0 0] readonly def\n",
|
||||
name,
|
||||
name,
|
||||
matrix.xx,
|
||||
matrix.yx,
|
||||
matrix.xy,
|
||||
matrix.yy);
|
||||
|
||||
/* We don't know the bbox values until after the charstrings have
|
||||
* been generated. Reserve some space and fill in the bbox
|
||||
* later. */
|
||||
|
||||
/* Worst case for four signed ints with spaces between each number */
|
||||
font->bbox_max_chars = 50;
|
||||
|
||||
_cairo_output_stream_printf (font->output, "/FontBBox {");
|
||||
font->bbox_position = _cairo_output_stream_get_position (font->output);
|
||||
_cairo_output_stream_write (font->output, spaces, font->bbox_max_chars);
|
||||
|
||||
_cairo_output_stream_printf (font->output,
|
||||
"} readonly def\n"
|
||||
"/Encoding 256 array\n"
|
||||
"0 1 255 {1 index exch /.notdef put} for\n");
|
||||
for (i = 0; i < font->scaled_font_subset->num_glyphs; i++)
|
||||
_cairo_output_stream_printf (font->output, "dup %d /g%d put\n", i, i);
|
||||
_cairo_output_stream_printf (font->output,
|
||||
"readonly def\n"
|
||||
"currentdict end\n"
|
||||
"currentfile eexec\n");
|
||||
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
static cairo_status_t
|
||||
cairo_type1_write_stream_encrypted (void *closure,
|
||||
const unsigned char *data,
|
||||
unsigned int length)
|
||||
{
|
||||
const unsigned char *in, *end;
|
||||
uint16_t c, p;
|
||||
static const char hex_digits[16] = "0123456789abcdef";
|
||||
char digits[3];
|
||||
cairo_type1_font_t *font = closure;
|
||||
|
||||
in = (const unsigned char *) data;
|
||||
end = (const unsigned char *) data + length;
|
||||
while (in < end) {
|
||||
p = *in++;
|
||||
c = p ^ (font->eexec_key >> 8);
|
||||
font->eexec_key = (c + font->eexec_key) * encrypt_c1 + encrypt_c2;
|
||||
|
||||
if (font->hex_encode) {
|
||||
digits[0] = hex_digits[c >> 4];
|
||||
digits[1] = hex_digits[c & 0x0f];
|
||||
digits[2] = '\n';
|
||||
font->hex_column += 2;
|
||||
|
||||
if (font->hex_column == 78) {
|
||||
_cairo_output_stream_write (font->output, digits, 3);
|
||||
font->hex_column = 0;
|
||||
} else {
|
||||
_cairo_output_stream_write (font->output, digits, 2);
|
||||
}
|
||||
} else {
|
||||
digits[0] = c;
|
||||
_cairo_output_stream_write (font->output, digits, 1);
|
||||
}
|
||||
}
|
||||
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
static cairo_int_status_t
|
||||
cairo_type1_font_write_private_dict (cairo_type1_font_t *font,
|
||||
const char *name)
|
||||
{
|
||||
cairo_int_status_t status;
|
||||
cairo_output_stream_t *encrypted_output;
|
||||
|
||||
font->eexec_key = private_dict_key;
|
||||
font->hex_encode = TRUE;
|
||||
font->hex_column = 0;
|
||||
encrypted_output = _cairo_output_stream_create (
|
||||
cairo_type1_write_stream_encrypted,
|
||||
NULL,
|
||||
font);
|
||||
if (encrypted_output == NULL)
|
||||
goto fail;
|
||||
|
||||
/* Note: the first four spaces at the start of this private dict
|
||||
* are the four "random" bytes of plaintext required by the
|
||||
* encryption algorithm */
|
||||
_cairo_output_stream_printf (encrypted_output,
|
||||
" dup /Private 9 dict dup begin\n"
|
||||
"/RD {string currentfile exch readstring pop}"
|
||||
" executeonly def\n"
|
||||
"/ND {noaccess def} executeonly def\n"
|
||||
"/NP {noaccess put} executeonly def\n"
|
||||
"/BlueValues [] def\n"
|
||||
"/MinFeature {16 16} def\n"
|
||||
"/lenIV 4 def\n"
|
||||
"/password 5839 def\n");
|
||||
|
||||
status = cairo_type1_font_write_charstrings (font, encrypted_output);
|
||||
if (status)
|
||||
goto fail;
|
||||
|
||||
_cairo_output_stream_printf (encrypted_output,
|
||||
"end\n"
|
||||
"end\n"
|
||||
"readonly put\n"
|
||||
"noaccess put\n"
|
||||
"dup /FontName get exch definefont pop\n"
|
||||
"mark currentfile closefile\n");
|
||||
|
||||
if (status == CAIRO_STATUS_SUCCESS)
|
||||
status = _cairo_output_stream_get_status (encrypted_output);
|
||||
fail:
|
||||
_cairo_output_stream_destroy (encrypted_output);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
static cairo_status_t
|
||||
cairo_type1_font_write_trailer(cairo_type1_font_t *font)
|
||||
{
|
||||
int i;
|
||||
static const char zeros[65] =
|
||||
"0000000000000000000000000000000000000000000000000000000000000000\n";
|
||||
|
||||
for (i = 0; i < 8; i++)
|
||||
_cairo_output_stream_write (font->output, zeros, sizeof zeros);
|
||||
|
||||
_cairo_output_stream_printf (font->output, "cleartomark\n");
|
||||
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
static cairo_status_t
|
||||
cairo_type1_write_stream (void *closure,
|
||||
const unsigned char *data,
|
||||
unsigned int length)
|
||||
{
|
||||
cairo_type1_font_t *font = closure;
|
||||
|
||||
return _cairo_array_append_multiple (&font->contents, data, length);
|
||||
}
|
||||
|
||||
static cairo_int_status_t
|
||||
cairo_type1_font_write (cairo_type1_font_t *font,
|
||||
const char *name)
|
||||
{
|
||||
cairo_int_status_t status;
|
||||
|
||||
cairo_type1_font_write_header (font, name);
|
||||
font->header_size = _cairo_output_stream_get_position (font->output);
|
||||
|
||||
status = cairo_type1_font_write_private_dict (font, name);
|
||||
if (status)
|
||||
return status;
|
||||
|
||||
font->data_size = _cairo_output_stream_get_position (font->output) -
|
||||
font->header_size;
|
||||
|
||||
cairo_type1_font_write_trailer (font);
|
||||
font->trailer_size =
|
||||
_cairo_output_stream_get_position (font->output) -
|
||||
font->header_size - font->data_size;
|
||||
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
static cairo_int_status_t
|
||||
cairo_type1_font_generate (cairo_type1_font_t *font, const char *name)
|
||||
{
|
||||
cairo_int_status_t status;
|
||||
|
||||
status = _cairo_array_grow_by (&font->contents, 4096);
|
||||
if (status)
|
||||
return status;
|
||||
|
||||
font->output = _cairo_output_stream_create (cairo_type1_write_stream, NULL, font);
|
||||
|
||||
status = cairo_type1_font_write (font, name);
|
||||
if (status)
|
||||
return status;
|
||||
|
||||
font->data = _cairo_array_index (&font->contents, 0);
|
||||
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
static void
|
||||
cairo_type1_font_destroy (cairo_type1_font_t *font)
|
||||
{
|
||||
free (font->widths);
|
||||
_cairo_array_fini (&font->contents);
|
||||
cairo_scaled_font_destroy (font->type1_scaled_font);
|
||||
free (font);
|
||||
}
|
||||
|
||||
cairo_status_t
|
||||
_cairo_type1_fallback_init (cairo_type1_subset_t *type1_subset,
|
||||
const char *name,
|
||||
cairo_scaled_font_subset_t *scaled_font_subset)
|
||||
{
|
||||
cairo_type1_font_t *font;
|
||||
cairo_status_t status;
|
||||
unsigned long length;
|
||||
unsigned int i, len;
|
||||
|
||||
status = cairo_type1_font_create (scaled_font_subset, &font);
|
||||
if (status)
|
||||
return status;
|
||||
|
||||
status = cairo_type1_font_generate (font, name);
|
||||
if (status)
|
||||
goto fail1;
|
||||
|
||||
type1_subset->base_font = strdup (name);
|
||||
if (type1_subset->base_font == NULL)
|
||||
goto fail1;
|
||||
|
||||
type1_subset->widths = calloc (sizeof (int), font->scaled_font_subset->num_glyphs);
|
||||
if (type1_subset->widths == NULL)
|
||||
goto fail2;
|
||||
for (i = 0; i < font->scaled_font_subset->num_glyphs; i++)
|
||||
type1_subset->widths[i] = font->widths[i];
|
||||
|
||||
type1_subset->x_min = (int) font->x_min;
|
||||
type1_subset->y_min = (int) font->y_min;
|
||||
type1_subset->x_max = (int) font->x_max;
|
||||
type1_subset->y_max = (int) font->y_max;
|
||||
type1_subset->ascent = (int) font->y_max;
|
||||
type1_subset->descent = (int) font->y_min;
|
||||
|
||||
length = font->header_size + font->data_size +
|
||||
font->trailer_size;
|
||||
type1_subset->data = malloc (length);
|
||||
if (type1_subset->data == NULL)
|
||||
goto fail3;
|
||||
|
||||
memcpy (type1_subset->data,
|
||||
_cairo_array_index (&font->contents, 0), length);
|
||||
|
||||
len = snprintf(type1_subset->data + font->bbox_position,
|
||||
font->bbox_max_chars,
|
||||
"%d %d %d %d",
|
||||
(int)type1_subset->x_min,
|
||||
(int)type1_subset->y_min,
|
||||
(int)type1_subset->x_max,
|
||||
(int)type1_subset->y_max);
|
||||
type1_subset->data[font->bbox_position + len] = ' ';
|
||||
|
||||
type1_subset->header_length = font->header_size;
|
||||
type1_subset->data_length = font->data_size;
|
||||
type1_subset->trailer_length = font->trailer_size;
|
||||
|
||||
cairo_type1_font_destroy (font);
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
|
||||
fail3:
|
||||
free (type1_subset->widths);
|
||||
fail2:
|
||||
free (type1_subset->base_font);
|
||||
fail1:
|
||||
cairo_type1_font_destroy (font);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
void
|
||||
_cairo_type1_fallback_fini (cairo_type1_subset_t *subset)
|
||||
{
|
||||
free (subset->base_font);
|
||||
free (subset->widths);
|
||||
free (subset->data);
|
||||
}
|
|
@ -53,7 +53,7 @@ typedef struct _cairo_type1_font_subset {
|
|||
cairo_unscaled_font_t *unscaled_font;
|
||||
unsigned int font_id;
|
||||
char *base_font;
|
||||
int num_glyphs;
|
||||
unsigned int num_glyphs;
|
||||
long x_min, y_min, x_max, y_max;
|
||||
long ascent, descent;
|
||||
|
||||
|
@ -103,7 +103,8 @@ typedef struct _cairo_type1_font_subset {
|
|||
|
||||
static cairo_status_t
|
||||
_cairo_type1_font_subset_create (cairo_unscaled_font_t *unscaled_font,
|
||||
cairo_type1_font_subset_t **subset_return)
|
||||
cairo_type1_font_subset_t **subset_return,
|
||||
cairo_bool_t hex_encode)
|
||||
{
|
||||
cairo_ft_unscaled_font_t *ft_unscaled_font;
|
||||
FT_Face face;
|
||||
|
@ -145,6 +146,7 @@ _cairo_type1_font_subset_create (cairo_unscaled_font_t *unscaled_font,
|
|||
if (font->glyphs == NULL)
|
||||
goto fail2;
|
||||
|
||||
font->hex_encode = hex_encode;
|
||||
font->num_glyphs = 0;
|
||||
for (i = 0; i < face->num_glyphs; i++)
|
||||
font->glyphs[i].subset_index = -1;
|
||||
|
@ -185,7 +187,7 @@ static const unsigned short charstring_key = 4330;
|
|||
static cairo_bool_t
|
||||
is_ps_delimiter(int c)
|
||||
{
|
||||
const static char delimiters[] = "()[]{}<>/% \t\r\n";
|
||||
static const char delimiters[] = "()[]{}<>/% \t\r\n";
|
||||
|
||||
return strchr (delimiters, c) != NULL;
|
||||
}
|
||||
|
@ -252,7 +254,7 @@ cairo_type1_font_subset_write_header (cairo_type1_font_subset_t *font,
|
|||
const char *name)
|
||||
{
|
||||
const char *start, *end, *segment_end;
|
||||
int i;
|
||||
unsigned int i;
|
||||
|
||||
segment_end = font->header_segment + font->header_segment_size;
|
||||
|
||||
|
@ -399,7 +401,7 @@ static int
|
|||
cairo_type1_font_subset_lookup_glyph (cairo_type1_font_subset_t *font,
|
||||
const char *glyph_name, int length)
|
||||
{
|
||||
int i;
|
||||
unsigned int i;
|
||||
|
||||
for (i = 0; i < font->base.num_glyphs; i++) {
|
||||
if (font->glyphs[i].name &&
|
||||
|
@ -414,7 +416,7 @@ cairo_type1_font_subset_lookup_glyph (cairo_type1_font_subset_t *font,
|
|||
static cairo_status_t
|
||||
cairo_type1_font_subset_get_glyph_names_and_widths (cairo_type1_font_subset_t *font)
|
||||
{
|
||||
int i;
|
||||
unsigned int i;
|
||||
char buffer[256];
|
||||
FT_Error error;
|
||||
|
||||
|
@ -481,45 +483,86 @@ cairo_type1_font_subset_decode_integer (const unsigned char *p, int *integer)
|
|||
}
|
||||
|
||||
static const char *ps_standard_encoding[256] = {
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0 */
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 16 */
|
||||
"space", "exclam", "quotedbl", "numbersign", /* 32 */
|
||||
"dollar", "percent", "ampersand", "quoteright",
|
||||
"parenleft", "parenright", "asterisk", "plus",
|
||||
"comma", "hyphen", "period", "slash",
|
||||
"zero", "one", "two", "three", /* 48 */
|
||||
"four", "five", "six", "seven", "eight",
|
||||
"nine", "colon", "semicolon", "less",
|
||||
"equal", "greater", "question", "at",
|
||||
"A", "B", "C", "D", "E", "F", "G", "H", /* 64 */
|
||||
"I", "J", "K", "L", "M", "N", "O", "P",
|
||||
"Q", "R", "S", "T", "U", "V", "W", "X", /* 80 */
|
||||
"Y", "Z", "bracketleft", "backslash",
|
||||
"bracketright", "asciicircum", "underscore", "quoteleft",
|
||||
"a", "b", "c", "d", "e", "f", "g", "h", /* 96 */
|
||||
"i", "j", "k", "l", "m", "n", "o", "p",
|
||||
"q", "r", "s", "t", "u", "v", "w", "x", /* 112 */
|
||||
"y", "z", "braceleft", "bar",
|
||||
"braceright", "asciitilde", 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 128 */
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 144 */
|
||||
"exclamdown", "cent", "sterling", "fraction",
|
||||
"yen", "florin", "section", "currency",
|
||||
"quotesingle", "quotedblleft", "guillemotleft", "guilsinglleft",
|
||||
"guilsinglright", "fi", "fl", NULL,
|
||||
"endash", "dagger", "daggerdbl", "periodcentered", /* 160 */
|
||||
NULL, "paragraph", "bullet", "quotesinglbase",
|
||||
"quotedblbase", "quotedblright", "guillemotright", "ellipsis",
|
||||
"perthousand", NULL, "questiondown", NULL,
|
||||
"grave", "acute", "circumflex", "tilde", /* 176 */
|
||||
"macron", "breve", "dotaccent", "dieresis",
|
||||
NULL, "ring", "cedilla", NULL,
|
||||
"hungarumlaut", "ogonek", "caron", "emdash",
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 192 */
|
||||
"AE", 0, "ordfeminine", 0, 0, 0, 0, "Lslash", /* 208 */
|
||||
"Oslash", "OE", "ordmasculine", 0, 0, 0, 0, 0,
|
||||
"ae", 0, 0, 0, "dotlessi", 0, 0, "lslash", /* 224 */
|
||||
"oslash", "oe", "germandbls", 0, 0, 0, 0
|
||||
/* 0 */
|
||||
NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL,
|
||||
/* 16 */
|
||||
NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL,
|
||||
/* 32 */
|
||||
"space", "exclam", "quotedbl", "numbersign",
|
||||
"dollar", "percent", "ampersand", "quoteright",
|
||||
"parenleft", "parenright", "asterisk", "plus",
|
||||
"comma", "hyphen", "period", "slash",
|
||||
/* 48 */
|
||||
"zero", "one", "two", "three",
|
||||
"four", "five", "six", "seven",
|
||||
"eight", "nine", "colon", "semicolon",
|
||||
"less", "equal", "greater", "question",
|
||||
/* 64 */
|
||||
"at", "A", "B", "C",
|
||||
"D", "E", "F", "G",
|
||||
"H", "I", "J", "K",
|
||||
"L", "M", "N", "O",
|
||||
/* 80 */
|
||||
"P", "Q", "R", "S",
|
||||
"T", "U", "V", "W",
|
||||
"X", "Y", "Z", "bracketleft",
|
||||
"backslash", "bracketright", "asciicircum", "underscore",
|
||||
/* 96 */
|
||||
"quoteleft", "a", "b", "c",
|
||||
"d", "e", "f", "g",
|
||||
"h", "i", "j", "k",
|
||||
"l", "m", "n", "o",
|
||||
/* 112 */
|
||||
"p", "q", "r", "s",
|
||||
"t", "u", "v", "w",
|
||||
"x", "y", "z", "braceleft",
|
||||
"bar", "braceright", "asciitilde", NULL,
|
||||
/* 128 */
|
||||
NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL,
|
||||
/* 144 */
|
||||
NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL,
|
||||
/* 160 */
|
||||
NULL, "exclamdown", "cent", "sterling",
|
||||
"fraction", "yen", "florin", "section",
|
||||
"currency", "quotesingle", "quotedblleft", "guillemotleft",
|
||||
"guilsinglleft","guilsinglright","fi", "fl",
|
||||
/* 176 */
|
||||
NULL, "endash", "dagger", "daggerdbl",
|
||||
"periodcentered",NULL, "paragraph", "bullet",
|
||||
"quotesinglbase","quotedblbase","quotedblright","guillemotright",
|
||||
"ellipsis", "perthousand", NULL, "questiondown",
|
||||
/* 192 */
|
||||
NULL, "grave", "acute", "circumflex",
|
||||
"tilde", "macron", "breve", "dotaccent",
|
||||
"dieresis", NULL, "ring", "cedilla",
|
||||
NULL, "hungarumlaut", "ogonek", "caron",
|
||||
/* 208 */
|
||||
"emdash", NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL,
|
||||
/* 224 */
|
||||
NULL, "AE", NULL, "ordfeminine",
|
||||
NULL, NULL, NULL, NULL,
|
||||
"Lslash", "Oslash", "OE", "ordmasculine",
|
||||
NULL, NULL, NULL, NULL,
|
||||
/* 240 */
|
||||
NULL, "ae", NULL, NULL,
|
||||
NULL, "dotlessi", NULL, NULL,
|
||||
"lslash", "oslash", "oe", "germandbls",
|
||||
NULL, NULL, NULL, NULL
|
||||
};
|
||||
|
||||
static void
|
||||
|
@ -859,7 +902,6 @@ cairo_type1_font_subset_write (cairo_type1_font_subset_t *font,
|
|||
}
|
||||
|
||||
font->eexec_key = private_dict_key;
|
||||
font->hex_encode = TRUE;
|
||||
font->hex_column = 0;
|
||||
|
||||
cairo_type1_font_subset_write_private_dict (font, name);
|
||||
|
@ -929,7 +971,7 @@ static void
|
|||
cairo_type1_font_subset_destroy (void *abstract_font)
|
||||
{
|
||||
cairo_type1_font_subset_t *font = abstract_font;
|
||||
int i;
|
||||
unsigned int i;
|
||||
|
||||
/* If the subset generation failed, some of the pointers below may
|
||||
* be NULL depending on at which point the error occurred. */
|
||||
|
@ -953,12 +995,13 @@ cairo_type1_font_subset_destroy (void *abstract_font)
|
|||
cairo_status_t
|
||||
_cairo_type1_subset_init (cairo_type1_subset_t *type1_subset,
|
||||
const char *name,
|
||||
cairo_scaled_font_subset_t *scaled_font_subset)
|
||||
cairo_scaled_font_subset_t *scaled_font_subset,
|
||||
cairo_bool_t hex_encode)
|
||||
{
|
||||
cairo_type1_font_subset_t *font;
|
||||
cairo_status_t status;
|
||||
unsigned long parent_glyph, length;
|
||||
int i;
|
||||
unsigned int i;
|
||||
cairo_unscaled_font_t *unscaled_font;
|
||||
|
||||
/* XXX: Need to fix this to work with a general cairo_unscaled_font_t. */
|
||||
|
@ -967,7 +1010,7 @@ _cairo_type1_subset_init (cairo_type1_subset_t *type1_subset,
|
|||
|
||||
unscaled_font = _cairo_ft_scaled_font_get_unscaled_font (scaled_font_subset->scaled_font);
|
||||
|
||||
status = _cairo_type1_font_subset_create (unscaled_font, &font);
|
||||
status = _cairo_type1_font_subset_create (unscaled_font, &font, hex_encode);
|
||||
if (status)
|
||||
return status;
|
||||
|
||||
|
@ -1038,4 +1081,3 @@ _cairo_type1_subset_fini (cairo_type1_subset_t *subset)
|
|||
free (subset->widths);
|
||||
free (subset->data);
|
||||
}
|
||||
|
||||
|
|
|
@ -50,6 +50,8 @@
|
|||
#define TT_PRIM_CSPLINE 3
|
||||
#endif
|
||||
|
||||
#define OPENTYPE_CFF_TAG 0x20464643
|
||||
|
||||
const cairo_scaled_font_backend_t cairo_win32_scaled_font_backend;
|
||||
|
||||
typedef struct {
|
||||
|
@ -97,6 +99,8 @@ typedef struct {
|
|||
HFONT scaled_hfont;
|
||||
HFONT unscaled_hfont;
|
||||
|
||||
cairo_bool_t glyph_indexing;
|
||||
|
||||
cairo_bool_t delete_scaled_hfont;
|
||||
} cairo_win32_scaled_font_t;
|
||||
|
||||
|
@ -233,6 +237,8 @@ _win32_scaled_font_create (LOGFONTW *logfont,
|
|||
cairo_matrix_t scale;
|
||||
cairo_status_t status;
|
||||
|
||||
_cairo_win32_initialize ();
|
||||
|
||||
f = malloc (sizeof(cairo_win32_scaled_font_t));
|
||||
if (f == NULL)
|
||||
return NULL;
|
||||
|
@ -464,6 +470,8 @@ _cairo_win32_scaled_font_create_toy (cairo_toy_font_face_t *toy_face,
|
|||
int face_name_len;
|
||||
cairo_status_t status;
|
||||
|
||||
_cairo_win32_initialize ();
|
||||
|
||||
status = _cairo_utf8_to_utf16 (toy_face->family, -1,
|
||||
&face_name, &face_name_len);
|
||||
if (status)
|
||||
|
@ -720,6 +728,12 @@ _cairo_win32_scaled_font_set_metrics (cairo_win32_scaled_font_t *scaled_font)
|
|||
|
||||
}
|
||||
|
||||
if ((metrics.tmPitchAndFamily & TMPF_TRUETYPE) ||
|
||||
(GetFontData (hdc, OPENTYPE_CFF_TAG, 0, NULL, 0) != GDI_ERROR))
|
||||
scaled_font->glyph_indexing = TRUE;
|
||||
else
|
||||
scaled_font->glyph_indexing = FALSE;
|
||||
|
||||
_cairo_scaled_font_set_metrics (&scaled_font->base, &extents);
|
||||
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
|
@ -734,12 +748,18 @@ _cairo_win32_scaled_font_init_glyph_metrics (cairo_win32_scaled_font_t *scaled_f
|
|||
cairo_status_t status;
|
||||
cairo_text_extents_t extents;
|
||||
HDC hdc;
|
||||
UINT glyph_index_option;
|
||||
|
||||
hdc = _get_global_font_dc ();
|
||||
if (!hdc)
|
||||
return CAIRO_STATUS_NO_MEMORY;
|
||||
|
||||
if (scaled_font->preserve_axes) {
|
||||
if (scaled_font->glyph_indexing)
|
||||
glyph_index_option = GGO_GLYPH_INDEX;
|
||||
else
|
||||
glyph_index_option = 0;
|
||||
|
||||
if (scaled_font->preserve_axes && scaled_font->base.options.hint_style != CAIRO_HINT_METRICS_OFF) {
|
||||
/* If we aren't rotating / skewing the axes, then we get the metrics
|
||||
* from the GDI in device space and convert to font space.
|
||||
*/
|
||||
|
@ -747,7 +767,7 @@ _cairo_win32_scaled_font_init_glyph_metrics (cairo_win32_scaled_font_t *scaled_f
|
|||
if (status)
|
||||
return status;
|
||||
if (GetGlyphOutlineW (hdc, _cairo_scaled_glyph_index (scaled_glyph),
|
||||
GGO_METRICS | GGO_GLYPH_INDEX,
|
||||
GGO_METRICS | glyph_index_option,
|
||||
&metrics, 0, NULL, &matrix) == GDI_ERROR) {
|
||||
status = _cairo_win32_print_gdi_error ("_cairo_win32_scaled_font_init_glyph_metrics:GetGlyphOutlineW");
|
||||
memset (&metrics, 0, sizeof (GLYPHMETRICS));
|
||||
|
@ -786,7 +806,7 @@ _cairo_win32_scaled_font_init_glyph_metrics (cairo_win32_scaled_font_t *scaled_f
|
|||
*/
|
||||
status = _cairo_win32_scaled_font_select_unscaled_font (&scaled_font->base, hdc);
|
||||
if (GetGlyphOutlineW (hdc, _cairo_scaled_glyph_index (scaled_glyph),
|
||||
GGO_METRICS | GGO_GLYPH_INDEX,
|
||||
GGO_METRICS | glyph_index_option,
|
||||
&metrics, 0, NULL, &matrix) == GDI_ERROR) {
|
||||
status = _cairo_win32_print_gdi_error ("_cairo_win32_scaled_font_init_glyph_metrics:GetGlyphOutlineW");
|
||||
memset (&metrics, 0, sizeof (GLYPHMETRICS));
|
||||
|
@ -829,6 +849,7 @@ _cairo_win32_scaled_font_glyph_bbox (void *abstract_font,
|
|||
GLYPHMETRICS metrics;
|
||||
cairo_status_t status;
|
||||
int i;
|
||||
UINT glyph_index_option;
|
||||
|
||||
if (!hdc)
|
||||
return CAIRO_STATUS_NO_MEMORY;
|
||||
|
@ -837,11 +858,16 @@ _cairo_win32_scaled_font_glyph_bbox (void *abstract_font,
|
|||
if (status)
|
||||
return status;
|
||||
|
||||
if (scaled_font->glyph_indexing)
|
||||
glyph_index_option = GGO_GLYPH_INDEX;
|
||||
else
|
||||
glyph_index_option = 0;
|
||||
|
||||
for (i = 0; i < num_glyphs; i++) {
|
||||
int x = floor (0.5 + glyphs[i].x);
|
||||
int y = floor (0.5 + glyphs[i].y);
|
||||
|
||||
GetGlyphOutlineW (hdc, glyphs[i].index, GGO_METRICS | GGO_GLYPH_INDEX,
|
||||
GetGlyphOutlineW (hdc, glyphs[i].index, GGO_METRICS | glyph_index_option,
|
||||
&metrics, 0, NULL, &matrix);
|
||||
|
||||
if (i == 0 || x1 > x + metrics.gmptGlyphOrigin.x)
|
||||
|
@ -897,16 +923,22 @@ _flush_glyphs (cairo_glyph_state_t *state)
|
|||
int dx = 0;
|
||||
WCHAR * elements;
|
||||
int * dx_elements;
|
||||
UINT glyph_index_option;
|
||||
|
||||
status = _cairo_array_append (&state->dx, &dx);
|
||||
if (status)
|
||||
return status;
|
||||
|
||||
if (state->scaled_font->glyph_indexing)
|
||||
glyph_index_option = ETO_GLYPH_INDEX;
|
||||
else
|
||||
glyph_index_option = 0;
|
||||
|
||||
elements = _cairo_array_index (&state->glyphs, 0);
|
||||
dx_elements = _cairo_array_index (&state->dx, 0);
|
||||
if (!ExtTextOutW (state->hdc,
|
||||
state->start_x, state->last_y,
|
||||
ETO_GLYPH_INDEX,
|
||||
glyph_index_option,
|
||||
NULL,
|
||||
elements,
|
||||
state->glyphs.num_elements,
|
||||
|
@ -1079,7 +1111,7 @@ _compute_a8_mask (cairo_win32_surface_t *mask_surface)
|
|||
return &image8->base;
|
||||
}
|
||||
|
||||
static cairo_status_t
|
||||
static cairo_int_status_t
|
||||
_cairo_win32_scaled_font_glyph_init (void *abstract_font,
|
||||
cairo_scaled_glyph_t *scaled_glyph,
|
||||
cairo_scaled_glyph_info_t info)
|
||||
|
@ -1220,10 +1252,45 @@ _cairo_win32_scaled_font_show_glyphs (void *abstract_font,
|
|||
}
|
||||
}
|
||||
|
||||
static cairo_fixed_t
|
||||
_cairo_fixed_from_FIXED (FIXED f)
|
||||
static cairo_int_status_t
|
||||
_cairo_win32_scaled_font_load_truetype_table (void *abstract_font,
|
||||
unsigned long tag,
|
||||
long offset,
|
||||
unsigned char *buffer,
|
||||
unsigned long *length)
|
||||
{
|
||||
return *((cairo_fixed_t *)&f);
|
||||
HDC hdc;
|
||||
cairo_status_t status = CAIRO_STATUS_SUCCESS;
|
||||
|
||||
cairo_win32_scaled_font_t *scaled_font = abstract_font;
|
||||
hdc = _get_global_font_dc ();
|
||||
if (!hdc)
|
||||
return CAIRO_STATUS_NO_MEMORY;
|
||||
|
||||
tag = (tag&0x000000ff)<<24 | (tag&0x0000ff00)<<8 | (tag&0x00ff0000)>>8 | (tag&0xff000000)>>24;
|
||||
status = _cairo_win32_scaled_font_select_unscaled_font (&scaled_font->base, hdc);
|
||||
|
||||
*length = GetFontData (hdc, tag, offset, buffer, *length);
|
||||
if (*length == GDI_ERROR)
|
||||
status = CAIRO_INT_STATUS_UNSUPPORTED;
|
||||
|
||||
_cairo_win32_scaled_font_done_unscaled_font (&scaled_font->base);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
static void
|
||||
_cairo_win32_transform_FIXED_to_fixed (cairo_matrix_t *matrix,
|
||||
FIXED Fx, FIXED Fy,
|
||||
cairo_fixed_t *fx, cairo_fixed_t *fy)
|
||||
{
|
||||
double x, y;
|
||||
|
||||
x = _cairo_fixed_to_double (*((cairo_fixed_t *)&Fx));
|
||||
y = _cairo_fixed_to_double (*((cairo_fixed_t *)&Fy));
|
||||
cairo_matrix_transform_point (matrix, &x, &y);
|
||||
*fx = _cairo_fixed_from_double (x);
|
||||
*fy = _cairo_fixed_from_double (y);
|
||||
}
|
||||
|
||||
static cairo_status_t
|
||||
|
@ -1237,6 +1304,9 @@ _cairo_win32_scaled_font_init_glyph_path (cairo_win32_scaled_font_t *scaled_font
|
|||
DWORD bytesGlyph;
|
||||
unsigned char *buffer, *ptr;
|
||||
cairo_path_fixed_t *path;
|
||||
cairo_matrix_t transform;
|
||||
cairo_fixed_t x, y;
|
||||
UINT glyph_index_option;
|
||||
|
||||
hdc = _get_global_font_dc ();
|
||||
if (!hdc)
|
||||
|
@ -1246,12 +1316,24 @@ _cairo_win32_scaled_font_init_glyph_path (cairo_win32_scaled_font_t *scaled_font
|
|||
if (!path)
|
||||
return CAIRO_STATUS_NO_MEMORY;
|
||||
|
||||
status = cairo_win32_scaled_font_select_font (&scaled_font->base, hdc);
|
||||
if (scaled_font->base.options.hint_style == CAIRO_HINT_STYLE_NONE) {
|
||||
status = _cairo_win32_scaled_font_select_unscaled_font (&scaled_font->base, hdc);
|
||||
transform = scaled_font->base.scale;
|
||||
cairo_matrix_scale (&transform, 1.0/scaled_font->em_square, 1.0/scaled_font->em_square);
|
||||
} else {
|
||||
status = cairo_win32_scaled_font_select_font (&scaled_font->base, hdc);
|
||||
cairo_matrix_init_identity(&transform);
|
||||
}
|
||||
if (status)
|
||||
goto CLEANUP_PATH;
|
||||
|
||||
if (scaled_font->glyph_indexing)
|
||||
glyph_index_option = GGO_GLYPH_INDEX;
|
||||
else
|
||||
glyph_index_option = 0;
|
||||
|
||||
bytesGlyph = GetGlyphOutlineW (hdc, _cairo_scaled_glyph_index (scaled_glyph),
|
||||
GGO_NATIVE | GGO_GLYPH_INDEX,
|
||||
GGO_NATIVE | glyph_index_option,
|
||||
&metrics, 0, NULL, &matrix);
|
||||
|
||||
if (bytesGlyph == GDI_ERROR) {
|
||||
|
@ -1267,7 +1349,7 @@ _cairo_win32_scaled_font_init_glyph_path (cairo_win32_scaled_font_t *scaled_font
|
|||
}
|
||||
|
||||
if (GetGlyphOutlineW (hdc, _cairo_scaled_glyph_index (scaled_glyph),
|
||||
GGO_NATIVE | GGO_GLYPH_INDEX,
|
||||
GGO_NATIVE | glyph_index_option,
|
||||
&metrics, bytesGlyph, buffer, &matrix) == GDI_ERROR) {
|
||||
status = _cairo_win32_print_gdi_error ("_cairo_win32_scaled_font_glyph_path");
|
||||
free (buffer);
|
||||
|
@ -1280,9 +1362,11 @@ _cairo_win32_scaled_font_init_glyph_path (cairo_win32_scaled_font_t *scaled_font
|
|||
|
||||
ptr += sizeof (TTPOLYGONHEADER);
|
||||
|
||||
_cairo_path_fixed_move_to (path,
|
||||
_cairo_fixed_from_FIXED (header->pfxStart.x),
|
||||
_cairo_fixed_from_FIXED (header->pfxStart.y));
|
||||
_cairo_win32_transform_FIXED_to_fixed (&transform,
|
||||
header->pfxStart.x,
|
||||
header->pfxStart.y,
|
||||
&x, &y);
|
||||
_cairo_path_fixed_move_to (path, x, y);
|
||||
|
||||
while (ptr < endPoly) {
|
||||
TTPOLYCURVE *curve = (TTPOLYCURVE *)ptr;
|
||||
|
@ -1291,26 +1375,36 @@ _cairo_win32_scaled_font_init_glyph_path (cairo_win32_scaled_font_t *scaled_font
|
|||
switch (curve->wType) {
|
||||
case TT_PRIM_LINE:
|
||||
for (i = 0; i < curve->cpfx; i++) {
|
||||
_cairo_path_fixed_line_to (path,
|
||||
_cairo_fixed_from_FIXED (points[i].x),
|
||||
_cairo_fixed_from_FIXED (points[i].y));
|
||||
_cairo_win32_transform_FIXED_to_fixed (&transform,
|
||||
points[i].x,
|
||||
points[i].y,
|
||||
&x, &y);
|
||||
_cairo_path_fixed_line_to (path, x, y);
|
||||
}
|
||||
break;
|
||||
case TT_PRIM_QSPLINE:
|
||||
for (i = 0; i < curve->cpfx - 1; i++) {
|
||||
cairo_fixed_t p1x, p1y, p2x, p2y, cx, cy, c1x, c1y, c2x, c2y;
|
||||
_cairo_path_fixed_get_current_point (path, &p1x, &p1y);
|
||||
cx = _cairo_fixed_from_FIXED (points[i].x);
|
||||
cy = _cairo_fixed_from_FIXED (points[i].y);
|
||||
_cairo_win32_transform_FIXED_to_fixed (&transform,
|
||||
points[i].x,
|
||||
points[i].y,
|
||||
&cx, &cy);
|
||||
|
||||
if (i + 1 == curve->cpfx - 1) {
|
||||
p2x = _cairo_fixed_from_FIXED (points[i + 1].x);
|
||||
p2y = _cairo_fixed_from_FIXED (points[i + 1].y);
|
||||
_cairo_win32_transform_FIXED_to_fixed (&transform,
|
||||
points[i + 1].x,
|
||||
points[i + 1].y,
|
||||
&p2x, &p2y);
|
||||
} else {
|
||||
/* records with more than one curve use interpolation for
|
||||
control points, per http://support.microsoft.com/kb/q87115/ */
|
||||
p2x = (cx + _cairo_fixed_from_FIXED (points[i + 1].x)) / 2;
|
||||
p2y = (cy + _cairo_fixed_from_FIXED (points[i + 1].y)) / 2;
|
||||
_cairo_win32_transform_FIXED_to_fixed (&transform,
|
||||
points[i + 1].x,
|
||||
points[i + 1].y,
|
||||
&x, &y);
|
||||
p2x = (cx + x) / 2;
|
||||
p2y = (cy + y) / 2;
|
||||
}
|
||||
|
||||
c1x = 2 * cx / 3 + p1x / 3;
|
||||
|
@ -1323,13 +1417,20 @@ _cairo_win32_scaled_font_init_glyph_path (cairo_win32_scaled_font_t *scaled_font
|
|||
break;
|
||||
case TT_PRIM_CSPLINE:
|
||||
for (i = 0; i < curve->cpfx - 2; i += 2) {
|
||||
_cairo_path_fixed_curve_to (path,
|
||||
_cairo_fixed_from_FIXED (points[i].x),
|
||||
_cairo_fixed_from_FIXED (points[i].y),
|
||||
_cairo_fixed_from_FIXED (points[i + 1].x),
|
||||
_cairo_fixed_from_FIXED (points[i + 1].y),
|
||||
_cairo_fixed_from_FIXED (points[i + 2].x),
|
||||
_cairo_fixed_from_FIXED (points[i + 2].y));
|
||||
cairo_fixed_t x1, y1, x2, y2;
|
||||
_cairo_win32_transform_FIXED_to_fixed (&transform,
|
||||
points[i].x,
|
||||
points[i].y,
|
||||
&x, &y);
|
||||
_cairo_win32_transform_FIXED_to_fixed (&transform,
|
||||
points[i + 1].x,
|
||||
points[i + 1].y,
|
||||
&x1, &y1);
|
||||
_cairo_win32_transform_FIXED_to_fixed (&transform,
|
||||
points[i + 2].x,
|
||||
points[i + 2].y,
|
||||
&x2, &y2);
|
||||
_cairo_path_fixed_curve_to (path, x, y, x1, y1, x2, y2);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
@ -1363,6 +1464,7 @@ const cairo_scaled_font_backend_t cairo_win32_scaled_font_backend = {
|
|||
_cairo_win32_scaled_font_text_to_glyphs,
|
||||
NULL, /* ucs4_to_index */
|
||||
_cairo_win32_scaled_font_show_glyphs,
|
||||
_cairo_win32_scaled_font_load_truetype_table,
|
||||
};
|
||||
|
||||
/* cairo_win32_font_face_t */
|
||||
|
@ -1391,6 +1493,8 @@ _cairo_win32_font_face_scaled_font_create (void *abstract_face,
|
|||
{
|
||||
cairo_win32_font_face_t *font_face = abstract_face;
|
||||
|
||||
_cairo_win32_initialize ();
|
||||
|
||||
*font = _win32_scaled_font_create (&font_face->logfont,
|
||||
font_face->hfont,
|
||||
&font_face->base,
|
||||
|
@ -1428,6 +1532,8 @@ cairo_win32_font_face_create_for_logfontw (LOGFONTW *logfont)
|
|||
{
|
||||
cairo_win32_font_face_t *font_face;
|
||||
|
||||
_cairo_win32_initialize ();
|
||||
|
||||
font_face = malloc (sizeof (cairo_win32_font_face_t));
|
||||
if (!font_face) {
|
||||
_cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
|
@ -1461,6 +1567,8 @@ cairo_win32_font_face_create_for_hfont (HFONT font)
|
|||
{
|
||||
cairo_win32_font_face_t *font_face;
|
||||
|
||||
_cairo_win32_initialize ();
|
||||
|
||||
font_face = malloc (sizeof (cairo_win32_font_face_t));
|
||||
if (!font_face) {
|
||||
_cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
|
@ -1563,9 +1671,6 @@ cairo_win32_scaled_font_done_font (cairo_scaled_font_t *scaled_font)
|
|||
double
|
||||
cairo_win32_scaled_font_get_metrics_factor (cairo_scaled_font_t *scaled_font)
|
||||
{
|
||||
if (cairo_scaled_font_get_type (scaled_font) != CAIRO_FONT_TYPE_WIN32)
|
||||
return 1.0;
|
||||
|
||||
return 1. / ((cairo_win32_scaled_font_t *)scaled_font)->logical_scale;
|
||||
}
|
||||
|
||||
|
@ -1574,9 +1679,6 @@ cairo_win32_scaled_font_get_logical_to_device (cairo_scaled_font_t *scaled_font,
|
|||
cairo_matrix_t *logical_to_device)
|
||||
{
|
||||
cairo_win32_scaled_font_t *win_font = (cairo_win32_scaled_font_t *)scaled_font;
|
||||
if (cairo_scaled_font_get_type (scaled_font) != CAIRO_FONT_TYPE_WIN32)
|
||||
return;
|
||||
|
||||
*logical_to_device = win_font->logical_to_device;
|
||||
}
|
||||
|
||||
|
@ -1585,8 +1687,5 @@ cairo_win32_scaled_font_get_device_to_logical (cairo_scaled_font_t *scaled_font,
|
|||
cairo_matrix_t *device_to_logical)
|
||||
{
|
||||
cairo_win32_scaled_font_t *win_font = (cairo_win32_scaled_font_t *)scaled_font;
|
||||
if (cairo_scaled_font_get_type (scaled_font) != CAIRO_FONT_TYPE_WIN32)
|
||||
return;
|
||||
|
||||
*device_to_logical = win_font->device_to_logical;
|
||||
}
|
||||
|
|
|
@ -102,4 +102,7 @@ _cairo_win32_print_gdi_error (const char *context);
|
|||
cairo_bool_t
|
||||
_cairo_surface_is_win32 (cairo_surface_t *surface);
|
||||
|
||||
void
|
||||
_cairo_win32_initialize ();
|
||||
|
||||
#endif /* CAIRO_WIN32_PRIVATE_H */
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* -*- Mode: c; c-basic-offset: 4; indent-tabs-mode: t; tab-width: 8; -*- */
|
||||
/* -*- Mode: c; tab-width: 8; c-basic-offset: 4; indent-tabs-mode: t; -*- */
|
||||
/* Cairo - a vector graphics library with display and print output
|
||||
*
|
||||
* Copyright © 2005 Red Hat, Inc.
|
||||
|
@ -49,6 +49,9 @@
|
|||
#define SB_NONE 0x00000000
|
||||
#endif
|
||||
|
||||
#define PELS_72DPI (72. / 0.0254)
|
||||
#define NIL_SURFACE ((cairo_surface_t*)&_cairo_surface_nil)
|
||||
|
||||
static const cairo_surface_backend_t cairo_win32_surface_backend;
|
||||
|
||||
/**
|
||||
|
@ -104,7 +107,7 @@ _cairo_win32_flags_for_dc (HDC dc)
|
|||
*/
|
||||
flags |= CAIRO_WIN32_SURFACE_CAN_BITBLT;
|
||||
flags |= CAIRO_WIN32_SURFACE_CAN_ALPHABLEND;
|
||||
/*flags |= CAIRO_WIN32_SURFACE_CAN_STRETCHBLT;*/
|
||||
flags |= CAIRO_WIN32_SURFACE_CAN_STRETCHBLT;
|
||||
} else {
|
||||
int cap;
|
||||
|
||||
|
@ -115,10 +118,8 @@ _cairo_win32_flags_for_dc (HDC dc)
|
|||
cap = GetDeviceCaps(dc, RASTERCAPS);
|
||||
if (cap & RC_BITBLT)
|
||||
flags |= CAIRO_WIN32_SURFACE_CAN_BITBLT;
|
||||
/*
|
||||
if (cap & RC_STRETCHBLT)
|
||||
flags |= CAIRO_WIN32_SURFACE_CAN_STRETCHBLT;
|
||||
*/
|
||||
}
|
||||
|
||||
return flags;
|
||||
|
@ -176,8 +177,8 @@ _create_dc_and_bitmap (cairo_win32_surface_t *surface,
|
|||
bitmap_info->bmiHeader.biWidth = width == 0 ? 1 : width;
|
||||
bitmap_info->bmiHeader.biHeight = height == 0 ? -1 : - height; /* top-down */
|
||||
bitmap_info->bmiHeader.biSizeImage = 0;
|
||||
bitmap_info->bmiHeader.biXPelsPerMeter = 72. / 0.0254; /* unused here */
|
||||
bitmap_info->bmiHeader.biYPelsPerMeter = 72. / 0.0254; /* unused here */
|
||||
bitmap_info->bmiHeader.biXPelsPerMeter = PELS_72DPI; /* unused here */
|
||||
bitmap_info->bmiHeader.biYPelsPerMeter = PELS_72DPI; /* unused here */
|
||||
bitmap_info->bmiHeader.biPlanes = 1;
|
||||
|
||||
switch (format) {
|
||||
|
@ -185,6 +186,8 @@ _create_dc_and_bitmap (cairo_win32_surface_t *surface,
|
|||
* break if we do, especially if we don't set up an image
|
||||
* fallback. It could be a bug with using a 24bpp pixman image
|
||||
* (and creating one with masks). So treat them like 32bpp.
|
||||
* NOTE: This causes problems when using BitBlt/AlphaBlend/etc!
|
||||
* see end of file.
|
||||
*/
|
||||
case CAIRO_FORMAT_RGB24:
|
||||
case CAIRO_FORMAT_ARGB32:
|
||||
|
@ -308,10 +311,12 @@ _cairo_win32_surface_create_for_dc (HDC original_dc,
|
|||
char *bits;
|
||||
int rowstride;
|
||||
|
||||
_cairo_win32_initialize ();
|
||||
|
||||
surface = malloc (sizeof (cairo_win32_surface_t));
|
||||
if (surface == NULL) {
|
||||
_cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
return &_cairo_surface_nil;
|
||||
return NIL_SURFACE;
|
||||
}
|
||||
|
||||
status = _create_dc_and_bitmap (surface, original_dc, format,
|
||||
|
@ -358,10 +363,10 @@ _cairo_win32_surface_create_for_dc (HDC original_dc,
|
|||
|
||||
if (status == CAIRO_STATUS_NO_MEMORY) {
|
||||
_cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
return &_cairo_surface_nil;
|
||||
return NIL_SURFACE;
|
||||
} else {
|
||||
_cairo_error (status);
|
||||
return &_cairo_surface_nil;
|
||||
return NIL_SURFACE;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -441,7 +446,7 @@ _cairo_win32_surface_get_subimage (cairo_win32_surface_t *surface,
|
|||
cairo_win32_surface_t **local_out)
|
||||
{
|
||||
cairo_win32_surface_t *local;
|
||||
cairo_status_t status;
|
||||
cairo_int_status_t status;
|
||||
cairo_content_t content = _cairo_content_from_format (surface->format);
|
||||
|
||||
local =
|
||||
|
@ -450,13 +455,22 @@ _cairo_win32_surface_get_subimage (cairo_win32_surface_t *surface,
|
|||
if (local->base.status)
|
||||
return CAIRO_STATUS_NO_MEMORY;
|
||||
|
||||
if (!BitBlt (local->dc,
|
||||
0, 0,
|
||||
width, height,
|
||||
surface->dc,
|
||||
x, y,
|
||||
SRCCOPY)) {
|
||||
/* If we fail to BitBlt here, most likely the source is a printer.
|
||||
status = CAIRO_INT_STATUS_UNSUPPORTED;
|
||||
|
||||
if ((local->flags & CAIRO_WIN32_SURFACE_CAN_BITBLT) &&
|
||||
BitBlt (local->dc,
|
||||
0, 0,
|
||||
width, height,
|
||||
surface->dc,
|
||||
x, y,
|
||||
SRCCOPY))
|
||||
{
|
||||
status = CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
if (status) {
|
||||
/* If we failed here, most likely the source or dest doesn't
|
||||
* support BitBlt/AlphaBlend (e.g. a printer).
|
||||
* You can't reliably get bits from a printer DC, so just fill in
|
||||
* the surface as white (common case for printing).
|
||||
*/
|
||||
|
@ -471,14 +485,6 @@ _cairo_win32_surface_get_subimage (cairo_win32_surface_t *surface,
|
|||
*local_out = local;
|
||||
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
|
||||
FAIL:
|
||||
status = _cairo_win32_print_gdi_error ("_cairo_win32_surface_get_subimage");
|
||||
|
||||
if (local)
|
||||
cairo_surface_destroy (&local->base);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
static cairo_status_t
|
||||
|
@ -690,10 +696,21 @@ _composite_alpha_blend (cairo_win32_surface_t *dst,
|
|||
if (!(dst->flags & CAIRO_WIN32_SURFACE_CAN_ALPHABLEND))
|
||||
return CAIRO_INT_STATUS_UNSUPPORTED;
|
||||
|
||||
if (src->format == CAIRO_FORMAT_RGB24 && dst->format == CAIRO_FORMAT_ARGB32)
|
||||
{
|
||||
/* Both of these are represented as 32bpp internally, and AlphaBlend
|
||||
* DOES NOT throw away source alpha is AC_SRC_ALPHA is not specified,
|
||||
* it just multiplies it by the SourceConstantAlpha, along with the
|
||||
* R G B components.
|
||||
* XXX there has to be a way to do this!
|
||||
*/
|
||||
return CAIRO_INT_STATUS_UNSUPPORTED;
|
||||
}
|
||||
|
||||
blend_function.BlendOp = AC_SRC_OVER;
|
||||
blend_function.BlendFlags = 0;
|
||||
blend_function.SourceConstantAlpha = alpha;
|
||||
blend_function.AlphaFormat = src->format == CAIRO_FORMAT_ARGB32 ? AC_SRC_ALPHA : 0;
|
||||
blend_function.AlphaFormat = (src->format == CAIRO_FORMAT_ARGB32) ? AC_SRC_ALPHA : 0;
|
||||
|
||||
/*oldstretchmode = SetStretchBltMode(dst->dc, HALFTONE);*/
|
||||
if (!alpha_blend (dst->dc,
|
||||
|
@ -730,11 +747,19 @@ _cairo_win32_surface_composite (cairo_operator_t op,
|
|||
int itx, ity;
|
||||
double scalex, scaley;
|
||||
cairo_fixed_t x0_fixed, y0_fixed;
|
||||
int orig_dst_x = dst_x, orig_dst_y = dst_y;
|
||||
int real_src_width, real_src_height;
|
||||
|
||||
int src_width, src_height;
|
||||
int dst_width, dst_height;
|
||||
|
||||
|
||||
cairo_bool_t needs_alpha, needs_scale;
|
||||
cairo_image_surface_t *src_image = NULL;
|
||||
|
||||
#if 0
|
||||
fprintf (stderr, "composite: %d %p %p %p [%d %d] [%d %d] [%d %d] %dx%d\n",
|
||||
op, pattern, mask_pattern, abstract_dst, src_x, src_y, mask_x, mask_y, dst_x, dst_y, width, height);
|
||||
#endif
|
||||
|
||||
/* If the destination can't do any of these, then
|
||||
* we may as well give up, since this is what we'll
|
||||
|
@ -769,8 +794,20 @@ _cairo_win32_surface_composite (cairo_operator_t op,
|
|||
src_surface_pattern = (cairo_surface_pattern_t *)pattern;
|
||||
src = (cairo_win32_surface_t *)src_surface_pattern->surface;
|
||||
|
||||
if (src->base.backend != dst->base.backend)
|
||||
/* Disable this StretchDIBits optimization for now */
|
||||
#if 0
|
||||
if (src->base.type == CAIRO_SURFACE_TYPE_IMAGE) {
|
||||
src_image = (cairo_image_surface_t*) src;
|
||||
|
||||
if (src_image->format != CAIRO_FORMAT_RGB24 ||
|
||||
alpha != 255 ||
|
||||
src_image->stride != (src_image->width * 4))
|
||||
return CAIRO_INT_STATUS_UNSUPPORTED;
|
||||
} else
|
||||
#endif
|
||||
if (src->base.backend != dst->base.backend) {
|
||||
return CAIRO_INT_STATUS_UNSUPPORTED;
|
||||
}
|
||||
|
||||
#if 0
|
||||
fprintf (stderr, "Before check: (%d %d) [%d %d] -> [%d %d %d %d] {mat %f %f %f %f}\n",
|
||||
|
@ -793,7 +830,7 @@ _cairo_win32_surface_composite (cairo_operator_t op,
|
|||
{
|
||||
return CAIRO_INT_STATUS_UNSUPPORTED;
|
||||
}
|
||||
|
||||
|
||||
itx = _cairo_fixed_integer_part(x0_fixed);
|
||||
ity = _cairo_fixed_integer_part(y0_fixed);
|
||||
|
||||
|
@ -803,105 +840,67 @@ _cairo_win32_surface_composite (cairo_operator_t op,
|
|||
src_x += itx;
|
||||
src_y += ity;
|
||||
|
||||
#if 0
|
||||
if (scalex != 1.0 || scaley != 1.0) {
|
||||
/* we already know that the destination is an integer rectangle;
|
||||
* we need to see if the source is also.
|
||||
*/
|
||||
cairo_fixed_t sx0 = _cairo_fixed_from_double(src_x * scalex);
|
||||
cairo_fixed_t sy0 = _cairo_fixed_from_double(src_y * scaley);
|
||||
cairo_fixed_t sw = _cairo_fixed_from_double((src->extents.width - src_x) * scalex);
|
||||
cairo_fixed_t sh = _cairo_fixed_from_double((src->extents.height - src_y) * scaley);
|
||||
|
||||
fprintf (stderr, "sx0 sy0 sw sh: %f %f %f %f\n",
|
||||
_cairo_fixed_to_double(sx0), _cairo_fixed_to_double(sy0),
|
||||
_cairo_fixed_to_double(sw), _cairo_fixed_to_double(sh));
|
||||
|
||||
if (!_cairo_fixed_is_integer(sw) ||
|
||||
!_cairo_fixed_is_integer(sh) ||
|
||||
!_cairo_fixed_is_integer(sx0) ||
|
||||
!_cairo_fixed_is_integer(sy0))
|
||||
{
|
||||
return CAIRO_INT_STATUS_UNSUPPORTED;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
if (scalex <= 0.0 || scaley <= 0.0)
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
|
||||
#if 0
|
||||
fprintf (stderr, "Before fixup: (%d %d) src: [%d %d] -> dst: [%d %d %d %d] itsc {%d %d %f %f}\n",
|
||||
src->extents.width, src->extents.height,
|
||||
src_x, src_y,
|
||||
dst_x, dst_y, width, height,
|
||||
itx, ity, scalex, scaley);
|
||||
#endif
|
||||
if (scalex != 1.0 || scaley != 1.0)
|
||||
return CAIRO_INT_STATUS_UNSUPPORTED;
|
||||
|
||||
/* Fix up src coordinates; the src coords and size must be within the
|
||||
* bounds of the source surface.
|
||||
* XXX the region not covered should be appropriately rendered!
|
||||
* - for OVER/SOURCE with RGB24 source -> opaque black
|
||||
* - for SOURCE with ARGB32 source -> 100% transparent black
|
||||
/* If the src coordinates are outside of the source surface bounds,
|
||||
* we have to fix them up, because this is an error for the GDI
|
||||
* functions.
|
||||
* XXX Make sure to correctly clear out the unpainted region.
|
||||
*/
|
||||
src_x *= scalex;
|
||||
src_y *= scaley;
|
||||
|
||||
if (src_x < 0) {
|
||||
width += src_x / scalex;
|
||||
dst_x -= src_x / scalex;
|
||||
width += src_x;
|
||||
dst_x -= src_x;
|
||||
src_x = 0;
|
||||
}
|
||||
|
||||
if (src_y < 0) {
|
||||
height += src_y / scaley;
|
||||
dst_y -= src_y / scaley;
|
||||
height += src_y;
|
||||
dst_y -= src_y;
|
||||
src_y = 0;
|
||||
}
|
||||
|
||||
if (src_x + width > (src->extents.width / scalex))
|
||||
dst_width = (src->extents.width / scalex) - src_x;
|
||||
if (src_x + width > src->extents.width)
|
||||
dst_width = src->extents.width - src_x;
|
||||
else
|
||||
dst_width = width;
|
||||
|
||||
if (src_y + height > (src->extents.height / scaley))
|
||||
dst_height = (src->extents.height / scaley) - src_y;
|
||||
if (src_y + height > src->extents.height)
|
||||
dst_height = src->extents.height - src_y;
|
||||
else
|
||||
dst_height = height;
|
||||
/* If we're scaling up an iamge, we may have
|
||||
* less than 1 pixel's worth of width/height map
|
||||
* into 1 row in the destination. If this is the case,
|
||||
* we need to clip to the destination's width/height,
|
||||
* and then figure out the next source/dest width/height combo
|
||||
* where there is an integer match.
|
||||
*
|
||||
* For now, just let cairo scale that case. THIS IS NOT IDEAL,
|
||||
* as the scaling algorithms aren't identical!
|
||||
|
||||
src_width = dst_width;
|
||||
src_height = dst_height;
|
||||
|
||||
/*
|
||||
* Figure out what action to take.
|
||||
* XXX handle SOURCE with alpha != 255
|
||||
*/
|
||||
if (!_cairo_fixed_is_integer(_cairo_fixed_from_double(dst_width * scalex)) ||
|
||||
!_cairo_fixed_is_integer(_cairo_fixed_from_double(dst_height * scaley)))
|
||||
return CAIRO_INT_STATUS_UNSUPPORTED;
|
||||
|
||||
src_width = dst_width * scalex;
|
||||
src_height = dst_height * scaley;
|
||||
|
||||
if (alpha == 255 &&
|
||||
(op == CAIRO_OPERATOR_SOURCE ||
|
||||
(src->format == CAIRO_FORMAT_RGB24 && op == CAIRO_OPERATOR_OVER)))
|
||||
(dst->format == src->format) &&
|
||||
((op == CAIRO_OPERATOR_SOURCE && (dst->format == CAIRO_FORMAT_ARGB32 ||
|
||||
dst->format == CAIRO_FORMAT_RGB24)) ||
|
||||
(op == CAIRO_OPERATOR_OVER && dst->format == CAIRO_FORMAT_RGB24)))
|
||||
{
|
||||
needs_alpha = FALSE;
|
||||
} else if ((src->format == CAIRO_FORMAT_RGB24 || src->format == CAIRO_FORMAT_ARGB32) &&
|
||||
(dst->format == CAIRO_FORMAT_RGB24 || dst->format == CAIRO_FORMAT_ARGB32) &&
|
||||
op == CAIRO_OPERATOR_OVER)
|
||||
} else if ((op == CAIRO_OPERATOR_OVER || op == CAIRO_OPERATOR_SOURCE) &&
|
||||
(src->format == CAIRO_FORMAT_RGB24 || src->format == CAIRO_FORMAT_ARGB32) &&
|
||||
(dst->format == CAIRO_FORMAT_RGB24 || dst->format == CAIRO_FORMAT_ARGB32))
|
||||
{
|
||||
needs_alpha = TRUE;
|
||||
} else {
|
||||
return CAIRO_INT_STATUS_UNSUPPORTED;
|
||||
}
|
||||
|
||||
|
||||
if (scalex == 1.0 && scaley == 1.0) {
|
||||
needs_scale = FALSE;
|
||||
} else {
|
||||
/* Should never be reached until we turn StretchBlt back on */
|
||||
needs_scale = TRUE;
|
||||
}
|
||||
|
||||
|
@ -912,8 +911,32 @@ _cairo_win32_surface_composite (cairo_operator_t op,
|
|||
fflush (stderr);
|
||||
#endif
|
||||
|
||||
/* Then do BitBlt, StretchBlt, AlphaBlend, or MaskBlt */
|
||||
if (!needs_alpha) {
|
||||
/* Then do BitBlt, StretchDIBits, StretchBlt, AlphaBlend, or MaskBlt */
|
||||
if (src_image) {
|
||||
BITMAPINFO bi;
|
||||
bi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
|
||||
bi.bmiHeader.biWidth = src_image->width;
|
||||
bi.bmiHeader.biHeight = src_image->height;
|
||||
bi.bmiHeader.biSizeImage = 0;
|
||||
bi.bmiHeader.biXPelsPerMeter = PELS_72DPI;
|
||||
bi.bmiHeader.biYPelsPerMeter = PELS_72DPI;
|
||||
bi.bmiHeader.biPlanes = 1;
|
||||
bi.bmiHeader.biBitCount = 32;
|
||||
bi.bmiHeader.biCompression = BI_RGB;
|
||||
bi.bmiHeader.biClrUsed = 0;
|
||||
bi.bmiHeader.biClrImportant = 0;
|
||||
|
||||
if (!StretchDIBits (dst->dc,
|
||||
dst_x, dst_y, dst_width, dst_height,
|
||||
src_x, src_y, src_width, src_height,
|
||||
src_image->data,
|
||||
&bi,
|
||||
DIB_RGB_COLORS,
|
||||
SRCCOPY))
|
||||
return _cairo_win32_print_gdi_error ("_cairo_win32_surface_composite(StretchDIBits)");
|
||||
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
} else if (!needs_alpha) {
|
||||
/* BitBlt or StretchBlt? */
|
||||
if (!needs_scale && (dst->flags & CAIRO_WIN32_SURFACE_CAN_BITBLT)) {
|
||||
if (!BitBlt (dst->dc,
|
||||
|
@ -922,15 +945,14 @@ _cairo_win32_surface_composite (cairo_operator_t op,
|
|||
src->dc,
|
||||
src_x, src_y,
|
||||
SRCCOPY))
|
||||
return _cairo_win32_print_gdi_error ("_cairo_win32_surface_composite");
|
||||
return _cairo_win32_print_gdi_error ("_cairo_win32_surface_composite(BitBlt)");
|
||||
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
} else if (dst->flags & CAIRO_WIN32_SURFACE_CAN_STRETCHBLT) {
|
||||
/* StretchBlt? */
|
||||
/* XXX check if we want HALFTONE, based on the src filter */
|
||||
int oldmode = SetStretchBltMode(dst->dc, HALFTONE);
|
||||
BOOL success;
|
||||
|
||||
int oldmode = SetStretchBltMode(dst->dc, HALFTONE);
|
||||
success = StretchBlt(dst->dc,
|
||||
dst_x, dst_y,
|
||||
dst_width, dst_height,
|
||||
|
@ -944,11 +966,11 @@ _cairo_win32_surface_composite (cairo_operator_t op,
|
|||
_cairo_win32_print_gdi_error ("StretchBlt");
|
||||
return CAIRO_INT_STATUS_UNSUPPORTED;
|
||||
}
|
||||
|
||||
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
} else if (needs_alpha && !needs_scale) {
|
||||
return _composite_alpha_blend (dst, src, alpha,
|
||||
return _composite_alpha_blend (dst, src, alpha,
|
||||
src_x, src_y, src_width, src_height,
|
||||
dst_x, dst_y, dst_width, dst_height);
|
||||
}
|
||||
|
@ -1348,13 +1370,15 @@ cairo_win32_surface_create (HDC hdc)
|
|||
int depth;
|
||||
cairo_format_t format;
|
||||
|
||||
_cairo_win32_initialize ();
|
||||
|
||||
/* Try to figure out the drawing bounds for the Device context
|
||||
*/
|
||||
if (GetClipBox (hdc, &rect) == ERROR) {
|
||||
_cairo_win32_print_gdi_error ("cairo_win32_surface_create");
|
||||
/* XXX: Can we make a more reasonable guess at the error cause here? */
|
||||
_cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
return &_cairo_surface_nil;
|
||||
return NIL_SURFACE;
|
||||
}
|
||||
|
||||
if (GetDeviceCaps(hdc, TECHNOLOGY) == DT_RASDISPLAY) {
|
||||
|
@ -1372,7 +1396,7 @@ cairo_win32_surface_create (HDC hdc)
|
|||
else {
|
||||
_cairo_win32_print_gdi_error("cairo_win32_surface_create(bad BITSPIXEL)");
|
||||
_cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
return &_cairo_surface_nil;
|
||||
return NIL_SURFACE;
|
||||
}
|
||||
} else {
|
||||
format = CAIRO_FORMAT_RGB24;
|
||||
|
@ -1381,7 +1405,7 @@ cairo_win32_surface_create (HDC hdc)
|
|||
surface = malloc (sizeof (cairo_win32_surface_t));
|
||||
if (surface == NULL) {
|
||||
_cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
return &_cairo_surface_nil;
|
||||
return NIL_SURFACE;
|
||||
}
|
||||
|
||||
surface->image = NULL;
|
||||
|
@ -1398,15 +1422,15 @@ cairo_win32_surface_create (HDC hdc)
|
|||
surface->clip_rect.height = rect.bottom - rect.top;
|
||||
|
||||
if (surface->clip_rect.width == 0 ||
|
||||
surface->clip_rect.height == 0)
|
||||
surface->clip_rect.height == 0)
|
||||
{
|
||||
surface->saved_clip = NULL;
|
||||
surface->saved_clip = NULL;
|
||||
} else {
|
||||
surface->saved_clip = CreateRectRgn (0, 0, 0, 0);
|
||||
if (GetClipRgn (hdc, surface->saved_clip) == 0) {
|
||||
DeleteObject(surface->saved_clip);
|
||||
surface->saved_clip = NULL;
|
||||
}
|
||||
surface->saved_clip = CreateRectRgn (0, 0, 0, 0);
|
||||
if (GetClipRgn (hdc, surface->saved_clip) == 0) {
|
||||
DeleteObject(surface->saved_clip);
|
||||
surface->saved_clip = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
surface->extents = surface->clip_rect;
|
||||
|
@ -1435,17 +1459,31 @@ cairo_win32_surface_create (HDC hdc)
|
|||
**/
|
||||
cairo_surface_t *
|
||||
cairo_win32_surface_create_with_dib (cairo_format_t format,
|
||||
int width,
|
||||
int height)
|
||||
int width,
|
||||
int height)
|
||||
{
|
||||
return _cairo_win32_surface_create_for_dc (NULL, format, width, height);
|
||||
}
|
||||
|
||||
/**
|
||||
* cairo_win32_surface_create_with_ddb:
|
||||
* @format: format of pixels in the surface to create
|
||||
* @width: width of the surface, in pixels
|
||||
* @height: height of the surface, in pixels
|
||||
*
|
||||
* Creates a device-independent-bitmap surface not associated with
|
||||
* any particular existing surface or device context. The created
|
||||
* bitmap will be unititialized.
|
||||
*
|
||||
* Return value: the newly created surface
|
||||
*
|
||||
* Since: 1.4
|
||||
**/
|
||||
cairo_surface_t *
|
||||
cairo_win32_surface_create_with_ddb (HDC hdc,
|
||||
cairo_format_t format,
|
||||
int width,
|
||||
int height)
|
||||
cairo_format_t format,
|
||||
int width,
|
||||
int height)
|
||||
{
|
||||
cairo_win32_surface_t *new_surf;
|
||||
HBITMAP ddb;
|
||||
|
@ -1536,8 +1574,10 @@ cairo_win32_surface_get_dc (cairo_surface_t *surface)
|
|||
* as the DIB of the Win32 surface. If the passed-in win32 surface
|
||||
* is not a DIB surface, NULL is returned.
|
||||
*
|
||||
* Return value: a #cairo_surface_t (reference owned by the win32 cairo_surface_t),
|
||||
* Return value: a #cairo_surface_t (owned by the win32 cairo_surface_t),
|
||||
* or NULL if the win32 surface is not a DIB.
|
||||
*
|
||||
* Since: 1.4
|
||||
*/
|
||||
cairo_surface_t *
|
||||
cairo_win32_surface_get_image (cairo_surface_t *surface)
|
||||
|
@ -1581,18 +1621,34 @@ static const cairo_surface_backend_t cairo_win32_surface_backend = {
|
|||
NULL /* snapshot */
|
||||
};
|
||||
|
||||
#if 0
|
||||
/*
|
||||
* Without pthread, on win32 we need to initialize all the 'mutex'es
|
||||
* before use. It is guaranteed that DllMain will get called single
|
||||
* threaded before any other function.
|
||||
* Initializing more than finally needed should not matter much.
|
||||
*/
|
||||
#ifndef HAVE_PTHREAD_H
|
||||
#if !defined(HAVE_PTHREAD_H)
|
||||
|
||||
CRITICAL_SECTION cairo_toy_font_face_hash_table_mutex;
|
||||
CRITICAL_SECTION cairo_scaled_font_map_mutex;
|
||||
CRITICAL_SECTION cairo_ft_unscaled_font_map_mutex;
|
||||
|
||||
static int _cairo_win32_initialized = 0;
|
||||
|
||||
void
|
||||
_cairo_win32_initialize () {
|
||||
if (_cairo_win32_initialized)
|
||||
return;
|
||||
|
||||
/* every 'mutex' from CAIRO_MUTEX_DECALRE needs to be initialized here */
|
||||
InitializeCriticalSection (&cairo_toy_font_face_hash_table_mutex);
|
||||
InitializeCriticalSection (&cairo_scaled_font_map_mutex);
|
||||
InitializeCriticalSection (&cairo_ft_unscaled_font_map_mutex);
|
||||
|
||||
_cairo_win32_initialized = 1;
|
||||
}
|
||||
|
||||
#if !defined(CAIRO_WIN32_STATIC_BUILD)
|
||||
BOOL WINAPI
|
||||
DllMain (HINSTANCE hinstDLL,
|
||||
DWORD fdwReason,
|
||||
|
@ -1601,10 +1657,7 @@ DllMain (HINSTANCE hinstDLL,
|
|||
switch (fdwReason)
|
||||
{
|
||||
case DLL_PROCESS_ATTACH:
|
||||
/* every 'mutex' from CAIRO_MUTEX_DECALRE needs to be initialized here */
|
||||
InitializeCriticalSection (&cairo_toy_font_face_hash_table_mutex);
|
||||
InitializeCriticalSection (&cairo_scaled_font_map_mutex);
|
||||
InitializeCriticalSection (&cairo_ft_unscaled_font_map_mutex);
|
||||
_cairo_win32_initialize();
|
||||
break;
|
||||
case DLL_PROCESS_DETACH:
|
||||
DeleteCriticalSection (&cairo_toy_font_face_hash_table_mutex);
|
||||
|
@ -1616,3 +1669,17 @@ DllMain (HINSTANCE hinstDLL,
|
|||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* Notes:
|
||||
*
|
||||
* Win32 alpha-understanding functions
|
||||
*
|
||||
* BitBlt - will copy full 32 bits from a 32bpp DIB to result
|
||||
* (so it's safe to use for ARGB32->ARGB32 SOURCE blits)
|
||||
* (but not safe going RGB24->ARGB32, if RGB24 is also represented
|
||||
* as a 32bpp DIB, since the alpha isn't discarded!)
|
||||
*
|
||||
* AlphaBlend - if both the source and dest have alpha, even if AC_SRC_ALPHA isn't set,
|
||||
* it will still copy over the src alpha, because the SCA value (255) will be
|
||||
* multiplied by all the src components.
|
||||
*/
|
||||
|
|
|
@ -37,35 +37,10 @@
|
|||
#include "cairoint.h"
|
||||
#include "cairo-xcb.h"
|
||||
#include "cairo-xcb-xrender.h"
|
||||
#include <X11/XCB/xcb_renderutil.h>
|
||||
|
||||
#define AllPlanes ((unsigned long)~0L)
|
||||
|
||||
static XCBRenderPICTFORMAT
|
||||
format_from_visual(XCBConnection *c, XCBVISUALID visual)
|
||||
{
|
||||
static const XCBRenderPICTFORMAT nil = { 0 };
|
||||
XCBRenderQueryPictFormatsRep *r;
|
||||
XCBRenderPICTSCREENIter si;
|
||||
XCBRenderPICTDEPTHIter di;
|
||||
XCBRenderPICTVISUALIter vi;
|
||||
|
||||
r = XCBRenderQueryPictFormatsReply(c, XCBRenderQueryPictFormats(c), 0);
|
||||
if(!r)
|
||||
return nil;
|
||||
|
||||
for(si = XCBRenderQueryPictFormatsScreensIter(r); si.rem; XCBRenderPICTSCREENNext(&si))
|
||||
for(di = XCBRenderPICTSCREENDepthsIter(si.data); di.rem; XCBRenderPICTDEPTHNext(&di))
|
||||
for(vi = XCBRenderPICTDEPTHVisualsIter(di.data); vi.rem; XCBRenderPICTVISUALNext(&vi))
|
||||
if(vi.data->visual.id == visual.id)
|
||||
{
|
||||
XCBRenderPICTFORMAT ret = vi.data->format;
|
||||
free(r);
|
||||
return ret;
|
||||
}
|
||||
|
||||
return nil;
|
||||
}
|
||||
|
||||
static cairo_content_t
|
||||
_xcb_render_format_to_content (XCBRenderPICTFORMINFO *xrender_format)
|
||||
{
|
||||
|
@ -92,95 +67,6 @@ _xcb_render_format_to_content (XCBRenderPICTFORMINFO *xrender_format)
|
|||
|
||||
}
|
||||
|
||||
/* XXX: Why is this ridiculously complex compared to the equivalent
|
||||
* function in cairo-xlib-surface.c */
|
||||
static XCBRenderPICTFORMINFO
|
||||
_format_from_cairo(XCBConnection *c, cairo_format_t fmt)
|
||||
{
|
||||
XCBRenderPICTFORMINFO ret = {{ 0 }};
|
||||
struct tmpl_t {
|
||||
XCBRenderDIRECTFORMAT direct;
|
||||
CARD8 depth;
|
||||
};
|
||||
static const struct tmpl_t templates[] = {
|
||||
/* CAIRO_FORMAT_ARGB32 */
|
||||
{
|
||||
{
|
||||
16, 0xff,
|
||||
8, 0xff,
|
||||
0, 0xff,
|
||||
24, 0xff
|
||||
},
|
||||
32
|
||||
},
|
||||
/* CAIRO_FORMAT_RGB24 */
|
||||
{
|
||||
{
|
||||
16, 0xff,
|
||||
8, 0xff,
|
||||
0, 0xff,
|
||||
0, 0x00
|
||||
},
|
||||
24
|
||||
},
|
||||
/* CAIRO_FORMAT_A8 */
|
||||
{
|
||||
{
|
||||
0, 0x00,
|
||||
0, 0x00,
|
||||
0, 0x00,
|
||||
0, 0xff
|
||||
},
|
||||
8
|
||||
},
|
||||
/* CAIRO_FORMAT_A1 */
|
||||
{
|
||||
{
|
||||
0, 0x00,
|
||||
0, 0x00,
|
||||
0, 0x00,
|
||||
0, 0x01
|
||||
},
|
||||
1
|
||||
},
|
||||
};
|
||||
const struct tmpl_t *tmpl;
|
||||
XCBRenderQueryPictFormatsRep *r;
|
||||
XCBRenderPICTFORMINFOIter fi;
|
||||
|
||||
if(fmt < 0 || fmt >= (sizeof(templates) / sizeof(*templates)))
|
||||
return ret;
|
||||
tmpl = templates + fmt;
|
||||
|
||||
r = XCBRenderQueryPictFormatsReply(c, XCBRenderQueryPictFormats(c), 0);
|
||||
if(!r)
|
||||
return ret;
|
||||
|
||||
for(fi = XCBRenderQueryPictFormatsFormatsIter(r); fi.rem; XCBRenderPICTFORMINFONext(&fi))
|
||||
{
|
||||
const XCBRenderDIRECTFORMAT *t, *f;
|
||||
if(fi.data->type != XCBRenderPictTypeDirect)
|
||||
continue;
|
||||
if(fi.data->depth != tmpl->depth)
|
||||
continue;
|
||||
t = &tmpl->direct;
|
||||
f = &fi.data->direct;
|
||||
if(t->red_mask && (t->red_mask != f->red_mask || t->red_shift != f->red_shift))
|
||||
continue;
|
||||
if(t->green_mask && (t->green_mask != f->green_mask || t->green_shift != f->green_shift))
|
||||
continue;
|
||||
if(t->blue_mask && (t->blue_mask != f->blue_mask || t->blue_shift != f->blue_shift))
|
||||
continue;
|
||||
if(t->alpha_mask && (t->alpha_mask != f->alpha_mask || t->alpha_shift != f->alpha_shift))
|
||||
continue;
|
||||
|
||||
ret = *fi.data;
|
||||
}
|
||||
|
||||
free(r);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* Instead of taking two round trips for each blending request,
|
||||
* assume that if a particular drawable fails GetImage that it will
|
||||
|
@ -209,6 +95,9 @@ typedef struct cairo_xcb_surface {
|
|||
int height;
|
||||
int depth;
|
||||
|
||||
XCBRECTANGLE *clip_rects;
|
||||
int num_clip_rects;
|
||||
|
||||
XCBRenderPICTURE picture;
|
||||
XCBRenderPICTFORMINFO format;
|
||||
int has_format;
|
||||
|
@ -265,7 +154,7 @@ _cairo_xcb_surface_create_similar (void *abstract_src,
|
|||
XCBDRAWABLE d;
|
||||
cairo_xcb_surface_t *surface;
|
||||
cairo_format_t format = _cairo_format_from_content (content);
|
||||
XCBRenderPICTFORMINFO xrender_format = _format_from_cairo (dpy, format);
|
||||
XCBRenderPICTFORMINFO *xrender_format;
|
||||
|
||||
/* As a good first approximation, if the display doesn't have COMPOSITE,
|
||||
* we're better off using image surfaces for all temporary operations
|
||||
|
@ -280,9 +169,11 @@ _cairo_xcb_surface_create_similar (void *abstract_src,
|
|||
width <= 0 ? 1 : width,
|
||||
height <= 0 ? 1 : height);
|
||||
|
||||
xrender_format = XCBRenderUtilFindStandardFormat (XCBRenderUtilQueryFormats (dpy), format);
|
||||
/* XXX: what to do if xrender_format is null? */
|
||||
surface = (cairo_xcb_surface_t *)
|
||||
cairo_xcb_surface_create_with_xrender_format (dpy, d, src->screen,
|
||||
&xrender_format,
|
||||
xrender_format,
|
||||
width, height);
|
||||
if (surface->base.status) {
|
||||
_cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
|
@ -307,6 +198,8 @@ _cairo_xcb_surface_finish (void *abstract_surface)
|
|||
if (surface->gc.xid)
|
||||
XCBFreeGC (surface->dpy, surface->gc);
|
||||
|
||||
free (surface->clip_rects);
|
||||
|
||||
surface->dpy = NULL;
|
||||
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
|
@ -565,6 +458,26 @@ _get_image_surface (cairo_xcb_surface_t *surface,
|
|||
return CAIRO_STATUS_NO_MEMORY;
|
||||
}
|
||||
|
||||
static void
|
||||
_cairo_xcb_surface_set_picture_clip_rects (cairo_xcb_surface_t *surface)
|
||||
{
|
||||
if (surface->num_clip_rects)
|
||||
XCBRenderSetPictureClipRectangles (surface->dpy, surface->picture,
|
||||
0, 0,
|
||||
surface->num_clip_rects,
|
||||
surface->clip_rects);
|
||||
}
|
||||
|
||||
static void
|
||||
_cairo_xcb_surface_set_gc_clip_rects (cairo_xcb_surface_t *surface)
|
||||
{
|
||||
if (surface->num_clip_rects)
|
||||
XCBSetClipRectangles(surface->dpy, XCBClipOrderingYXSorted, surface->gc,
|
||||
0, 0,
|
||||
surface->num_clip_rects,
|
||||
surface->clip_rects );
|
||||
}
|
||||
|
||||
static void
|
||||
_cairo_xcb_surface_ensure_gc (cairo_xcb_surface_t *surface)
|
||||
{
|
||||
|
@ -573,6 +486,7 @@ _cairo_xcb_surface_ensure_gc (cairo_xcb_surface_t *surface)
|
|||
|
||||
surface->gc = XCBGCONTEXTNew(surface->dpy);
|
||||
XCBCreateGC (surface->dpy, surface->gc, surface->drawable, 0, 0);
|
||||
_cairo_xcb_surface_set_gc_clip_rects(surface);
|
||||
}
|
||||
|
||||
static cairo_status_t
|
||||
|
@ -1000,7 +914,8 @@ _cairo_xcb_surface_composite_trapezoids (cairo_operator_t op,
|
|||
cairo_int_status_t status;
|
||||
int render_reference_x, render_reference_y;
|
||||
int render_src_x, render_src_y;
|
||||
XCBRenderPICTFORMINFO render_format;
|
||||
int cairo_format;
|
||||
XCBRenderPICTFORMINFO *render_format;
|
||||
|
||||
if (!CAIRO_SURFACE_RENDER_HAS_TRAPEZOIDS (dst))
|
||||
return CAIRO_INT_STATUS_UNSUPPORTED;
|
||||
|
@ -1025,30 +940,94 @@ _cairo_xcb_surface_composite_trapezoids (cairo_operator_t op,
|
|||
|
||||
switch (antialias) {
|
||||
case CAIRO_ANTIALIAS_NONE:
|
||||
render_format = _format_from_cairo (dst->dpy, CAIRO_FORMAT_A1);
|
||||
cairo_format = CAIRO_FORMAT_A1;
|
||||
break;
|
||||
default:
|
||||
render_format = _format_from_cairo (dst->dpy, CAIRO_FORMAT_A8);
|
||||
cairo_format = CAIRO_FORMAT_A8;
|
||||
break;
|
||||
}
|
||||
render_format = XCBRenderUtilFindStandardFormat (XCBRenderUtilQueryFormats (dst->dpy), cairo_format);
|
||||
/* XXX: what to do if render_format is null? */
|
||||
|
||||
/* XXX: The XTrapezoid cast is evil and needs to go away somehow. */
|
||||
/* XXX: _format_from_cairo is slow. should cache something. */
|
||||
status = _cairo_xcb_surface_set_attributes (src, &attributes);
|
||||
if (status == CAIRO_STATUS_SUCCESS)
|
||||
XCBRenderTrapezoids (dst->dpy,
|
||||
_render_operator (op),
|
||||
src->picture, dst->picture,
|
||||
render_format.id,
|
||||
render_format->id,
|
||||
render_src_x + attributes.x_offset,
|
||||
render_src_y + attributes.y_offset,
|
||||
num_traps, (XCBRenderTRAP *) traps);
|
||||
num_traps, (XCBRenderTRAPEZOID *) traps);
|
||||
|
||||
_cairo_pattern_release_surface (pattern, &src->base, &attributes);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
static cairo_int_status_t
|
||||
_cairo_xcb_surface_set_clip_region (void *abstract_surface,
|
||||
pixman_region16_t *region)
|
||||
{
|
||||
cairo_xcb_surface_t *surface = abstract_surface;
|
||||
|
||||
if (surface->clip_rects) {
|
||||
free (surface->clip_rects);
|
||||
surface->clip_rects = NULL;
|
||||
}
|
||||
|
||||
surface->num_clip_rects = 0;
|
||||
|
||||
if (region == NULL) {
|
||||
if (surface->gc.xid) {
|
||||
CARD32 mask = XCBGCClipMask;
|
||||
CARD32 pa[] = { XCBNone };
|
||||
|
||||
XCBChangeGC (surface->dpy, surface->gc, mask, pa);
|
||||
}
|
||||
|
||||
if (surface->has_format && surface->picture.xid) {
|
||||
CARD32 mask = XCBRenderCPClipMask;
|
||||
CARD32 pa[] = { XCBNone };
|
||||
|
||||
XCBRenderChangePicture (surface->dpy, surface->picture, mask, pa);
|
||||
}
|
||||
} else {
|
||||
pixman_box16_t *boxes;
|
||||
XCBRECTANGLE *rects = NULL;
|
||||
int n_boxes, i;
|
||||
|
||||
n_boxes = pixman_region_num_rects (region);
|
||||
if (n_boxes > 0) {
|
||||
rects = malloc (sizeof(XCBRECTANGLE) * n_boxes);
|
||||
if (rects == NULL)
|
||||
return CAIRO_STATUS_NO_MEMORY;
|
||||
} else {
|
||||
rects = NULL;
|
||||
}
|
||||
|
||||
boxes = pixman_region_rects (region);
|
||||
|
||||
for (i = 0; i < n_boxes; i++) {
|
||||
rects[i].x = boxes[i].x1;
|
||||
rects[i].y = boxes[i].y1;
|
||||
rects[i].width = boxes[i].x2 - boxes[i].x1;
|
||||
rects[i].height = boxes[i].y2 - boxes[i].y1;
|
||||
}
|
||||
|
||||
surface->clip_rects = rects;
|
||||
surface->num_clip_rects = n_boxes;
|
||||
|
||||
if (surface->gc.xid)
|
||||
_cairo_xcb_surface_set_gc_clip_rects (surface);
|
||||
|
||||
if (surface->picture.xid)
|
||||
_cairo_xcb_surface_set_picture_clip_rects (surface);
|
||||
}
|
||||
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
static cairo_int_status_t
|
||||
_cairo_xcb_surface_get_extents (void *abstract_surface,
|
||||
cairo_rectangle_int16_t *rectangle)
|
||||
|
@ -1078,7 +1057,7 @@ static const cairo_surface_backend_t cairo_xcb_surface_backend = {
|
|||
_cairo_xcb_surface_composite_trapezoids,
|
||||
NULL, /* copy_page */
|
||||
NULL, /* show_page */
|
||||
NULL, /* _cairo_xcb_surface_set_clip_region */
|
||||
_cairo_xcb_surface_set_clip_region,
|
||||
NULL, /* intersect_clip_path */
|
||||
_cairo_xcb_surface_get_extents,
|
||||
NULL, /* old_show_glyphs */
|
||||
|
@ -1103,26 +1082,6 @@ _cairo_surface_is_xcb (cairo_surface_t *surface)
|
|||
return surface->backend == &cairo_xcb_surface_backend;
|
||||
}
|
||||
|
||||
static void
|
||||
query_render_version (XCBConnection *c, cairo_xcb_surface_t *surface)
|
||||
{
|
||||
XCBRenderQueryVersionRep *r;
|
||||
|
||||
surface->render_major = -1;
|
||||
surface->render_minor = -1;
|
||||
|
||||
if (!XCBRenderInit(c))
|
||||
return;
|
||||
|
||||
r = XCBRenderQueryVersionReply(c, XCBRenderQueryVersion(c, 0, 6), 0);
|
||||
if (!r)
|
||||
return;
|
||||
|
||||
surface->render_major = r->major_version;
|
||||
surface->render_minor = r->minor_version;
|
||||
free(r);
|
||||
}
|
||||
|
||||
static cairo_surface_t *
|
||||
_cairo_xcb_surface_create_internal (XCBConnection *dpy,
|
||||
XCBDRAWABLE drawable,
|
||||
|
@ -1134,6 +1093,7 @@ _cairo_xcb_surface_create_internal (XCBConnection *dpy,
|
|||
int depth)
|
||||
{
|
||||
cairo_xcb_surface_t *surface;
|
||||
const XCBRenderQueryVersionRep *r;
|
||||
|
||||
surface = malloc (sizeof (cairo_xcb_surface_t));
|
||||
if (surface == NULL) {
|
||||
|
@ -1163,6 +1123,9 @@ _cairo_xcb_surface_create_internal (XCBConnection *dpy,
|
|||
surface->height = height;
|
||||
surface->depth = depth;
|
||||
|
||||
surface->clip_rects = NULL;
|
||||
surface->num_clip_rects = 0;
|
||||
|
||||
if (format) {
|
||||
surface->depth = format->depth;
|
||||
} else if (visual) {
|
||||
|
@ -1189,30 +1152,40 @@ _cairo_xcb_surface_create_internal (XCBConnection *dpy,
|
|||
;
|
||||
}
|
||||
|
||||
query_render_version(dpy, surface);
|
||||
surface->render_major = -1;
|
||||
surface->render_minor = -1;
|
||||
|
||||
r = XCBRenderUtilQueryVersion(dpy);
|
||||
if (r) {
|
||||
surface->render_major = r->major_version;
|
||||
surface->render_minor = r->minor_version;
|
||||
}
|
||||
|
||||
surface->picture.xid = 0;
|
||||
|
||||
if (CAIRO_SURFACE_RENDER_HAS_CREATE_PICTURE (surface))
|
||||
{
|
||||
XCBRenderPICTFORMAT pict_format = {0};
|
||||
XCBRenderPICTFORMINFO format_info;
|
||||
static const XCBRenderPICTFORMAT nil = { 0 };
|
||||
const XCBRenderPICTFORMAT *pict_format = &nil;
|
||||
|
||||
surface->picture = XCBRenderPICTURENew(dpy);
|
||||
|
||||
if (!format) {
|
||||
if (visual) {
|
||||
pict_format = format_from_visual (dpy, visual->visual_id);
|
||||
} else if (depth == 1) {
|
||||
format_info = _format_from_cairo (dpy, CAIRO_FORMAT_A1);
|
||||
pict_format = format_info.id;
|
||||
}
|
||||
XCBRenderCreatePicture (dpy, surface->picture, drawable,
|
||||
pict_format, 0, NULL);
|
||||
} else {
|
||||
XCBRenderCreatePicture (dpy, surface->picture, drawable,
|
||||
format->id, 0, NULL);
|
||||
if (format) {
|
||||
pict_format = &format->id;
|
||||
} else if (visual) {
|
||||
XCBRenderPICTVISUAL *pict_visual;
|
||||
pict_visual = XCBRenderUtilFindVisualFormat (XCBRenderUtilQueryFormats (dpy), visual->visual_id);
|
||||
if (pict_visual)
|
||||
pict_format = &pict_visual->format;
|
||||
} else if (depth == 1) {
|
||||
XCBRenderPICTFORMINFO *format_info;
|
||||
format_info = XCBRenderUtilFindStandardFormat (XCBRenderUtilQueryFormats (dpy), CAIRO_FORMAT_A1);
|
||||
if (format_info)
|
||||
pict_format = &format_info->id;
|
||||
}
|
||||
|
||||
/* XXX: if pict_format is nil, should we still call CreatePicture? */
|
||||
surface->picture = XCBRenderPICTURENew(dpy);
|
||||
XCBRenderCreatePicture (dpy, surface->picture, drawable,
|
||||
*pict_format, 0, NULL);
|
||||
}
|
||||
|
||||
return (cairo_surface_t *) surface;
|
||||
|
|
|
@ -51,4 +51,10 @@ struct _cairo_xlib_screen_info {
|
|||
cairo_private cairo_xlib_screen_info_t *
|
||||
_cairo_xlib_screen_info_get (Display *display, Screen *screen);
|
||||
|
||||
#if CAIRO_HAS_XLIB_XRENDER_SURFACE
|
||||
|
||||
#include "cairo-xlib-xrender.h"
|
||||
|
||||
#endif
|
||||
|
||||
#endif /* CAIRO_XLIB_PRIVATE_H */
|
||||
|
|
|
@ -219,10 +219,11 @@ _cairo_xlib_surface_create_similar_with_format (void *abstract_src,
|
|||
|
||||
/* 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
|
||||
* using image surfaces for all temporary operations, so return NULL
|
||||
* and let the fallback code happen.
|
||||
*/
|
||||
if (!CAIRO_SURFACE_RENDER_HAS_COMPOSITE(src)) {
|
||||
return cairo_image_surface_create (format, width, height);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
pix = XCreatePixmap (dpy, RootWindowOfScreen (src->screen),
|
||||
|
@ -747,7 +748,7 @@ _draw_image_surface (cairo_xlib_surface_t *surface,
|
|||
int dst_y)
|
||||
{
|
||||
XImage ximage;
|
||||
int bpp, alpha, red, green, blue;
|
||||
unsigned int bpp, alpha, red, green, blue;
|
||||
int native_byte_order = _native_byte_order_lsb () ? LSBFirst : MSBFirst;
|
||||
|
||||
pixman_format_get_masks (pixman_image_get_format (image->pixman_image),
|
||||
|
@ -874,6 +875,9 @@ _cairo_xlib_surface_clone_similar (void *abstract_surface,
|
|||
} else if (_cairo_surface_is_image (src)) {
|
||||
cairo_image_surface_t *image_src = (cairo_image_surface_t *)src;
|
||||
|
||||
if (! CAIRO_FORMAT_VALID (image_src->format))
|
||||
return CAIRO_INT_STATUS_UNSUPPORTED;
|
||||
|
||||
clone = (cairo_xlib_surface_t *)
|
||||
_cairo_xlib_surface_create_similar_with_format (surface, image_src->format,
|
||||
image_src->width, image_src->height);
|
||||
|
@ -934,7 +938,7 @@ static cairo_status_t
|
|||
_cairo_xlib_surface_set_filter (cairo_xlib_surface_t *surface,
|
||||
cairo_filter_t filter)
|
||||
{
|
||||
char *render_filter;
|
||||
const char *render_filter;
|
||||
|
||||
if (!surface->src_picture)
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
|
@ -963,13 +967,19 @@ _cairo_xlib_surface_set_filter (cairo_xlib_surface_t *surface,
|
|||
case CAIRO_FILTER_BILINEAR:
|
||||
render_filter = FilterBilinear;
|
||||
break;
|
||||
case CAIRO_FILTER_GAUSSIAN:
|
||||
/* XXX: The GAUSSIAN value has no implementation in cairo
|
||||
* whatsoever, so it was really a mistake to have it in the
|
||||
* API. We could fix this by officially deprecating it, or
|
||||
* else inventing semantics and providing an actual
|
||||
* implementation for it. */
|
||||
default:
|
||||
render_filter = FilterBest;
|
||||
break;
|
||||
}
|
||||
|
||||
XRenderSetPictureFilter (surface->dpy, surface->src_picture,
|
||||
render_filter, NULL, 0);
|
||||
(char *) render_filter, NULL, 0);
|
||||
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
|
@ -1372,6 +1382,7 @@ _cairo_xlib_surface_composite (cairo_operator_t op,
|
|||
dst_x, dst_y, width, height);
|
||||
break;
|
||||
|
||||
case DO_UNSUPPORTED:
|
||||
default:
|
||||
ASSERT_NOT_REACHED;
|
||||
}
|
||||
|
@ -1561,6 +1572,9 @@ _cairo_xlib_surface_composite_trapezoids (cairo_operator_t op,
|
|||
case CAIRO_ANTIALIAS_NONE:
|
||||
pict_format = XRenderFindStandardFormat (dst->dpy, PictStandardA1);
|
||||
break;
|
||||
case CAIRO_ANTIALIAS_GRAY:
|
||||
case CAIRO_ANTIALIAS_SUBPIXEL:
|
||||
case CAIRO_ANTIALIAS_DEFAULT:
|
||||
default:
|
||||
pict_format = XRenderFindStandardFormat (dst->dpy, PictStandardA8);
|
||||
break;
|
||||
|
@ -2423,7 +2437,7 @@ _cairo_xlib_surface_add_glyph (Display *dpy,
|
|||
break;
|
||||
case CAIRO_FORMAT_ARGB32:
|
||||
if (_native_byte_order_lsb() != (ImageByteOrder (dpy) == LSBFirst)) {
|
||||
int c = glyph_surface->stride * glyph_surface->height;
|
||||
unsigned int c = glyph_surface->stride * glyph_surface->height;
|
||||
unsigned char *d;
|
||||
unsigned char *new, *n;
|
||||
|
||||
|
@ -2434,7 +2448,7 @@ _cairo_xlib_surface_add_glyph (Display *dpy,
|
|||
}
|
||||
n = new;
|
||||
d = data;
|
||||
while ((c -= 4) >= 0)
|
||||
while (c >= 4)
|
||||
{
|
||||
n[3] = d[0];
|
||||
n[2] = d[1];
|
||||
|
@ -2442,6 +2456,7 @@ _cairo_xlib_surface_add_glyph (Display *dpy,
|
|||
n[0] = d[3];
|
||||
d += 4;
|
||||
n += 4;
|
||||
c -= 4;
|
||||
}
|
||||
data = new;
|
||||
}
|
||||
|
@ -2674,12 +2689,13 @@ _cairo_xlib_surface_show_glyphs (void *abstract_dst,
|
|||
cairo_surface_attributes_t attributes;
|
||||
cairo_xlib_surface_t *src = NULL;
|
||||
|
||||
cairo_glyph_t *output_glyphs;
|
||||
const cairo_glyph_t *glyphs_chunk;
|
||||
int glyphs_remaining, chunk_size, max_chunk_size;
|
||||
cairo_scaled_glyph_t *scaled_glyph;
|
||||
cairo_xlib_surface_font_private_t *font_private;
|
||||
|
||||
int i;
|
||||
int i, o;
|
||||
unsigned long max_index = 0;
|
||||
|
||||
cairo_xlib_surface_show_glyphs_func_t show_glyphs_func;
|
||||
|
@ -2723,6 +2739,13 @@ _cairo_xlib_surface_show_glyphs (void *abstract_dst,
|
|||
(font_private != NULL && font_private->dpy != dst->dpy))
|
||||
return CAIRO_INT_STATUS_UNSUPPORTED;
|
||||
|
||||
/* We make a copy of the glyphs so that we can elide any size-zero
|
||||
* glyphs to workaround an X server bug, (present in at least Xorg
|
||||
* 7.1 without EXA). */
|
||||
output_glyphs = malloc (num_glyphs * sizeof (cairo_glyph_t));
|
||||
if (output_glyphs == NULL)
|
||||
return CAIRO_STATUS_NO_MEMORY;
|
||||
|
||||
/* After passing all those tests, we're now committed to rendering
|
||||
* these glyphs or to fail trying. We first upload any glyphs to
|
||||
* the X server that it doesn't have already, then we draw
|
||||
|
@ -2781,7 +2804,7 @@ _cairo_xlib_surface_show_glyphs (void *abstract_dst,
|
|||
goto BAIL;
|
||||
|
||||
/* Send all unsent glyphs to the server, and count the max of the glyph indices */
|
||||
for (i = 0; i < num_glyphs; i++) {
|
||||
for (i = 0, o = 0; i < num_glyphs; i++) {
|
||||
if (glyphs[i].index > max_index)
|
||||
max_index = glyphs[i].index;
|
||||
status = _cairo_scaled_glyph_lookup (scaled_font,
|
||||
|
@ -2790,11 +2813,18 @@ _cairo_xlib_surface_show_glyphs (void *abstract_dst,
|
|||
&scaled_glyph);
|
||||
if (status != CAIRO_STATUS_SUCCESS)
|
||||
goto BAIL;
|
||||
if (scaled_glyph->surface_private == NULL) {
|
||||
_cairo_xlib_surface_add_glyph (dst->dpy, scaled_font, scaled_glyph);
|
||||
scaled_glyph->surface_private = (void *) 1;
|
||||
/* Don't put any size-zero glyphs into output_glyphs to avoid
|
||||
* an X server bug which stops rendering glyphs after the
|
||||
* first size-zero glyph. */
|
||||
if (scaled_glyph->surface->width && scaled_glyph->surface->height) {
|
||||
output_glyphs[o++] = glyphs[i];
|
||||
if (scaled_glyph->surface_private == NULL) {
|
||||
_cairo_xlib_surface_add_glyph (dst->dpy, scaled_font, scaled_glyph);
|
||||
scaled_glyph->surface_private = (void *) 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
num_glyphs = o;
|
||||
|
||||
_cairo_xlib_surface_ensure_dst_picture (dst);
|
||||
|
||||
|
@ -2811,7 +2841,7 @@ _cairo_xlib_surface_show_glyphs (void *abstract_dst,
|
|||
}
|
||||
max_chunk_size /= sz_xGlyphElt;
|
||||
|
||||
for (glyphs_remaining = num_glyphs, glyphs_chunk = glyphs;
|
||||
for (glyphs_remaining = num_glyphs, glyphs_chunk = output_glyphs;
|
||||
glyphs_remaining;
|
||||
glyphs_remaining -= chunk_size, glyphs_chunk += chunk_size)
|
||||
{
|
||||
|
@ -2826,6 +2856,7 @@ _cairo_xlib_surface_show_glyphs (void *abstract_dst,
|
|||
|
||||
BAIL:
|
||||
_cairo_scaled_font_thaw_cache (scaled_font);
|
||||
free (output_glyphs);
|
||||
|
||||
if (src)
|
||||
_cairo_pattern_release_surface (src_pattern, &src->base, &attributes);
|
||||
|
|
|
@ -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
|
||||
|
@ -44,7 +45,7 @@
|
|||
#define CAIRO_TOLERANCE_MINIMUM 0.0002 /* We're limited by 16 bits of sub-pixel precision */
|
||||
|
||||
static const cairo_t cairo_nil = {
|
||||
(unsigned int)-1, /* ref_count */
|
||||
CAIRO_REF_COUNT_INVALID, /* ref_count */
|
||||
CAIRO_STATUS_NO_MEMORY, /* status */
|
||||
{ /* path */
|
||||
NULL, NULL, /* op_buf_head, op_buf_tail */
|
||||
|
@ -62,7 +63,7 @@ static const cairo_t cairo_nil = {
|
|||
* 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_DSC_COMMENT
|
||||
#define CAIRO_STATUS_LAST_STATUS CAIRO_STATUS_INVALID_INDEX
|
||||
|
||||
/**
|
||||
* _cairo_error:
|
||||
|
@ -206,6 +207,7 @@ cairo_create (cairo_surface_t *target)
|
|||
|
||||
return cr;
|
||||
}
|
||||
slim_hidden_def (cairo_create);
|
||||
|
||||
/**
|
||||
* cairo_reference:
|
||||
|
@ -223,7 +225,7 @@ cairo_reference (cairo_t *cr)
|
|||
if (cr == NULL)
|
||||
return NULL;
|
||||
|
||||
if (cr->ref_count == (unsigned int)-1)
|
||||
if (cr->ref_count == CAIRO_REF_COUNT_INVALID)
|
||||
return cr;
|
||||
|
||||
assert (cr->ref_count > 0);
|
||||
|
@ -247,7 +249,7 @@ cairo_destroy (cairo_t *cr)
|
|||
if (cr == NULL)
|
||||
return;
|
||||
|
||||
if (cr->ref_count == (unsigned int)-1)
|
||||
if (cr->ref_count == CAIRO_REF_COUNT_INVALID)
|
||||
return;
|
||||
|
||||
assert (cr->ref_count > 0);
|
||||
|
@ -267,6 +269,7 @@ cairo_destroy (cairo_t *cr)
|
|||
|
||||
free (cr);
|
||||
}
|
||||
slim_hidden_def (cairo_destroy);
|
||||
|
||||
/**
|
||||
* cairo_save:
|
||||
|
@ -571,6 +574,7 @@ cairo_set_operator (cairo_t *cr, cairo_operator_t op)
|
|||
if (cr->status)
|
||||
_cairo_set_error (cr, cr->status);
|
||||
}
|
||||
slim_hidden_def (cairo_set_operator);
|
||||
|
||||
/**
|
||||
* cairo_set_source_rgb
|
||||
|
@ -674,6 +678,7 @@ cairo_set_source_surface (cairo_t *cr,
|
|||
cairo_set_source (cr, pattern);
|
||||
cairo_pattern_destroy (pattern);
|
||||
}
|
||||
slim_hidden_def (cairo_set_source_surface);
|
||||
|
||||
/**
|
||||
* cairo_set_source
|
||||
|
@ -714,6 +719,7 @@ cairo_set_source (cairo_t *cr, cairo_pattern_t *source)
|
|||
if (cr->status)
|
||||
_cairo_set_error (cr, cr->status);
|
||||
}
|
||||
slim_hidden_def (cairo_set_source);
|
||||
|
||||
/**
|
||||
* cairo_get_source:
|
||||
|
@ -928,10 +934,10 @@ cairo_set_line_join (cairo_t *cr, cairo_line_join_t line_join)
|
|||
* #CAIRO_STATUS_INVALID_DASH.
|
||||
**/
|
||||
void
|
||||
cairo_set_dash (cairo_t *cr,
|
||||
double *dashes,
|
||||
int num_dashes,
|
||||
double offset)
|
||||
cairo_set_dash (cairo_t *cr,
|
||||
const double *dashes,
|
||||
int num_dashes,
|
||||
double offset)
|
||||
{
|
||||
if (cr->status)
|
||||
return;
|
||||
|
@ -942,6 +948,64 @@ cairo_set_dash (cairo_t *cr,
|
|||
_cairo_set_error (cr, cr->status);
|
||||
}
|
||||
|
||||
/**
|
||||
* cairo_get_dash_count:
|
||||
* @cr: a #cairo_t
|
||||
* @count: return value for the number of dash values, or %NULL
|
||||
*
|
||||
* Gets the length of the dash array in @cr.
|
||||
*
|
||||
* Return value: %CAIRO_STATUS_SUCCESS, or error status set on
|
||||
* @cr.
|
||||
*
|
||||
* Since: 1.4
|
||||
*/
|
||||
cairo_status_t
|
||||
cairo_get_dash_count (cairo_t *cr,
|
||||
int *count)
|
||||
{
|
||||
if (cr->status)
|
||||
return cr->status;
|
||||
|
||||
if (count)
|
||||
*count = cr->gstate->stroke_style.num_dashes;
|
||||
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* cairo_get_dash:
|
||||
* @cr: a #cairo_t
|
||||
* @dashes: return value for the dash array, or %NULL
|
||||
* @offset: return value for the current dash offset, or %NULL
|
||||
*
|
||||
* Gets the current dash array. If not %NULL, @dashes should be big
|
||||
* enough to hold at least the number of values returned by
|
||||
* cairo_get_dash_count().
|
||||
*
|
||||
* Return value: %CAIRO_STATUS_SUCCESS, or error status set on
|
||||
* @cr.
|
||||
*
|
||||
* Since: 1.4
|
||||
**/
|
||||
cairo_status_t
|
||||
cairo_get_dash (cairo_t *cr,
|
||||
double *dashes,
|
||||
double *offset)
|
||||
{
|
||||
if (cr->status)
|
||||
return cr->status;
|
||||
|
||||
memcpy (dashes,
|
||||
cr->gstate->stroke_style.dash,
|
||||
sizeof(double) * cr->gstate->stroke_style.num_dashes);
|
||||
|
||||
if (offset)
|
||||
*offset = cr->gstate->stroke_style.dash_offset;
|
||||
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
void
|
||||
cairo_set_miter_limit (cairo_t *cr, double limit)
|
||||
{
|
||||
|
@ -1268,6 +1332,7 @@ cairo_line_to (cairo_t *cr, double x, double y)
|
|||
if (cr->status)
|
||||
_cairo_set_error (cr, cr->status);
|
||||
}
|
||||
slim_hidden_def (cairo_line_to);
|
||||
|
||||
/**
|
||||
* cairo_curve_to:
|
||||
|
@ -1321,6 +1386,7 @@ cairo_curve_to (cairo_t *cr,
|
|||
if (cr->status)
|
||||
_cairo_set_error (cr, cr->status);
|
||||
}
|
||||
slim_hidden_def (cairo_curve_to);
|
||||
|
||||
/**
|
||||
* cairo_arc:
|
||||
|
@ -1645,6 +1711,14 @@ cairo_stroke_to_path (cairo_t *cr)
|
|||
*
|
||||
* If there is no current point before the call to cairo_close_path,
|
||||
* this function will have no effect.
|
||||
*
|
||||
* Note: As of cairo version 1.2.4 any call to cairo_close_path will
|
||||
* place an explicit MOVE_TO element into the path immediately after
|
||||
* the CLOSE_PATH element, (which can be seen in cairo_copy_path() for
|
||||
* example). This can simplify path processing in some cases as it may
|
||||
* not be necessary to save the "last move_to point" during processing
|
||||
* as the MOVE_TO immediately after the CLOSE_PATH will provide that
|
||||
* point.
|
||||
**/
|
||||
void
|
||||
cairo_close_path (cairo_t *cr)
|
||||
|
@ -1675,6 +1749,7 @@ cairo_paint (cairo_t *cr)
|
|||
if (cr->status)
|
||||
_cairo_set_error (cr, cr->status);
|
||||
}
|
||||
slim_hidden_def (cairo_paint);
|
||||
|
||||
/**
|
||||
* cairo_paint_with_alpha:
|
||||
|
@ -1722,7 +1797,7 @@ cairo_paint_with_alpha (cairo_t *cr,
|
|||
*
|
||||
* A drawing operator that paints the current source
|
||||
* using the alpha channel of @pattern as a mask. (Opaque
|
||||
* areas of @mask are painted with the source, transparent
|
||||
* areas of @pattern are painted with the source, transparent
|
||||
* areas are not painted.)
|
||||
*/
|
||||
void
|
||||
|
@ -1746,6 +1821,7 @@ cairo_mask (cairo_t *cr,
|
|||
if (cr->status)
|
||||
_cairo_set_error (cr, cr->status);
|
||||
}
|
||||
slim_hidden_def (cairo_mask);
|
||||
|
||||
/**
|
||||
* cairo_mask_surface:
|
||||
|
@ -1887,6 +1963,15 @@ cairo_fill_preserve (cairo_t *cr)
|
|||
}
|
||||
slim_hidden_def(cairo_fill_preserve);
|
||||
|
||||
/**
|
||||
* cairo_copy_page:
|
||||
* @cr: a cairo context
|
||||
*
|
||||
* Emits the current page for backends that support multiple pages, but
|
||||
* doesn't clear it, so, the contents of the current page will be retained
|
||||
* for the next page too. Use cairo_show_page() if you want to get an
|
||||
* empty page after the emission.
|
||||
**/
|
||||
void
|
||||
cairo_copy_page (cairo_t *cr)
|
||||
{
|
||||
|
@ -1898,6 +1983,13 @@ cairo_copy_page (cairo_t *cr)
|
|||
_cairo_set_error (cr, cr->status);
|
||||
}
|
||||
|
||||
/**
|
||||
* cairo_show_page:
|
||||
* @cr: a cairo context
|
||||
*
|
||||
* Emits and clears the current page for backends that support multiple
|
||||
* pages. Use cairo_copy_page() if you don't want to clear the page.
|
||||
**/
|
||||
void
|
||||
cairo_show_page (cairo_t *cr)
|
||||
{
|
||||
|
@ -1909,6 +2001,20 @@ cairo_show_page (cairo_t *cr)
|
|||
_cairo_set_error (cr, cr->status);
|
||||
}
|
||||
|
||||
/**
|
||||
* cairo_in_stroke:
|
||||
* @cr: a cairo context
|
||||
* @x: X coordinate of the point to test
|
||||
* @y: Y coordinate of the point to test
|
||||
*
|
||||
* Tests whether the given point is on the area stroked by doing a
|
||||
* cairo_stroke() operation on @cr given the current path and stroking
|
||||
* parameters.
|
||||
*
|
||||
* See cairo_stroke, cairo_set_line_width(), cairo_set_line_join(),
|
||||
* cairo_set_line_cap(), cairo_set_dash(), and
|
||||
* cairo_stroke_preserve().
|
||||
**/
|
||||
cairo_bool_t
|
||||
cairo_in_stroke (cairo_t *cr, double x, double y)
|
||||
{
|
||||
|
@ -1926,6 +2032,18 @@ cairo_in_stroke (cairo_t *cr, double x, double y)
|
|||
return inside;
|
||||
}
|
||||
|
||||
/**
|
||||
* cairo_in_fill:
|
||||
* @cr: a cairo context
|
||||
* @x: X coordinate of the point to test
|
||||
* @y: Y coordinate of the point to test
|
||||
*
|
||||
* Tests whether the given point is on the area filled by doing a
|
||||
* cairo_stroke() operation on @cr given the current path and filling
|
||||
* parameters.
|
||||
*
|
||||
* See cairo_fill(), cairo_set_fill_rule() and cairo_fill_preserve().
|
||||
**/
|
||||
cairo_bool_t
|
||||
cairo_in_fill (cairo_t *cr, double x, double y)
|
||||
{
|
||||
|
@ -1945,6 +2063,19 @@ cairo_in_fill (cairo_t *cr, double x, double y)
|
|||
return inside;
|
||||
}
|
||||
|
||||
/**
|
||||
* cairo_stroke_extents:
|
||||
* @cr: a cairo context
|
||||
* @x1: left of the resulting extents
|
||||
* @y1: top of the resulting extents
|
||||
* @x2: right of the resulting extents
|
||||
* @y2: bottom of the resulting extents
|
||||
*
|
||||
* Computes a bounding box in user coordinates covering all area that will
|
||||
* be stroked by the current path with the current stroking parameters. If
|
||||
* the current path is empty, returns an empty rectangle. Surface dimensions
|
||||
* and clipping are not taken into account.
|
||||
**/
|
||||
void
|
||||
cairo_stroke_extents (cairo_t *cr,
|
||||
double *x1, double *y1, double *x2, double *y2)
|
||||
|
@ -1959,6 +2090,19 @@ cairo_stroke_extents (cairo_t *cr,
|
|||
_cairo_set_error (cr, cr->status);
|
||||
}
|
||||
|
||||
/**
|
||||
* cairo_fill_extents:
|
||||
* @cr: a cairo context
|
||||
* @x1: left of the resulting extents
|
||||
* @y1: top of the resulting extents
|
||||
* @x2: right of the resulting extents
|
||||
* @y2: bottom of the resulting extents
|
||||
*
|
||||
* Computes a bounding box in user coordinates covering all area that will
|
||||
* be filled by the current path. If the current path is empty, returns an
|
||||
* empty rectangle. Surface dimensions and clipping are not taken into
|
||||
* account.
|
||||
**/
|
||||
void
|
||||
cairo_fill_extents (cairo_t *cr,
|
||||
double *x1, double *y1, double *x2, double *y2)
|
||||
|
@ -2064,6 +2208,67 @@ cairo_reset_clip (cairo_t *cr)
|
|||
_cairo_set_error (cr, cr->status);
|
||||
}
|
||||
|
||||
/**
|
||||
* cairo_clip_extents:
|
||||
* @cr: a cairo context
|
||||
* @x1: left of the resulting extents
|
||||
* @y1: top of the resulting extents
|
||||
* @x2: right of the resulting extents
|
||||
* @y2: bottom of the resulting extents
|
||||
*
|
||||
* Computes a bounding box in user coordinates covering the area inside the
|
||||
* current clip.
|
||||
**/
|
||||
void
|
||||
cairo_clip_extents (cairo_t *cr,
|
||||
double *x1, double *y1,
|
||||
double *x2, double *y2)
|
||||
{
|
||||
if (cr->status)
|
||||
return;
|
||||
|
||||
cr->status = _cairo_gstate_clip_extents (cr->gstate, x1, y1, x2, y2);
|
||||
if (cr->status)
|
||||
_cairo_set_error (cr, cr->status);
|
||||
}
|
||||
|
||||
static cairo_rectangle_list_t *
|
||||
_cairo_rectangle_list_create_for_status (cairo_status_t status)
|
||||
{
|
||||
cairo_rectangle_list_t *list;
|
||||
|
||||
list = malloc (sizeof (cairo_rectangle_list_t));
|
||||
if (list == NULL)
|
||||
return (cairo_rectangle_list_t*) &_cairo_rectangles_nil;
|
||||
list->status = status;
|
||||
list->rectangles = NULL;
|
||||
list->num_rectangles = 0;
|
||||
return list;
|
||||
}
|
||||
|
||||
/**
|
||||
* cairo_copy_clip_rectangles:
|
||||
*
|
||||
* Returns the current clip region as a list of rectangles in user coordinates.
|
||||
* Never returns %NULL.
|
||||
*
|
||||
* The status in the list may be CAIRO_STATUS_CLIP_NOT_REPRESENTABLE to
|
||||
* indicate that the clip region cannot be represented as a list of
|
||||
* user-space rectangles. The status may have other values to indicate
|
||||
* other errors.
|
||||
*
|
||||
* The caller must always call cairo_rectangle_list_destroy on the result of
|
||||
* this function.
|
||||
**/
|
||||
cairo_rectangle_list_t *
|
||||
cairo_copy_clip_rectangles (cairo_t *cr)
|
||||
{
|
||||
if (cr->status)
|
||||
return _cairo_rectangle_list_create_for_status (cr->status);
|
||||
|
||||
return _cairo_gstate_copy_clip_rectangles (cr->gstate);
|
||||
}
|
||||
|
||||
/**
|
||||
* cairo_select_font_face:
|
||||
* @cr: a #cairo_t
|
||||
|
@ -2478,7 +2683,7 @@ cairo_show_text (cairo_t *cr, const char *utf8)
|
|||
}
|
||||
|
||||
void
|
||||
cairo_show_glyphs (cairo_t *cr, cairo_glyph_t *glyphs, int num_glyphs)
|
||||
cairo_show_glyphs (cairo_t *cr, const cairo_glyph_t *glyphs, int num_glyphs)
|
||||
{
|
||||
if (cr->status)
|
||||
return;
|
||||
|
@ -2564,6 +2769,7 @@ cairo_get_tolerance (cairo_t *cr)
|
|||
{
|
||||
return _cairo_gstate_get_tolerance (cr->gstate);
|
||||
}
|
||||
slim_hidden_def (cairo_get_tolerance);
|
||||
|
||||
/**
|
||||
* cairo_get_antialias:
|
||||
|
@ -2707,6 +2913,7 @@ cairo_get_matrix (cairo_t *cr, cairo_matrix_t *matrix)
|
|||
{
|
||||
_cairo_gstate_get_matrix (cr->gstate, matrix);
|
||||
}
|
||||
slim_hidden_def (cairo_get_matrix);
|
||||
|
||||
/**
|
||||
* cairo_get_target:
|
||||
|
@ -2862,7 +3069,8 @@ cairo_append_path (cairo_t *cr,
|
|||
}
|
||||
|
||||
if (path->status) {
|
||||
if (path->status <= CAIRO_STATUS_LAST_STATUS)
|
||||
if (path->status > CAIRO_STATUS_SUCCESS &&
|
||||
path->status <= CAIRO_STATUS_LAST_STATUS)
|
||||
_cairo_set_error (cr, path->status);
|
||||
else
|
||||
_cairo_set_error (cr, CAIRO_STATUS_INVALID_STATUS);
|
||||
|
@ -2892,6 +3100,7 @@ cairo_status (cairo_t *cr)
|
|||
{
|
||||
return cr->status;
|
||||
}
|
||||
slim_hidden_def (cairo_status);
|
||||
|
||||
/**
|
||||
* cairo_status_to_string:
|
||||
|
@ -2947,6 +3156,10 @@ cairo_status_to_string (cairo_status_t status)
|
|||
return "invalid value for a dash setting";
|
||||
case CAIRO_STATUS_INVALID_DSC_COMMENT:
|
||||
return "invalid value for a DSC comment";
|
||||
case CAIRO_STATUS_INVALID_INDEX:
|
||||
return "invalid index passed to getter";
|
||||
case CAIRO_STATUS_CLIP_NOT_REPRESENTABLE:
|
||||
return "clip region not representable in desired format";
|
||||
}
|
||||
|
||||
return "<unknown error status>";
|
||||
|
@ -2960,42 +3173,3 @@ _cairo_restrict_value (double *value, double min, double max)
|
|||
else if (*value > max)
|
||||
*value = max;
|
||||
}
|
||||
|
||||
/**
|
||||
* cairo_has_clip
|
||||
* @cr: a cairo context
|
||||
*
|
||||
* Returns TRUE if the cairo context has any clipping active, otherwise
|
||||
* FALSE.
|
||||
*/
|
||||
cairo_bool_t
|
||||
cairo_has_clip (cairo_t *cr)
|
||||
{
|
||||
if (cr->status)
|
||||
return FALSE;
|
||||
return _cairo_gstate_has_clip (cr->gstate);
|
||||
}
|
||||
|
||||
/**
|
||||
* cairo_extract_clip_rectangles
|
||||
* @cr: a cairo context
|
||||
* @max_rectangles: the maximum number of rectangles to be returned
|
||||
* @rectangles_out: the output buffer for the rectangles
|
||||
* @num_rectangles_out: the number of rectangles returned
|
||||
*
|
||||
* If the current clip can be expressed as the union of at most
|
||||
* 'max_rectangles' device-coordinate rectangles, then we fill in the array
|
||||
* with the rectangles, and return True. Otherwise we return False. When there
|
||||
* is no clipping active, we return False.
|
||||
*/
|
||||
cairo_bool_t
|
||||
cairo_extract_clip_rectangles (cairo_t *cr,
|
||||
int max_rectangles,
|
||||
cairo_clip_rect_t *rectangles_out,
|
||||
int *num_rectangles_out)
|
||||
{
|
||||
if (cr->status)
|
||||
return FALSE;
|
||||
return _cairo_gstate_extract_clip_rectangles (cr->gstate, max_rectangles,
|
||||
rectangles_out, num_rectangles_out);
|
||||
}
|
||||
|
|
|
@ -39,6 +39,7 @@
|
|||
#define CAIRO_H
|
||||
|
||||
#include <cairo-features.h>
|
||||
#include <cairo-deprecated.h>
|
||||
|
||||
CAIRO_BEGIN_DECLS
|
||||
|
||||
|
@ -168,12 +169,16 @@ typedef struct _cairo_user_data_key {
|
|||
* @CAIRO_STATUS_FILE_NOT_FOUND: file not found
|
||||
* @CAIRO_STATUS_INVALID_DASH: invalid value for a dash setting
|
||||
* @CAIRO_STATUS_INVALID_DSC_COMMENT: invalid value for a DSC comment (Since 1.2)
|
||||
* @CAIRO_STATUS_INVALID_INDEX: invalid index value for a getter (Since 1.3+)
|
||||
* @CAIRO_STATUS_INVALID_INDEX: invalid index passed to getter
|
||||
* @CAIRO_STATUS_CLIP_NOT_REPRESENTABLE: clip region not representable in desired format (Since 1.4)
|
||||
*
|
||||
* #cairo_status_t is used to indicate errors that can occur when
|
||||
* using Cairo. In some cases it is returned directly by functions.
|
||||
* but when using #cairo_t, the last error, if any, is stored in
|
||||
* the context and can be retrieved with cairo_status().
|
||||
*
|
||||
* New entries may be added in future versions. Use cairo_status_to_string()
|
||||
* to get a human-readable representation of an error message.
|
||||
**/
|
||||
typedef enum _cairo_status {
|
||||
CAIRO_STATUS_SUCCESS = 0,
|
||||
|
@ -197,7 +202,8 @@ typedef enum _cairo_status {
|
|||
CAIRO_STATUS_FILE_NOT_FOUND,
|
||||
CAIRO_STATUS_INVALID_DASH,
|
||||
CAIRO_STATUS_INVALID_DSC_COMMENT,
|
||||
CAIRO_STATUS_INVALID_INDEX
|
||||
CAIRO_STATUS_INVALID_INDEX,
|
||||
CAIRO_STATUS_CLIP_NOT_REPRESENTABLE
|
||||
} cairo_status_t;
|
||||
|
||||
/**
|
||||
|
@ -376,6 +382,8 @@ cairo_set_antialias (cairo_t *cr, cairo_antialias_t antialias);
|
|||
* or have a tricky intersection such as intersecting tangent to the path.
|
||||
* (Note that filling is not actually implemented in this way. This
|
||||
* is just a description of the rule that is applied.)
|
||||
*
|
||||
* New entries may be added in future versions.
|
||||
**/
|
||||
typedef enum _cairo_fill_rule {
|
||||
CAIRO_FILL_RULE_WINDING,
|
||||
|
@ -415,10 +423,10 @@ cairo_public void
|
|||
cairo_set_line_join (cairo_t *cr, cairo_line_join_t line_join);
|
||||
|
||||
cairo_public void
|
||||
cairo_set_dash (cairo_t *cr,
|
||||
double *dashes,
|
||||
int num_dashes,
|
||||
double offset);
|
||||
cairo_set_dash (cairo_t *cr,
|
||||
const double *dashes,
|
||||
int num_dashes,
|
||||
double offset);
|
||||
|
||||
cairo_public void
|
||||
cairo_set_miter_limit (cairo_t *cr, double limit);
|
||||
|
@ -583,6 +591,38 @@ cairo_clip (cairo_t *cr);
|
|||
cairo_public void
|
||||
cairo_clip_preserve (cairo_t *cr);
|
||||
|
||||
cairo_public void
|
||||
cairo_clip_extents (cairo_t *cr,
|
||||
double *x1, double *y1,
|
||||
double *x2, double *y2);
|
||||
|
||||
/**
|
||||
* cairo_rectangle_t:
|
||||
*
|
||||
* A data structure for holding a rectangle.
|
||||
*/
|
||||
typedef struct _cairo_rectangle {
|
||||
double x, y, width, height;
|
||||
} cairo_rectangle_t;
|
||||
|
||||
/**
|
||||
* cairo_rectangle_list_t:
|
||||
*
|
||||
* A data structure for holding a dynamically allocated
|
||||
* array of rectangles.
|
||||
*/
|
||||
typedef struct _cairo_rectangle_list {
|
||||
cairo_status_t status;
|
||||
cairo_rectangle_t *rectangles;
|
||||
int num_rectangles;
|
||||
} cairo_rectangle_list_t;
|
||||
|
||||
cairo_public cairo_rectangle_list_t *
|
||||
cairo_copy_clip_rectangles (cairo_t *cr);
|
||||
|
||||
cairo_public void
|
||||
cairo_rectangle_list_destroy (cairo_rectangle_list_t *rectangle_list);
|
||||
|
||||
/* Font/Text functions */
|
||||
|
||||
/**
|
||||
|
@ -777,6 +817,8 @@ typedef enum _cairo_subpixel_order {
|
|||
* involves distorting them, it also reduces the faithfulness
|
||||
* to the original outline shapes. Not all of the outline hinting
|
||||
* styles are supported by all font backends.
|
||||
*
|
||||
* New entries may be added in future versions.
|
||||
*/
|
||||
typedef enum _cairo_hint_style {
|
||||
CAIRO_HINT_STYLE_DEFAULT,
|
||||
|
@ -889,7 +931,7 @@ cairo_public void
|
|||
cairo_show_text (cairo_t *cr, const char *utf8);
|
||||
|
||||
cairo_public void
|
||||
cairo_show_glyphs (cairo_t *cr, cairo_glyph_t *glyphs, int num_glyphs);
|
||||
cairo_show_glyphs (cairo_t *cr, const cairo_glyph_t *glyphs, int num_glyphs);
|
||||
|
||||
cairo_public cairo_font_face_t *
|
||||
cairo_get_font_face (cairo_t *cr);
|
||||
|
@ -961,6 +1003,8 @@ cairo_font_face_status (cairo_font_face_t *font_face);
|
|||
* The behavior of calling a type-specific function with a scaled font
|
||||
* of the wrong type is undefined.
|
||||
*
|
||||
* New entries may be added in future versions.
|
||||
*
|
||||
* Since: 1.2
|
||||
*/
|
||||
typedef enum _cairo_font_type {
|
||||
|
@ -1065,7 +1109,11 @@ cairo_get_line_join (cairo_t *cr);
|
|||
cairo_public double
|
||||
cairo_get_miter_limit (cairo_t *cr);
|
||||
|
||||
/* XXX: How to do cairo_get_dash??? Do we want to switch to a cairo_dash object? */
|
||||
cairo_public cairo_status_t
|
||||
cairo_get_dash_count (cairo_t *cr, int *count);
|
||||
|
||||
cairo_public cairo_status_t
|
||||
cairo_get_dash (cairo_t *cr, double *dashes, double *offset);
|
||||
|
||||
cairo_public void
|
||||
cairo_get_matrix (cairo_t *cr, cairo_matrix_t *matrix);
|
||||
|
@ -1160,8 +1208,8 @@ union _cairo_path_data_t {
|
|||
* @num_data: the number of elements in the data array
|
||||
*
|
||||
* A data structure for holding a path. This data structure serves as
|
||||
* the return value for cairo_copy_path_data() and
|
||||
* cairo_copy_path_data_flat() as well the input value for
|
||||
* the return value for cairo_copy_path() and
|
||||
* cairo_copy_path_flat() as well the input value for
|
||||
* cairo_append_path().
|
||||
*
|
||||
* See #cairo_path_data_t for hints on how to iterate over the
|
||||
|
@ -1191,24 +1239,6 @@ cairo_append_path (cairo_t *cr,
|
|||
cairo_public void
|
||||
cairo_path_destroy (cairo_path_t *path);
|
||||
|
||||
/**
|
||||
* cairo_clip_rect_t:
|
||||
*
|
||||
* A data structure for holding clip rectangles.
|
||||
*/
|
||||
typedef struct _cairo_clip_rect {
|
||||
double x, y, width, height;
|
||||
} cairo_clip_rect_t;
|
||||
|
||||
cairo_public cairo_bool_t
|
||||
cairo_has_clip (cairo_t *cr);
|
||||
|
||||
cairo_public cairo_bool_t
|
||||
cairo_extract_clip_rectangles (cairo_t *cr,
|
||||
int max_rectangles,
|
||||
cairo_clip_rect_t *rectangles_out,
|
||||
int *num_rectangles_out);
|
||||
|
||||
/* Error status queries */
|
||||
|
||||
cairo_public cairo_status_t
|
||||
|
@ -1250,6 +1280,7 @@ cairo_surface_status (cairo_surface_t *surface);
|
|||
* @CAIRO_SURFACE_TYPE_BEOS: The surface is of type beos
|
||||
* @CAIRO_SURFACE_TYPE_DIRECTFB: The surface is of type directfb
|
||||
* @CAIRO_SURFACE_TYPE_SVG: The surface is of type svg
|
||||
* @CAIRO_SURFACE_TYPE_OS2: The surface is of type os2
|
||||
*
|
||||
* #cairo_surface_type_t is used to describe the type of a given
|
||||
* surface. The surface types are also known as "backends" or "surface
|
||||
|
@ -1270,6 +1301,8 @@ cairo_surface_status (cairo_surface_t *surface);
|
|||
* The behavior of calling a type-specific function with a surface of
|
||||
* the wrong type is undefined.
|
||||
*
|
||||
* New entries may be added in future versions.
|
||||
*
|
||||
* Since: 1.2
|
||||
*/
|
||||
typedef enum _cairo_surface_type {
|
||||
|
@ -1284,7 +1317,8 @@ typedef enum _cairo_surface_type {
|
|||
CAIRO_SURFACE_TYPE_BEOS,
|
||||
CAIRO_SURFACE_TYPE_DIRECTFB,
|
||||
CAIRO_SURFACE_TYPE_SVG,
|
||||
CAIRO_SURFACE_TYPE_NQUARTZ
|
||||
CAIRO_SURFACE_TYPE_NQUARTZ,
|
||||
CAIRO_SURFACE_TYPE_OS2
|
||||
} cairo_surface_type_t;
|
||||
|
||||
cairo_public cairo_surface_type_t
|
||||
|
@ -1368,19 +1402,24 @@ cairo_surface_set_fallback_resolution (cairo_surface_t *surface,
|
|||
* endianess of the platform. On a big-endian machine, the
|
||||
* first pixel is in the uppermost bit, on a little-endian
|
||||
* machine the first pixel is in the least-significant bit.
|
||||
* @CAIRO_FORMAT_RGB16_565: each pixel is a 16-bit quantity,
|
||||
* with red in the upper 5 bits, then green in the next 6,
|
||||
* then blue in the lowest 5 bits. (Since 1.2)
|
||||
* @CAIRO_FORMAT_RGB16_565: This format value is deprecated. It has
|
||||
* never been properly implemented in cairo and should not be used
|
||||
* by applications. (since 1.2)
|
||||
*
|
||||
* #cairo_format_t is used to identify the memory format of
|
||||
* image data.
|
||||
*
|
||||
* New entries may be added in future versions.
|
||||
*/
|
||||
typedef enum _cairo_format {
|
||||
CAIRO_FORMAT_ARGB32,
|
||||
CAIRO_FORMAT_RGB24,
|
||||
CAIRO_FORMAT_A8,
|
||||
CAIRO_FORMAT_A1,
|
||||
CAIRO_FORMAT_RGB16_565
|
||||
CAIRO_FORMAT_A1
|
||||
/* The value of 4 is reserved by a deprecated enum value.
|
||||
* The next format added must have an explicit value of 5.
|
||||
CAIRO_FORMAT_RGB16_565 = 4,
|
||||
*/
|
||||
} cairo_format_t;
|
||||
|
||||
cairo_public cairo_surface_t *
|
||||
|
@ -1476,6 +1515,8 @@ cairo_pattern_status (cairo_pattern_t *pattern);
|
|||
* gradient patterns (either LINEAR or RADIAL). Otherwise the pattern
|
||||
* will be shutdown and put into an error state.
|
||||
*
|
||||
* New entries may be added in future versions.
|
||||
*
|
||||
* Since: 1.2
|
||||
*/
|
||||
typedef enum _cairo_pattern_type {
|
||||
|
@ -1507,15 +1548,6 @@ cairo_public void
|
|||
cairo_pattern_get_matrix (cairo_pattern_t *pattern,
|
||||
cairo_matrix_t *matrix);
|
||||
|
||||
cairo_public cairo_status_t
|
||||
cairo_pattern_get_solid_color (cairo_pattern_t *pattern,
|
||||
double *r, double *g, double *b, double *a);
|
||||
|
||||
cairo_public cairo_status_t
|
||||
cairo_pattern_get_color_stop (cairo_pattern_t *pattern,
|
||||
int stop_index, double *offset,
|
||||
double *r, double *g, double *b, double *a);
|
||||
|
||||
/**
|
||||
* cairo_extend_t
|
||||
* @CAIRO_EXTEND_NONE: pixels outside of the source pattern
|
||||
|
@ -1529,6 +1561,8 @@ cairo_pattern_get_color_stop (cairo_pattern_t *pattern,
|
|||
*
|
||||
* #cairo_extend_t is used to describe how the area outside
|
||||
* of a pattern will be drawn.
|
||||
*
|
||||
* New entries may be added in future versions.
|
||||
*/
|
||||
typedef enum _cairo_extend {
|
||||
CAIRO_EXTEND_NONE,
|
||||
|
@ -1558,6 +1592,36 @@ cairo_pattern_set_filter (cairo_pattern_t *pattern, cairo_filter_t filter);
|
|||
cairo_public cairo_filter_t
|
||||
cairo_pattern_get_filter (cairo_pattern_t *pattern);
|
||||
|
||||
cairo_public cairo_status_t
|
||||
cairo_pattern_get_rgba (cairo_pattern_t *pattern,
|
||||
double *red, double *green,
|
||||
double *blue, double *alpha);
|
||||
|
||||
cairo_public cairo_status_t
|
||||
cairo_pattern_get_surface (cairo_pattern_t *pattern,
|
||||
cairo_surface_t **surface);
|
||||
|
||||
|
||||
cairo_public cairo_status_t
|
||||
cairo_pattern_get_color_stop_rgba (cairo_pattern_t *pattern,
|
||||
int index, double *offset,
|
||||
double *red, double *green,
|
||||
double *blue, double *alpha);
|
||||
|
||||
cairo_public cairo_status_t
|
||||
cairo_pattern_get_color_stop_count (cairo_pattern_t *pattern,
|
||||
int *count);
|
||||
|
||||
cairo_public cairo_status_t
|
||||
cairo_pattern_get_linear_points (cairo_pattern_t *pattern,
|
||||
double *x0, double *y0,
|
||||
double *x1, double *y1);
|
||||
|
||||
cairo_public cairo_status_t
|
||||
cairo_pattern_get_radial_circles (cairo_pattern_t *pattern,
|
||||
double *x0, double *y0, double *r0,
|
||||
double *x1, double *y1, double *r1);
|
||||
|
||||
/* Matrix functions */
|
||||
|
||||
cairo_public void
|
||||
|
@ -1610,92 +1674,6 @@ cairo_matrix_transform_point (const cairo_matrix_t *matrix,
|
|||
cairo_public void
|
||||
cairo_debug_reset_static_data (void);
|
||||
|
||||
#ifndef _CAIROINT_H_
|
||||
|
||||
/* Obsolete functions. These definitions exist to coerce the compiler
|
||||
* into providing a little bit of guidance with its error
|
||||
* messages. The idea is to help users port their old code without
|
||||
* having to dig through lots of documentation.
|
||||
*
|
||||
* The first set of REPLACED_BY functions is for functions whose names
|
||||
* have just been changed. So fixing these up is mechanical, (and
|
||||
* automated by means of the cairo/util/cairo-api-update script.
|
||||
*
|
||||
* The second set of DEPRECATED_BY functions is for functions where
|
||||
* the replacement is used in a different way, (ie. different
|
||||
* arguments, multiple functions instead of one, etc). Fixing these up
|
||||
* will require a bit more work on the user's part, (and hopefully we
|
||||
* can get cairo-api-update to find these and print some guiding
|
||||
* information).
|
||||
*/
|
||||
#define cairo_current_font_extents cairo_current_font_extents_REPLACED_BY_cairo_font_extents
|
||||
#define cairo_get_font_extents cairo_get_font_extents_REPLACED_BY_cairo_font_extents
|
||||
#define cairo_current_operator cairo_current_operator_REPLACED_BY_cairo_get_operator
|
||||
#define cairo_current_tolerance cairo_current_tolerance_REPLACED_BY_cairo_get_tolerance
|
||||
#define cairo_current_point cairo_current_point_REPLACED_BY_cairo_get_current_point
|
||||
#define cairo_current_fill_rule cairo_current_fill_rule_REPLACED_BY_cairo_get_fill_rule
|
||||
#define cairo_current_line_width cairo_current_line_width_REPLACED_BY_cairo_get_line_width
|
||||
#define cairo_current_line_cap cairo_current_line_cap_REPLACED_BY_cairo_get_line_cap
|
||||
#define cairo_current_line_join cairo_current_line_join_REPLACED_BY_cairo_get_line_join
|
||||
#define cairo_current_miter_limit cairo_current_miter_limit_REPLACED_BY_cairo_get_miter_limit
|
||||
#define cairo_current_matrix cairo_current_matrix_REPLACED_BY_cairo_get_matrix
|
||||
#define cairo_current_target_surface cairo_current_target_surface_REPLACED_BY_cairo_get_target
|
||||
#define cairo_get_status cairo_get_status_REPLACED_BY_cairo_status
|
||||
#define cairo_concat_matrix cairo_concat_matrix_REPLACED_BY_cairo_transform
|
||||
#define cairo_scale_font cairo_scale_font_REPLACED_BY_cairo_set_font_size
|
||||
#define cairo_select_font cairo_select_font_REPLACED_BY_cairo_select_font_face
|
||||
#define cairo_transform_font cairo_transform_font_REPLACED_BY_cairo_set_font_matrix
|
||||
#define cairo_transform_point cairo_transform_point_REPLACED_BY_cairo_user_to_device
|
||||
#define cairo_transform_distance cairo_transform_distance_REPLACED_BY_cairo_user_to_device_distance
|
||||
#define cairo_inverse_transform_point cairo_inverse_transform_point_REPLACED_BY_cairo_device_to_user
|
||||
#define cairo_inverse_transform_distance cairo_inverse_transform_distance_REPLACED_BY_cairo_device_to_user_distance
|
||||
#define cairo_init_clip cairo_init_clip_REPLACED_BY_cairo_reset_clip
|
||||
#define cairo_surface_create_for_image cairo_surface_create_for_image_REPLACED_BY_cairo_image_surface_create_for_data
|
||||
#define cairo_default_matrix cairo_default_matrix_REPLACED_BY_cairo_identity_matrix
|
||||
#define cairo_matrix_set_affine cairo_matrix_set_affine_REPLACED_BY_cairo_matrix_init
|
||||
#define cairo_matrix_set_identity cairo_matrix_set_identity_REPLACED_BY_cairo_matrix_init_identity
|
||||
#define cairo_pattern_add_color_stop cairo_pattern_add_color_stop_REPLACED_BY_cairo_pattern_add_color_stop_rgba
|
||||
#define cairo_set_rgb_color cairo_set_rgb_color_REPLACED_BY_cairo_set_source_rgb
|
||||
#define cairo_set_pattern cairo_set_pattern_REPLACED_BY_cairo_set_source
|
||||
#define cairo_xlib_surface_create_for_pixmap_with_visual cairo_xlib_surface_create_for_pixmap_with_visual_REPLACED_BY_cairo_xlib_surface_create
|
||||
#define cairo_xlib_surface_create_for_window_with_visual cairo_xlib_surface_create_for_window_with_visual_REPLACED_BY_cairo_xlib_surface_create
|
||||
#define cairo_xcb_surface_create_for_pixmap_with_visual cairo_xcb_surface_create_for_pixmap_with_visual_REPLACED_BY_cairo_xcb_surface_create
|
||||
#define cairo_xcb_surface_create_for_window_with_visual cairo_xcb_surface_create_for_window_with_visual_REPLACED_BY_cairo_xcb_surface_create
|
||||
#define cairo_ps_surface_set_dpi cairo_ps_surface_set_dpi_REPLACED_BY_cairo_surface_set_fallback_resolution
|
||||
#define cairo_pdf_surface_set_dpi cairo_pdf_surface_set_dpi_REPLACED_BY_cairo_surface_set_fallback_resolution
|
||||
#define cairo_svg_surface_set_dpi cairo_svg_surface_set_dpi_REPLACED_BY_cairo_surface_set_fallback_resolution
|
||||
|
||||
#define cairo_current_path cairo_current_path_DEPRECATED_BY_cairo_copy_path
|
||||
#define cairo_current_path_flat cairo_current_path_flat_DEPRECATED_BY_cairo_copy_path_flat
|
||||
#define cairo_get_path cairo_get_path_DEPRECATED_BY_cairo_copy_path
|
||||
#define cairo_get_path_flat cairo_get_path_flat_DEPRECATED_BY_cairo_get_path_flat
|
||||
#define cairo_set_alpha cairo_set_alpha_DEPRECATED_BY_cairo_set_source_rgba_OR_cairo_paint_with_alpha
|
||||
#define cairo_show_surface cairo_show_surface_DEPRECATED_BY_cairo_set_source_surface_AND_cairo_paint
|
||||
#define cairo_copy cairo_copy_DEPRECATED_BY_cairo_create_AND_MANY_INDIVIDUAL_FUNCTIONS
|
||||
#define cairo_surface_set_repeat cairo_surface_set_repeat_DEPRECATED_BY_cairo_pattern_set_extend
|
||||
#define cairo_surface_set_matrix cairo_surface_set_matrix_DEPRECATED_BY_cairo_pattern_set_matrix
|
||||
#define cairo_surface_get_matrix cairo_surface_get_matrix_DEPRECATED_BY_cairo_pattern_get_matrix
|
||||
#define cairo_surface_set_filter cairo_surface_set_filter_DEPRECATED_BY_cairo_pattern_set_filter
|
||||
#define cairo_surface_get_filter cairo_surface_get_filter_DEPRECATED_BY_cairo_pattern_get_filter
|
||||
#define cairo_matrix_create cairo_matrix_create_DEPRECATED_BY_cairo_matrix_t
|
||||
#define cairo_matrix_destroy cairo_matrix_destroy_DEPRECATED_BY_cairo_matrix_t
|
||||
#define cairo_matrix_copy cairo_matrix_copy_DEPRECATED_BY_cairo_matrix_t
|
||||
#define cairo_matrix_get_affine cairo_matrix_get_affine_DEPRECATED_BY_cairo_matrix_t
|
||||
#define cairo_set_target_surface cairo_set_target_surface_DEPRECATED_BY_cairo_create
|
||||
#define cairo_set_target_glitz cairo_set_target_glitz_DEPRECATED_BY_cairo_glitz_surface_create
|
||||
#define cairo_set_target_image cairo_set_target_image_DEPRECATED_BY_cairo_image_surface_create_for_data
|
||||
#define cairo_set_target_pdf cairo_set_target_pdf_DEPRECATED_BY_cairo_pdf_surface_create
|
||||
#define cairo_set_target_png cairo_set_target_png_DEPRECATED_BY_cairo_surface_write_to_png
|
||||
#define cairo_set_target_ps cairo_set_target_ps_DEPRECATED_BY_cairo_ps_surface_create
|
||||
#define cairo_set_target_quartz cairo_set_target_quartz_DEPRECATED_BY_cairo_quartz_surface_create
|
||||
#define cairo_set_target_win32 cairo_set_target_win32_DEPRECATED_BY_cairo_win32_surface_create
|
||||
#define cairo_set_target_xcb cairo_set_target_xcb_DEPRECATED_BY_cairo_xcb_surface_create
|
||||
#define cairo_set_target_drawable cairo_set_target_drawable_DEPRECATED_BY_cairo_xlib_surface_create
|
||||
#define cairo_get_status_string cairo_get_status_string_DEPRECATED_BY_cairo_status_AND_cairo_status_to_string
|
||||
#define cairo_status_string cairo_status_string_DEPRECATED_BY_cairo_status_AND_cairo_status_to_string
|
||||
|
||||
#endif
|
||||
|
||||
CAIRO_END_DECLS
|
||||
|
||||
#endif /* CAIRO_H */
|
||||
|
|
|
@ -65,19 +65,21 @@
|
|||
#include "cairo.h"
|
||||
#include <pixman.h>
|
||||
|
||||
CAIRO_BEGIN_DECLS
|
||||
|
||||
#ifndef PACKAGE_BUGREPORT
|
||||
#define PACKAGE_BUGREPORT "(unknown)"
|
||||
#ifdef _MSC_VER
|
||||
#define snprintf _snprintf
|
||||
#define inline __inline
|
||||
#endif
|
||||
|
||||
CAIRO_BEGIN_DECLS
|
||||
|
||||
#if __GNUC__ >= 3 && defined(__ELF__)
|
||||
# define slim_hidden_proto(name) slim_hidden_proto1(name, INT_##name)
|
||||
# define slim_hidden_def(name) slim_hidden_def1(name, INT_##name)
|
||||
# define slim_hidden_proto(name) slim_hidden_proto1(name, slim_hidden_int_name(name))
|
||||
# define slim_hidden_def(name) slim_hidden_def1(name, slim_hidden_int_name(name))
|
||||
# define slim_hidden_int_name(name) INT_##name
|
||||
# define slim_hidden_proto1(name, internal) \
|
||||
extern __typeof (name) name \
|
||||
__asm__ (slim_hidden_asmname (internal)) \
|
||||
cairo_private;
|
||||
cairo_private
|
||||
# define slim_hidden_def1(name, internal) \
|
||||
extern __typeof (name) EXT_##name __asm__(slim_hidden_asmname(name)) \
|
||||
__attribute__((__alias__(slim_hidden_asmname(internal))))
|
||||
|
@ -147,7 +149,12 @@ CAIRO_BEGIN_DECLS
|
|||
#endif
|
||||
|
||||
#if !defined(CAIRO_MUTEX_DECLARE) && defined CAIRO_HAS_WIN32_SURFACE
|
||||
# define WIN32_LEAN_AND_MEAN
|
||||
# ifndef WIN32_LEAN_AND_MEAN
|
||||
# define WIN32_LEAN_AND_MEAN
|
||||
# endif
|
||||
# ifndef WINVER
|
||||
# define WINVER 0xFFFFF /* use newest and greatest */
|
||||
# endif
|
||||
# include <windows.h>
|
||||
/* the real initialization must take place in DllMain */
|
||||
# define CAIRO_MUTEX_DECLARE(name) extern CRITICAL_SECTION name;
|
||||
|
@ -156,6 +163,17 @@ CAIRO_BEGIN_DECLS
|
|||
# define CAIRO_MUTEX_UNLOCK(name) LeaveCriticalSection (&name)
|
||||
#endif
|
||||
|
||||
#if defined(__OS2__) && !defined(CAIRO_MUTEX_DECLARE)
|
||||
# define INCL_BASE
|
||||
# define INCL_PM
|
||||
# include <os2.h>
|
||||
|
||||
# define CAIRO_MUTEX_DECLARE(name) extern HMTX name
|
||||
# define CAIRO_MUTEX_DECLARE_GLOBAL(name) extern HMTX name
|
||||
# define CAIRO_MUTEX_LOCK(name) DosRequestMutexSem(name, SEM_INDEFINITE_WAIT)
|
||||
# define CAIRO_MUTEX_UNLOCK(name) DosReleaseMutexSem(name)
|
||||
#endif
|
||||
|
||||
#if !defined(CAIRO_MUTEX_DECLARE) && defined CAIRO_HAS_BEOS_SURFACE
|
||||
cairo_private void _cairo_beos_lock(void*);
|
||||
cairo_private void _cairo_beos_unlock(void*);
|
||||
|
@ -198,6 +216,8 @@ do { \
|
|||
assert (NOT_REACHED); \
|
||||
} while (0)
|
||||
|
||||
#define CAIRO_REF_COUNT_INVALID ((unsigned int) -1)
|
||||
|
||||
#include "cairo-wideint-private.h"
|
||||
|
||||
typedef int32_t cairo_fixed_16_16_t;
|
||||
|
@ -282,6 +302,35 @@ typedef enum cairo_internal_surface_type {
|
|||
CAIRO_INTERNAL_SURFACE_TYPE_TEST_PAGINATED
|
||||
} cairo_internal_surface_type_t;
|
||||
|
||||
/* For xlib fallbacks, we use image surfaces with formats that match
|
||||
* the visual of the X server. There are a couple of common X server
|
||||
* visuals for which we do not have corresponding public
|
||||
* cairo_format_t values, since we do not plan on always guaranteeing
|
||||
* that cairo will be able to draw to these formats.
|
||||
*
|
||||
* So, currently pixman does provide support for these formats. It's
|
||||
* possible that in the future we will change the implementation to
|
||||
* instead convert to a supported format. This would allow us to be
|
||||
* able to simplify pixman to handle fewer formats.
|
||||
*
|
||||
* The RGB16_565 case could probably have been handled this same way,
|
||||
* (and in fact we could still change it to do so, and maybe just
|
||||
* leave the value in the enum but deprecate it entirely). We can't
|
||||
* drop the value since it did appear in cairo 1.2.0 so it might
|
||||
* appear in code, (particularly bindings which are thorough about
|
||||
* things like that). But we did neglect to update CAIRO_FORMAT_VALID
|
||||
* for 1.2 so we know that no functional code is out there relying on
|
||||
* being able to create an image surface with a 565 format, (which is
|
||||
* good since things like write_to_png are missing support for the 565
|
||||
* format.
|
||||
*
|
||||
* NOTE: The implementation of CAIRO_FORMAT_VALID *must* *not*
|
||||
* consider these internal formats as valid. */
|
||||
typedef enum cairo_internal_format {
|
||||
CAIRO_INTERNAL_FORMAT_ABGR32 = 0x1000,
|
||||
CAIRO_INTERNAL_FORMAT_BGR24
|
||||
} cairo_internal_format_t;
|
||||
|
||||
typedef enum cairo_direction {
|
||||
CAIRO_DIRECTION_FORWARD,
|
||||
CAIRO_DIRECTION_REVERSE
|
||||
|
@ -356,9 +405,9 @@ _cairo_rectangle_intersect (cairo_rectangle_int16_t *dest, cairo_rectangle_int16
|
|||
|
||||
typedef struct _cairo_array cairo_array_t;
|
||||
struct _cairo_array {
|
||||
int size;
|
||||
int num_elements;
|
||||
int element_size;
|
||||
unsigned int size;
|
||||
unsigned int num_elements;
|
||||
unsigned int element_size;
|
||||
char **elements;
|
||||
|
||||
cairo_bool_t is_snapshot;
|
||||
|
@ -378,7 +427,7 @@ cairo_private cairo_status_t
|
|||
_cairo_array_grow_by (cairo_array_t *array, int additional);
|
||||
|
||||
cairo_private void
|
||||
_cairo_array_truncate (cairo_array_t *array, int length);
|
||||
_cairo_array_truncate (cairo_array_t *array, unsigned int num_elements);
|
||||
|
||||
cairo_private cairo_status_t
|
||||
_cairo_array_append (cairo_array_t *array, const void *element);
|
||||
|
@ -390,11 +439,11 @@ _cairo_array_append_multiple (cairo_array_t *array,
|
|||
|
||||
cairo_private cairo_status_t
|
||||
_cairo_array_allocate (cairo_array_t *array,
|
||||
int num_elements,
|
||||
unsigned int num_elements,
|
||||
void **elements);
|
||||
|
||||
cairo_private void *
|
||||
_cairo_array_index (cairo_array_t *array, int index);
|
||||
_cairo_array_index (cairo_array_t *array, unsigned int index);
|
||||
|
||||
cairo_private void
|
||||
_cairo_array_copy_element (cairo_array_t *array, int index, void *dst);
|
||||
|
@ -402,6 +451,9 @@ _cairo_array_copy_element (cairo_array_t *array, int index, void *dst);
|
|||
cairo_private int
|
||||
_cairo_array_num_elements (cairo_array_t *array);
|
||||
|
||||
cairo_private int
|
||||
_cairo_array_size (cairo_array_t *array);
|
||||
|
||||
typedef cairo_array_t cairo_user_data_array_t;
|
||||
|
||||
cairo_private void
|
||||
|
@ -433,7 +485,7 @@ typedef struct _cairo_font_face_backend cairo_font_face_backend_t;
|
|||
*/
|
||||
typedef struct _cairo_unscaled_font {
|
||||
cairo_hash_entry_t hash_entry;
|
||||
int ref_count;
|
||||
unsigned int ref_count;
|
||||
const cairo_unscaled_font_backend_t *backend;
|
||||
} cairo_unscaled_font_t;
|
||||
|
||||
|
@ -463,7 +515,7 @@ struct _cairo_scaled_font {
|
|||
|
||||
/* useful bits for _cairo_scaled_font_nil */
|
||||
cairo_status_t status;
|
||||
int ref_count;
|
||||
unsigned int ref_count;
|
||||
|
||||
/* hash key members */
|
||||
cairo_font_face_t *font_face; /* may be NULL */
|
||||
|
@ -492,7 +544,7 @@ struct _cairo_font_face {
|
|||
/* hash_entry must be first */
|
||||
cairo_hash_entry_t hash_entry;
|
||||
cairo_status_t status;
|
||||
int ref_count;
|
||||
unsigned int ref_count;
|
||||
cairo_user_data_array_t user_data;
|
||||
const cairo_font_face_backend_t *backend;
|
||||
};
|
||||
|
@ -580,6 +632,12 @@ struct _cairo_scaled_font_backend {
|
|||
const cairo_glyph_t *glyphs,
|
||||
int num_glyphs);
|
||||
|
||||
cairo_int_status_t
|
||||
(*load_truetype_table)(void *scaled_font,
|
||||
unsigned long tag,
|
||||
long offset,
|
||||
unsigned char *buffer,
|
||||
unsigned long *length);
|
||||
};
|
||||
|
||||
struct _cairo_font_face_backend {
|
||||
|
@ -624,7 +682,7 @@ typedef struct _cairo_stroke_style {
|
|||
cairo_line_join_t line_join;
|
||||
double miter_limit;
|
||||
double *dash;
|
||||
int num_dashes;
|
||||
unsigned int num_dashes;
|
||||
double dash_offset;
|
||||
} cairo_stroke_style_t;
|
||||
|
||||
|
@ -899,6 +957,14 @@ struct _cairo_surface {
|
|||
|
||||
/* A "snapshot" surface is immutable. See _cairo_surface_snapshot. */
|
||||
cairo_bool_t is_snapshot;
|
||||
|
||||
/*
|
||||
* Surface font options, falling back to backend's default options,
|
||||
* and set using _cairo_surface_set_font_options(), and propagated by
|
||||
* cairo_surface_create_similar().
|
||||
*/
|
||||
cairo_bool_t has_font_options;
|
||||
cairo_font_options_t font_options;
|
||||
};
|
||||
|
||||
struct _cairo_image_surface {
|
||||
|
@ -974,7 +1040,7 @@ typedef struct _cairo_gradient_pattern {
|
|||
cairo_pattern_t base;
|
||||
|
||||
pixman_gradient_stop_t *stops;
|
||||
int n_stops;
|
||||
unsigned int n_stops;
|
||||
} cairo_gradient_pattern_t;
|
||||
|
||||
typedef struct _cairo_linear_pattern {
|
||||
|
@ -1168,7 +1234,7 @@ cairo_private cairo_line_join_t
|
|||
_cairo_gstate_get_line_join (cairo_gstate_t *gstate);
|
||||
|
||||
cairo_private cairo_status_t
|
||||
_cairo_gstate_set_dash (cairo_gstate_t *gstate, double *dash, int num_dashes, double offset);
|
||||
_cairo_gstate_set_dash (cairo_gstate_t *gstate, const double *dash, int num_dashes, double offset);
|
||||
|
||||
cairo_private cairo_status_t
|
||||
_cairo_gstate_set_miter_limit (cairo_gstate_t *gstate, double limit);
|
||||
|
@ -1217,6 +1283,12 @@ _cairo_gstate_user_to_backend (cairo_gstate_t *gstate, double *x, double *y);
|
|||
cairo_private void
|
||||
_cairo_gstate_backend_to_user (cairo_gstate_t *gstate, double *x, double *y);
|
||||
|
||||
cairo_private void
|
||||
_cairo_gstate_backend_to_user_rectangle (cairo_gstate_t *gstate,
|
||||
double *x1, double *y1,
|
||||
double *x2, double *y2,
|
||||
cairo_bool_t *is_tight);
|
||||
|
||||
cairo_private cairo_status_t
|
||||
_cairo_gstate_paint (cairo_gstate_t *gstate);
|
||||
|
||||
|
@ -1268,6 +1340,16 @@ _cairo_gstate_clip (cairo_gstate_t *gstate, cairo_path_fixed_t *path);
|
|||
cairo_private cairo_status_t
|
||||
_cairo_gstate_reset_clip (cairo_gstate_t *gstate);
|
||||
|
||||
cairo_private cairo_status_t
|
||||
_cairo_gstate_clip_extents (cairo_gstate_t *gstate,
|
||||
double *x1,
|
||||
double *y1,
|
||||
double *x2,
|
||||
double *y2);
|
||||
|
||||
cairo_private cairo_rectangle_list_t*
|
||||
_cairo_gstate_copy_clip_rectangles (cairo_gstate_t *gstate);
|
||||
|
||||
cairo_private cairo_status_t
|
||||
_cairo_gstate_show_surface (cairo_gstate_t *gstate,
|
||||
cairo_surface_t *surface,
|
||||
|
@ -1330,7 +1412,7 @@ _cairo_gstate_glyph_extents (cairo_gstate_t *gstate,
|
|||
|
||||
cairo_private cairo_status_t
|
||||
_cairo_gstate_show_glyphs (cairo_gstate_t *gstate,
|
||||
cairo_glyph_t *glyphs,
|
||||
const cairo_glyph_t *glyphs,
|
||||
int num_glyphs);
|
||||
|
||||
cairo_private cairo_status_t
|
||||
|
@ -1676,6 +1758,10 @@ _cairo_surface_init (cairo_surface_t *surface,
|
|||
const cairo_surface_backend_t *backend,
|
||||
cairo_content_t content);
|
||||
|
||||
cairo_private void
|
||||
_cairo_surface_set_font_options (cairo_surface_t *surface,
|
||||
cairo_font_options_t *options);
|
||||
|
||||
cairo_private cairo_clip_mode_t
|
||||
_cairo_surface_get_clip_mode (cairo_surface_t *surface);
|
||||
|
||||
|
@ -1894,8 +1980,37 @@ _cairo_surface_has_device_transform (cairo_surface_t *surface);
|
|||
|
||||
/* cairo_image_surface.c */
|
||||
|
||||
#define CAIRO_FORMAT_VALID(format) ((format) >= CAIRO_FORMAT_ARGB32 && \
|
||||
(format) <= CAIRO_FORMAT_A1)
|
||||
/* XXX: In cairo 1.2.0 we added a new CAIRO_FORMAT_RGB16_565 but
|
||||
* neglected to adjust this macro. The net effect is that it's
|
||||
* impossible to externally create an image surface with this
|
||||
* format. This is perhaps a good thing since we also neglected to fix
|
||||
* up things like cairo_surface_write_to_png for the new format
|
||||
* (-Wswitch-enum will tell you where). Is it obvious that format was
|
||||
* added in haste?
|
||||
*
|
||||
* The reason for the new format was to allow the xlib backend to be
|
||||
* used on X servers with a 565 visual. So the new format did its job
|
||||
* for that, even without being considered "valid" for the sake of
|
||||
* things like cairo_image_surface_create.
|
||||
*
|
||||
* Since 1.2.0 we ran into the same situtation with X servers with BGR
|
||||
* visuals. This time we invented cairo_internal_format_t instead,
|
||||
* (see it for more discussion).
|
||||
*
|
||||
* The punchline is that CAIRO_FORMAT_VALID must not conside any
|
||||
* internal format to be valid. Also we need to decide if the
|
||||
* RGB16_565 should be moved to instead be an internal format. If so,
|
||||
* this macro need not change for it. (We probably will need to leave
|
||||
* an RGB16_565 value in the header files for the sake of code that
|
||||
* might have that value in it.)
|
||||
*
|
||||
* If we do decide to start fully supporting RGB16_565 as an external
|
||||
* format, then CAIRO_FORMAT_VALID needs to be adjusted to include
|
||||
* it. But that should not happen before all necessary code is fixed
|
||||
* to support it (at least cairo_surface_write_to_png and a few spots
|
||||
* in cairo-xlib-surface.c--again see -Wswitch-enum).
|
||||
*/
|
||||
#define CAIRO_FORMAT_VALID(format) ((format) <= CAIRO_FORMAT_A1)
|
||||
|
||||
#define CAIRO_CONTENT_VALID(content) ((content) && \
|
||||
(((content) & ~(CAIRO_CONTENT_COLOR | \
|
||||
|
@ -1948,6 +2063,10 @@ cairo_private cairo_int_status_t
|
|||
_cairo_image_surface_set_clip_region (void *abstract_surface,
|
||||
pixman_region16_t *region);
|
||||
|
||||
cairo_private cairo_image_surface_t *
|
||||
_cairo_image_surface_clone (cairo_image_surface_t *surface,
|
||||
cairo_format_t format);
|
||||
|
||||
cairo_private cairo_bool_t
|
||||
_cairo_surface_is_image (const cairo_surface_t *surface);
|
||||
|
||||
|
@ -2039,7 +2158,8 @@ _cairo_matrix_get_affine (const cairo_matrix_t *matrix,
|
|||
cairo_private void
|
||||
_cairo_matrix_transform_bounding_box (const cairo_matrix_t *matrix,
|
||||
double *x, double *y,
|
||||
double *width, double *height);
|
||||
double *width, double *height,
|
||||
cairo_bool_t *is_tight);
|
||||
|
||||
cairo_private void
|
||||
_cairo_matrix_compute_determinant (const cairo_matrix_t *matrix, double *det);
|
||||
|
@ -2153,7 +2273,7 @@ _cairo_pattern_transform (cairo_pattern_t *pattern,
|
|||
cairo_private cairo_bool_t
|
||||
_cairo_pattern_is_opaque_solid (const cairo_pattern_t *pattern);
|
||||
|
||||
cairo_bool_t
|
||||
cairo_private cairo_bool_t
|
||||
_cairo_pattern_is_opaque (const cairo_pattern_t *abstract_pattern);
|
||||
|
||||
cairo_private cairo_int_status_t
|
||||
|
@ -2227,32 +2347,88 @@ cairo_private int
|
|||
_cairo_dtostr (char *buffer, size_t size, double d);
|
||||
|
||||
/* Avoid unnecessary PLT entries. */
|
||||
slim_hidden_proto(cairo_get_current_point)
|
||||
slim_hidden_proto(cairo_fill_preserve)
|
||||
slim_hidden_proto(cairo_clip_preserve)
|
||||
slim_hidden_proto(cairo_close_path)
|
||||
slim_hidden_proto(cairo_matrix_invert)
|
||||
slim_hidden_proto(cairo_matrix_multiply)
|
||||
slim_hidden_proto(cairo_matrix_scale)
|
||||
slim_hidden_proto(cairo_matrix_init)
|
||||
slim_hidden_proto(cairo_matrix_init_identity)
|
||||
slim_hidden_proto(cairo_matrix_init_translate)
|
||||
slim_hidden_proto(cairo_matrix_init_scale)
|
||||
slim_hidden_proto(cairo_matrix_init_rotate)
|
||||
slim_hidden_proto(cairo_matrix_transform_distance)
|
||||
slim_hidden_proto(cairo_matrix_transform_point)
|
||||
slim_hidden_proto(cairo_move_to)
|
||||
slim_hidden_proto(cairo_new_path)
|
||||
slim_hidden_proto(cairo_rel_line_to)
|
||||
slim_hidden_proto(cairo_restore)
|
||||
slim_hidden_proto(cairo_save)
|
||||
slim_hidden_proto(cairo_stroke_preserve)
|
||||
slim_hidden_proto(cairo_surface_destroy)
|
||||
slim_hidden_proto(cairo_surface_get_content)
|
||||
slim_hidden_proto(cairo_push_group)
|
||||
slim_hidden_proto(cairo_push_group_with_content)
|
||||
slim_hidden_proto(cairo_pop_group)
|
||||
slim_hidden_proto(cairo_pop_group_to_source)
|
||||
slim_hidden_proto (cairo_clip_preserve);
|
||||
slim_hidden_proto (cairo_close_path);
|
||||
slim_hidden_proto (cairo_create);
|
||||
slim_hidden_proto (cairo_curve_to);
|
||||
slim_hidden_proto (cairo_destroy);
|
||||
slim_hidden_proto (cairo_fill_preserve);
|
||||
slim_hidden_proto (cairo_font_face_destroy);
|
||||
slim_hidden_proto (cairo_font_face_reference);
|
||||
slim_hidden_proto (cairo_font_options_create);
|
||||
slim_hidden_proto (cairo_font_options_destroy);
|
||||
slim_hidden_proto (cairo_font_options_equal);
|
||||
slim_hidden_proto (cairo_font_options_hash);
|
||||
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_subpixel_order);
|
||||
slim_hidden_proto (cairo_get_current_point);
|
||||
slim_hidden_proto (cairo_get_matrix);
|
||||
slim_hidden_proto (cairo_get_tolerance);
|
||||
slim_hidden_proto (cairo_image_surface_create);
|
||||
slim_hidden_proto (cairo_image_surface_create_for_data);
|
||||
slim_hidden_proto (cairo_image_surface_get_height);
|
||||
slim_hidden_proto (cairo_image_surface_get_width);
|
||||
slim_hidden_proto (cairo_line_to);
|
||||
slim_hidden_proto (cairo_mask);
|
||||
slim_hidden_proto (cairo_matrix_init);
|
||||
slim_hidden_proto (cairo_matrix_init_identity);
|
||||
slim_hidden_proto (cairo_matrix_init_rotate);
|
||||
slim_hidden_proto (cairo_matrix_init_scale);
|
||||
slim_hidden_proto (cairo_matrix_init_translate);
|
||||
slim_hidden_proto (cairo_matrix_invert);
|
||||
slim_hidden_proto (cairo_matrix_multiply);
|
||||
slim_hidden_proto (cairo_matrix_scale);
|
||||
slim_hidden_proto (cairo_matrix_transform_distance);
|
||||
slim_hidden_proto (cairo_matrix_transform_point);
|
||||
slim_hidden_proto (cairo_matrix_translate);
|
||||
slim_hidden_proto (cairo_move_to);
|
||||
slim_hidden_proto (cairo_new_path);
|
||||
slim_hidden_proto (cairo_paint);
|
||||
slim_hidden_proto (cairo_pattern_create_for_surface);
|
||||
slim_hidden_proto (cairo_pattern_create_rgb);
|
||||
slim_hidden_proto (cairo_pattern_create_rgba);
|
||||
slim_hidden_proto (cairo_pattern_destroy);
|
||||
slim_hidden_proto (cairo_pattern_get_extend);
|
||||
slim_hidden_proto (cairo_pattern_get_type);
|
||||
slim_hidden_proto (cairo_pattern_reference);
|
||||
slim_hidden_proto (cairo_pattern_set_matrix);
|
||||
slim_hidden_proto (cairo_pop_group);
|
||||
slim_hidden_proto (cairo_pop_group_to_source);
|
||||
slim_hidden_proto (cairo_push_group);
|
||||
slim_hidden_proto (cairo_push_group_with_content);
|
||||
slim_hidden_proto (cairo_rel_line_to);
|
||||
slim_hidden_proto (cairo_restore);
|
||||
slim_hidden_proto (cairo_save);
|
||||
slim_hidden_proto (cairo_scaled_font_create);
|
||||
slim_hidden_proto (cairo_scaled_font_destroy);
|
||||
slim_hidden_proto (cairo_scaled_font_extents);
|
||||
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_glyph_extents);
|
||||
slim_hidden_proto (cairo_scaled_font_reference);
|
||||
slim_hidden_proto (cairo_set_operator);
|
||||
slim_hidden_proto (cairo_set_source);
|
||||
slim_hidden_proto (cairo_set_source_surface);
|
||||
slim_hidden_proto (cairo_status);
|
||||
slim_hidden_proto (cairo_stroke_preserve);
|
||||
slim_hidden_proto (cairo_surface_create_similar);
|
||||
slim_hidden_proto (cairo_surface_destroy);
|
||||
slim_hidden_proto (cairo_surface_finish);
|
||||
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_mark_dirty_rectangle);
|
||||
slim_hidden_proto (cairo_surface_reference);
|
||||
slim_hidden_proto (cairo_surface_set_device_offset);
|
||||
slim_hidden_proto (cairo_surface_set_fallback_resolution);
|
||||
slim_hidden_proto (cairo_surface_status);
|
||||
slim_hidden_proto (cairo_surface_write_to_png_stream);
|
||||
|
||||
CAIRO_END_DECLS
|
||||
|
||||
|
|
|
@ -64,6 +64,8 @@ typedef struct _test_fallback_surface {
|
|||
|
||||
const cairo_private cairo_surface_backend_t test_fallback_surface_backend;
|
||||
|
||||
slim_hidden_proto (_test_fallback_surface_create);
|
||||
|
||||
cairo_surface_t *
|
||||
_test_fallback_surface_create (cairo_content_t content,
|
||||
int width,
|
||||
|
@ -89,6 +91,7 @@ _test_fallback_surface_create (cairo_content_t content,
|
|||
|
||||
return &surface->base;
|
||||
}
|
||||
slim_hidden_def (_test_fallback_surface_create);
|
||||
|
||||
static cairo_surface_t *
|
||||
_test_fallback_surface_create_similar (void *abstract_surface,
|
||||
|
|
|
@ -95,6 +95,16 @@ _test_paginated_surface_create_for_data (unsigned char *data,
|
|||
&test_paginated_surface_paginated_backend);
|
||||
}
|
||||
|
||||
static cairo_status_t
|
||||
_test_paginated_surface_finish (void *abstract_surface)
|
||||
{
|
||||
test_paginated_surface_t *surface = abstract_surface;
|
||||
|
||||
cairo_surface_destroy (surface->target);
|
||||
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
static cairo_int_status_t
|
||||
_test_paginated_surface_set_clip_region (void *abstract_surface,
|
||||
pixman_region16_t *region)
|
||||
|
@ -247,7 +257,7 @@ static const cairo_surface_backend_t test_paginated_surface_backend = {
|
|||
* surface backend interface as historical cruft and ignore it. */
|
||||
|
||||
NULL, /* create_similar */
|
||||
NULL, /* finish */
|
||||
_test_paginated_surface_finish,
|
||||
NULL, /* acquire_source_image */
|
||||
NULL, /* release_source_image */
|
||||
NULL, /* acquire_dest_image */
|
||||
|
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -28,6 +28,7 @@
|
|||
#endif
|
||||
#include "pixman-xserver-compat.h"
|
||||
#include "fbpict.h"
|
||||
#include "fbmmx.h"
|
||||
|
||||
#ifdef RENDER
|
||||
|
||||
|
@ -3092,8 +3093,8 @@ static void fbFetchTransformed(PicturePtr pict, int x, int y, int width, CARD32
|
|||
if (pict->filter == PIXMAN_FILTER_NEAREST || pict->filter == PIXMAN_FILTER_FAST)
|
||||
{
|
||||
if (pict->repeat == RepeatNormal) {
|
||||
if (PIXREGION_NUM_RECTS(pict->pCompositeClip) == 1) {
|
||||
box = pict->pCompositeClip->extents;
|
||||
if (PIXREGION_NUM_RECTS(pict->pSourceClip) == 1) {
|
||||
box = pict->pSourceClip->extents;
|
||||
for (i = 0; i < width; ++i) {
|
||||
if (!mask || mask[i] & maskBits)
|
||||
{
|
||||
|
@ -3128,7 +3129,7 @@ static void fbFetchTransformed(PicturePtr pict, int x, int y, int width, CARD32
|
|||
y = MOD(v.vector[1]>>16, pict->pDrawable->height);
|
||||
x = MOD(v.vector[0]>>16, pict->pDrawable->width);
|
||||
}
|
||||
if (pixman_region_contains_point (pict->pCompositeClip, x, y, &box))
|
||||
if (pixman_region_contains_point (pict->pSourceClip, x, y, &box))
|
||||
buffer[i] = fetch(bits + (y + pict->pDrawable->y)*stride, x + pict->pDrawable->x, indexed);
|
||||
else
|
||||
buffer[i] = 0;
|
||||
|
@ -3140,8 +3141,8 @@ static void fbFetchTransformed(PicturePtr pict, int x, int y, int width, CARD32
|
|||
}
|
||||
}
|
||||
} else {
|
||||
if (PIXREGION_NUM_RECTS(pict->pCompositeClip) == 1) {
|
||||
box = pict->pCompositeClip->extents;
|
||||
if (PIXREGION_NUM_RECTS(pict->pSourceClip) == 1) {
|
||||
box = pict->pSourceClip->extents;
|
||||
for (i = 0; i < width; ++i) {
|
||||
if (!mask || mask[i] & maskBits)
|
||||
{
|
||||
|
@ -3175,7 +3176,7 @@ static void fbFetchTransformed(PicturePtr pict, int x, int y, int width, CARD32
|
|||
y = v.vector[1]>>16;
|
||||
x = v.vector[0]>>16;
|
||||
}
|
||||
if (pixman_region_contains_point (pict->pCompositeClip, x, y, &box))
|
||||
if (pixman_region_contains_point (pict->pSourceClip, x, y, &box))
|
||||
buffer[i] = fetch(bits + (y + pict->pDrawable->y)*stride, x + pict->pDrawable->x, indexed);
|
||||
else
|
||||
buffer[i] = 0;
|
||||
|
@ -3194,8 +3195,8 @@ static void fbFetchTransformed(PicturePtr pict, int x, int y, int width, CARD32
|
|||
unit.vector[1] -= unit.vector[2]/2;
|
||||
|
||||
if (pict->repeat == RepeatNormal) {
|
||||
if (PIXREGION_NUM_RECTS(pict->pCompositeClip) == 1) {
|
||||
box = pict->pCompositeClip->extents;
|
||||
if (PIXREGION_NUM_RECTS(pict->pSourceClip) == 1) {
|
||||
box = pict->pSourceClip->extents;
|
||||
for (i = 0; i < width; ++i) {
|
||||
if (!mask || mask[i] & maskBits)
|
||||
{
|
||||
|
@ -3298,14 +3299,14 @@ static void fbFetchTransformed(PicturePtr pict, int x, int y, int width, CARD32
|
|||
|
||||
b = bits + (y1 + pict->pDrawable->y)*stride;
|
||||
|
||||
tl = pixman_region_contains_point(pict->pCompositeClip, x1, y1, &box)
|
||||
tl = pixman_region_contains_point(pict->pSourceClip, x1, y1, &box)
|
||||
? fetch(b, x1 + pict->pDrawable->x, indexed) : 0;
|
||||
tr = pixman_region_contains_point(pict->pCompositeClip, x2, y1, &box)
|
||||
tr = pixman_region_contains_point(pict->pSourceClip, x2, y1, &box)
|
||||
? fetch(b, x2 + pict->pDrawable->x, indexed) : 0;
|
||||
b = bits + (y2 + pict->pDrawable->y)*stride;
|
||||
bl = pixman_region_contains_point(pict->pCompositeClip, x1, y2, &box)
|
||||
bl = pixman_region_contains_point(pict->pSourceClip, x1, y2, &box)
|
||||
? fetch(b, x1 + pict->pDrawable->x, indexed) : 0;
|
||||
br = pixman_region_contains_point(pict->pCompositeClip, x2, y2, &box)
|
||||
br = pixman_region_contains_point(pict->pSourceClip, x2, y2, &box)
|
||||
? fetch(b, x2 + pict->pDrawable->x, indexed) : 0;
|
||||
|
||||
ft = FbGet8(tl,0) * idistx + FbGet8(tr,0) * distx;
|
||||
|
@ -3329,8 +3330,8 @@ static void fbFetchTransformed(PicturePtr pict, int x, int y, int width, CARD32
|
|||
}
|
||||
}
|
||||
} else {
|
||||
if (PIXREGION_NUM_RECTS(pict->pCompositeClip) == 1) {
|
||||
box = pict->pCompositeClip->extents;
|
||||
if (PIXREGION_NUM_RECTS(pict->pSourceClip) == 1) {
|
||||
box = pict->pSourceClip->extents;
|
||||
for (i = 0; i < width; ++i) {
|
||||
if (!mask || mask[i] & maskBits)
|
||||
{
|
||||
|
@ -3431,14 +3432,14 @@ static void fbFetchTransformed(PicturePtr pict, int x, int y, int width, CARD32
|
|||
b = bits + (y1 + pict->pDrawable->y)*stride;
|
||||
x_off = x1 + pict->pDrawable->x;
|
||||
|
||||
tl = pixman_region_contains_point(pict->pCompositeClip, x1, y1, &box)
|
||||
tl = pixman_region_contains_point(pict->pSourceClip, x1, y1, &box)
|
||||
? fetch(b, x_off, indexed) : 0;
|
||||
tr = pixman_region_contains_point(pict->pCompositeClip, x2, y1, &box)
|
||||
tr = pixman_region_contains_point(pict->pSourceClip, x2, y1, &box)
|
||||
? fetch(b, x_off + 1, indexed) : 0;
|
||||
b += stride;
|
||||
bl = pixman_region_contains_point(pict->pCompositeClip, x1, y2, &box)
|
||||
bl = pixman_region_contains_point(pict->pSourceClip, x1, y2, &box)
|
||||
? fetch(b, x_off, indexed) : 0;
|
||||
br = pixman_region_contains_point(pict->pCompositeClip, x2, y2, &box)
|
||||
br = pixman_region_contains_point(pict->pSourceClip, x2, y2, &box)
|
||||
? fetch(b, x_off + 1, indexed) : 0;
|
||||
|
||||
ft = FbGet8(tl,0) * idistx + FbGet8(tr,0) * distx;
|
||||
|
@ -3500,7 +3501,7 @@ static void fbFetchTransformed(PicturePtr pict, int x, int y, int width, CARD32
|
|||
for (x = x1; x < x2; x++) {
|
||||
if (*p) {
|
||||
int tx = (pict->repeat == RepeatNormal) ? MOD (x, pict->pDrawable->width) : x;
|
||||
if (pixman_region_contains_point (pict->pCompositeClip, tx, ty, &box)) {
|
||||
if (pixman_region_contains_point (pict->pSourceClip, tx, ty, &box)) {
|
||||
FbBits *b = bits + (ty + pict->pDrawable->y)*stride;
|
||||
CARD32 c = fetch(b, tx + pict->pDrawable->x, indexed);
|
||||
|
||||
|
@ -3755,6 +3756,24 @@ fbCompositeRect (const FbComposeData *data, CARD32 *scanline_buffer)
|
|||
if (!compose)
|
||||
return;
|
||||
|
||||
/* XXX: The non-MMX version of some of the fbCompose functions
|
||||
* overwrite the source or mask data (ones that use
|
||||
* fbCombineMaskC, fbCombineMaskAlphaC, or fbCombineMaskValueC
|
||||
* as helpers). This causes problems with the optimization in
|
||||
* this function that only fetches the source or mask once if
|
||||
* possible. If we're on a non-MMX machine, disable this
|
||||
* optimization as a bandaid fix.
|
||||
*
|
||||
* https://bugs.freedesktop.org/show_bug.cgi?id=5777
|
||||
*/
|
||||
#ifdef USE_MMX
|
||||
if (!fbHaveMMX())
|
||||
#endif
|
||||
{
|
||||
srcClass = SourcePictClassUnknown;
|
||||
maskClass = SourcePictClassUnknown;
|
||||
}
|
||||
|
||||
for (i = 0; i < data->height; ++i) {
|
||||
/* fill first half of scanline with source */
|
||||
if (fetchSrc)
|
||||
|
@ -3764,7 +3783,7 @@ fbCompositeRect (const FbComposeData *data, CARD32 *scanline_buffer)
|
|||
/* fetch mask before source so that fetching of
|
||||
source can be optimized */
|
||||
fetchMask (data->mask, data->xMask, data->yMask + i,
|
||||
data->width, mask_buffer, 0, 0);
|
||||
data->width, mask_buffer, NULL, 0);
|
||||
|
||||
if (maskClass == SourcePictClassHorizontal)
|
||||
fetchMask = NULL;
|
||||
|
@ -3773,7 +3792,7 @@ fbCompositeRect (const FbComposeData *data, CARD32 *scanline_buffer)
|
|||
if (srcClass == SourcePictClassHorizontal)
|
||||
{
|
||||
fetchSrc (data->src, data->xSrc, data->ySrc + i,
|
||||
data->width, src_buffer, 0, 0);
|
||||
data->width, src_buffer, NULL, 0);
|
||||
fetchSrc = NULL;
|
||||
}
|
||||
else
|
||||
|
@ -3786,7 +3805,7 @@ fbCompositeRect (const FbComposeData *data, CARD32 *scanline_buffer)
|
|||
else if (fetchMask)
|
||||
{
|
||||
fetchMask (data->mask, data->xMask, data->yMask + i,
|
||||
data->width, mask_buffer, 0, 0);
|
||||
data->width, mask_buffer, NULL, 0);
|
||||
}
|
||||
|
||||
if (store)
|
||||
|
@ -3794,7 +3813,7 @@ fbCompositeRect (const FbComposeData *data, CARD32 *scanline_buffer)
|
|||
/* fill dest into second half of scanline */
|
||||
if (fetchDest)
|
||||
fetchDest (data->dest, data->xDest, data->yDest + i,
|
||||
data->width, dest_buffer, 0, 0);
|
||||
data->width, dest_buffer, NULL, 0);
|
||||
|
||||
/* blend */
|
||||
compose (dest_buffer, src_buffer, mask_buffer, data->width);
|
||||
|
@ -3814,8 +3833,8 @@ fbCompositeRect (const FbComposeData *data, CARD32 *scanline_buffer)
|
|||
}
|
||||
else
|
||||
{
|
||||
CARD32 *src_mask_buffer = 0; /* squelch bogus compiler warning */
|
||||
CARD32 *mask_buffer = 0;
|
||||
CARD32 *src_mask_buffer = NULL; /* squelch bogus compiler warning */
|
||||
CARD32 *mask_buffer = NULL;
|
||||
CombineFuncU compose = composeFunctions.combineU[data->op];
|
||||
if (!compose)
|
||||
return;
|
||||
|
@ -3832,7 +3851,7 @@ fbCompositeRect (const FbComposeData *data, CARD32 *scanline_buffer)
|
|||
/* fetch mask before source so that fetching of
|
||||
source can be optimized */
|
||||
fetchMask (data->mask, data->xMask, data->yMask + i,
|
||||
data->width, mask_buffer, 0, 0);
|
||||
data->width, mask_buffer, NULL, 0);
|
||||
|
||||
if (maskClass == SourcePictClassHorizontal)
|
||||
fetchMask = NULL;
|
||||
|
@ -3841,7 +3860,7 @@ fbCompositeRect (const FbComposeData *data, CARD32 *scanline_buffer)
|
|||
if (srcClass == SourcePictClassHorizontal)
|
||||
{
|
||||
fetchSrc (data->src, data->xSrc, data->ySrc + i,
|
||||
data->width, src_buffer, 0, 0);
|
||||
data->width, src_buffer, NULL, 0);
|
||||
|
||||
if (mask_buffer)
|
||||
{
|
||||
|
@ -3870,7 +3889,7 @@ fbCompositeRect (const FbComposeData *data, CARD32 *scanline_buffer)
|
|||
else if (fetchMask)
|
||||
{
|
||||
fetchMask (data->mask, data->xMask, data->yMask + i,
|
||||
data->width, mask_buffer, 0, 0);
|
||||
data->width, mask_buffer, NULL, 0);
|
||||
|
||||
fbCombineInU (mask_buffer, src_buffer, data->width);
|
||||
|
||||
|
@ -3882,7 +3901,7 @@ fbCompositeRect (const FbComposeData *data, CARD32 *scanline_buffer)
|
|||
/* fill dest into second half of scanline */
|
||||
if (fetchDest)
|
||||
fetchDest (data->dest, data->xDest, data->yDest + i,
|
||||
data->width, dest_buffer, 0, 0);
|
||||
data->width, dest_buffer, NULL, 0);
|
||||
|
||||
/* blend */
|
||||
compose (dest_buffer, src_mask_buffer, data->width);
|
||||
|
|
|
@ -1060,7 +1060,7 @@ fbCompositeSolidMask_nx8888x8888Cmmx (pixman_operator_t op,
|
|||
|
||||
while (height--)
|
||||
{
|
||||
int twidth = width;
|
||||
unsigned int twidth = width;
|
||||
CARD32 *p = (CARD32 *)maskLine;
|
||||
CARD32 *q = (CARD32 *)dstLine;
|
||||
|
||||
|
@ -2020,7 +2020,7 @@ fbCompositeSolidMask_nx8888x0565Cmmx (pixman_operator_t op,
|
|||
|
||||
while (height--)
|
||||
{
|
||||
int twidth = width;
|
||||
unsigned int twidth = width;
|
||||
CARD32 *p = (CARD32 *)maskLine;
|
||||
CARD16 *q = (CARD16 *)dstLine;
|
||||
|
||||
|
@ -2270,7 +2270,7 @@ fbSolidFillmmx (FbPixels *pDraw,
|
|||
|
||||
while (height--)
|
||||
{
|
||||
int w;
|
||||
unsigned int w;
|
||||
CARD8 *d = byte_line;
|
||||
byte_line += stride;
|
||||
w = byte_width;
|
||||
|
@ -2386,7 +2386,7 @@ fbCopyAreammx (FbPixels *pSrc,
|
|||
|
||||
while (height--)
|
||||
{
|
||||
int w;
|
||||
unsigned int w;
|
||||
CARD8 *s = src_bytes;
|
||||
CARD8 *d = dst_bytes;
|
||||
src_bytes += src_stride;
|
||||
|
@ -2401,7 +2401,7 @@ fbCopyAreammx (FbPixels *pSrc,
|
|||
d += 2;
|
||||
}
|
||||
|
||||
while (w >= 4 && ((unsigned int)d & 7))
|
||||
while (w >= 4 && ((unsigned long)d & 7))
|
||||
{
|
||||
*(CARD32 *)d = *(CARD32 *)s;
|
||||
|
||||
|
|
|
@ -29,6 +29,7 @@
|
|||
#ifdef USE_MMX
|
||||
|
||||
#if !defined(__amd64__) && !defined(__x86_64__)
|
||||
pixman_private
|
||||
Bool fbHaveMMX(void);
|
||||
#else
|
||||
#define fbHaveMMX() TRUE
|
||||
|
@ -40,8 +41,10 @@ Bool fbHaveMMX(void);
|
|||
|
||||
#ifdef USE_MMX
|
||||
|
||||
pixman_private
|
||||
void fbComposeSetupMMX(void);
|
||||
|
||||
pixman_private
|
||||
void fbCompositeSolidMask_nx8888x0565Cmmx (pixman_operator_t op,
|
||||
PicturePtr pSrc,
|
||||
PicturePtr pMask,
|
||||
|
@ -54,6 +57,7 @@ void fbCompositeSolidMask_nx8888x0565Cmmx (pixman_operator_t op,
|
|||
INT16 yDst,
|
||||
CARD16 width,
|
||||
CARD16 height);
|
||||
pixman_private
|
||||
void fbCompositeSrcAdd_8888x8888mmx (pixman_operator_t op,
|
||||
PicturePtr pSrc,
|
||||
PicturePtr pMask,
|
||||
|
@ -66,6 +70,7 @@ void fbCompositeSrcAdd_8888x8888mmx (pixman_operator_t op,
|
|||
INT16 yDst,
|
||||
CARD16 width,
|
||||
CARD16 height);
|
||||
pixman_private
|
||||
void fbCompositeSolidMask_nx8888x8888Cmmx (pixman_operator_t op,
|
||||
PicturePtr pSrc,
|
||||
PicturePtr pMask,
|
||||
|
@ -78,6 +83,7 @@ void fbCompositeSolidMask_nx8888x8888Cmmx (pixman_operator_t op,
|
|||
INT16 yDst,
|
||||
CARD16 width,
|
||||
CARD16 height);
|
||||
pixman_private
|
||||
void fbCompositeSolidMask_nx8x8888mmx (pixman_operator_t op,
|
||||
PicturePtr pSrc,
|
||||
PicturePtr pMask,
|
||||
|
@ -90,6 +96,7 @@ void fbCompositeSolidMask_nx8x8888mmx (pixman_operator_t op,
|
|||
INT16 yDst,
|
||||
CARD16 width,
|
||||
CARD16 height);
|
||||
pixman_private
|
||||
void fbCompositeSolidMaskSrc_nx8x8888mmx (pixman_operator_t op,
|
||||
PicturePtr pSrc,
|
||||
PicturePtr pMask,
|
||||
|
@ -102,6 +109,7 @@ void fbCompositeSolidMaskSrc_nx8x8888mmx (pixman_operator_t op,
|
|||
INT16 yDst,
|
||||
CARD16 width,
|
||||
CARD16 height);
|
||||
pixman_private
|
||||
void fbCompositeSrcAdd_8000x8000mmx (pixman_operator_t op,
|
||||
PicturePtr pSrc,
|
||||
PicturePtr pMask,
|
||||
|
@ -114,6 +122,7 @@ void fbCompositeSrcAdd_8000x8000mmx (pixman_operator_t op,
|
|||
INT16 yDst,
|
||||
CARD16 width,
|
||||
CARD16 height);
|
||||
pixman_private
|
||||
void fbCompositeSrc_8888RevNPx8888mmx (pixman_operator_t op,
|
||||
PicturePtr pSrc,
|
||||
PicturePtr pMask,
|
||||
|
@ -126,6 +135,7 @@ void fbCompositeSrc_8888RevNPx8888mmx (pixman_operator_t op,
|
|||
INT16 yDst,
|
||||
CARD16 width,
|
||||
CARD16 height);
|
||||
pixman_private
|
||||
void fbCompositeSrc_8888RevNPx0565mmx (pixman_operator_t op,
|
||||
PicturePtr pSrc,
|
||||
PicturePtr pMask,
|
||||
|
@ -138,6 +148,7 @@ void fbCompositeSrc_8888RevNPx0565mmx (pixman_operator_t op,
|
|||
INT16 yDst,
|
||||
CARD16 width,
|
||||
CARD16 height);
|
||||
pixman_private
|
||||
void fbCompositeSolid_nx8888mmx (pixman_operator_t op,
|
||||
PicturePtr pSrc,
|
||||
PicturePtr pMask,
|
||||
|
@ -150,6 +161,7 @@ void fbCompositeSolid_nx8888mmx (pixman_operator_t op,
|
|||
INT16 yDst,
|
||||
CARD16 width,
|
||||
CARD16 height);
|
||||
pixman_private
|
||||
void fbCompositeSolid_nx0565mmx (pixman_operator_t op,
|
||||
PicturePtr pSrc,
|
||||
PicturePtr pMask,
|
||||
|
@ -162,6 +174,7 @@ void fbCompositeSolid_nx0565mmx (pixman_operator_t op,
|
|||
INT16 yDst,
|
||||
CARD16 width,
|
||||
CARD16 height);
|
||||
pixman_private
|
||||
void fbCompositeSolidMask_nx8x0565mmx (pixman_operator_t op,
|
||||
PicturePtr pSrc,
|
||||
PicturePtr pMask,
|
||||
|
@ -174,6 +187,7 @@ void fbCompositeSolidMask_nx8x0565mmx (pixman_operator_t op,
|
|||
INT16 yDst,
|
||||
CARD16 width,
|
||||
CARD16 height);
|
||||
pixman_private
|
||||
void fbCompositeSrc_x888x8x8888mmx (pixman_operator_t op,
|
||||
PicturePtr pSrc,
|
||||
PicturePtr pMask,
|
||||
|
@ -186,6 +200,7 @@ void fbCompositeSrc_x888x8x8888mmx (pixman_operator_t op,
|
|||
INT16 yDst,
|
||||
CARD16 width,
|
||||
CARD16 height);
|
||||
pixman_private
|
||||
void fbCompositeSrc_8888x8x8888mmx (pixman_operator_t op,
|
||||
PicturePtr pSrc,
|
||||
PicturePtr pMask,
|
||||
|
@ -198,6 +213,7 @@ void fbCompositeSrc_8888x8x8888mmx (pixman_operator_t op,
|
|||
INT16 yDst,
|
||||
CARD16 width,
|
||||
CARD16 height);
|
||||
pixman_private
|
||||
void fbCompositeSrc_8888x8888mmx (pixman_operator_t op,
|
||||
PicturePtr pSrc,
|
||||
PicturePtr pMask,
|
||||
|
@ -210,6 +226,7 @@ void fbCompositeSrc_8888x8888mmx (pixman_operator_t op,
|
|||
INT16 yDst,
|
||||
CARD16 width,
|
||||
CARD16 height);
|
||||
pixman_private
|
||||
Bool fbCopyAreammx (FbPixels *pSrc,
|
||||
FbPixels *pDst,
|
||||
int src_x,
|
||||
|
@ -218,6 +235,8 @@ Bool fbCopyAreammx (FbPixels *pSrc,
|
|||
int dst_y,
|
||||
int width,
|
||||
int height);
|
||||
|
||||
pixman_private
|
||||
void fbCompositeCopyAreammx (pixman_operator_t op,
|
||||
PicturePtr pSrc,
|
||||
PicturePtr pMask,
|
||||
|
@ -230,6 +249,8 @@ void fbCompositeCopyAreammx (pixman_operator_t op,
|
|||
INT16 yDst,
|
||||
CARD16 width,
|
||||
CARD16 height);
|
||||
|
||||
pixman_private
|
||||
Bool fbSolidFillmmx (FbPixels *pDraw,
|
||||
int x,
|
||||
int y,
|
||||
|
|
|
@ -1349,7 +1349,7 @@ pixman_composite (pixman_operator_t op,
|
|||
Bool maskAlphaMap = FALSE;
|
||||
Bool dstAlphaMap = pDst->alphaMap != 0;
|
||||
int x_msk, y_msk, x_src, y_src, x_dst, y_dst;
|
||||
int w, h, w_this, h_this;
|
||||
unsigned int w, h, w_this, h_this;
|
||||
|
||||
#ifdef USE_MMX
|
||||
static Bool mmx_setup = FALSE;
|
||||
|
@ -1798,6 +1798,17 @@ pixman_composite (pixman_operator_t op,
|
|||
}
|
||||
}
|
||||
break;
|
||||
case PIXMAN_OPERATOR_CLEAR:
|
||||
case PIXMAN_OPERATOR_DST:
|
||||
case PIXMAN_OPERATOR_OVER_REVERSE:
|
||||
case PIXMAN_OPERATOR_IN:
|
||||
case PIXMAN_OPERATOR_IN_REVERSE:
|
||||
case PIXMAN_OPERATOR_OUT:
|
||||
case PIXMAN_OPERATOR_OUT_REVERSE:
|
||||
case PIXMAN_OPERATOR_ATOP:
|
||||
case PIXMAN_OPERATOR_ATOP_REVERSE:
|
||||
case PIXMAN_OPERATOR_XOR:
|
||||
case PIXMAN_OPERATOR_SATURATE:
|
||||
default:
|
||||
/* For any operator not specifically handled above we default out to the general code. */
|
||||
func = NULL;
|
||||
|
@ -1891,7 +1902,6 @@ pixman_composite (pixman_operator_t op,
|
|||
}
|
||||
pixman_region_destroy (region);
|
||||
}
|
||||
slim_hidden_def(pixman_composite);
|
||||
|
||||
/* The CPU detection code needs to be in a file not compiled with
|
||||
* "-mmmx -msse", as gcc would generate CMOV instructions otherwise
|
||||
|
|
|
@ -53,7 +53,6 @@ pixman_color_to_pixel (const pixman_format_t *format,
|
|||
a = a << format->alpha;
|
||||
*pixel = r|g|b|a;
|
||||
}
|
||||
slim_hidden_def(pixman_color_to_pixel);
|
||||
|
||||
static uint16_t
|
||||
FbFillColor (uint32_t pixel, int bits)
|
||||
|
|
|
@ -23,7 +23,7 @@
|
|||
|
||||
#include "icint.h"
|
||||
|
||||
#define Mask(n) ((n) == 32 ? 0xffffffff : ((1 << (n))-1))
|
||||
#define Mask(n) ((n) == 32 ? 0xffffffff : (unsigned) ((1 << (n))-1))
|
||||
|
||||
pixman_format_t *
|
||||
pixman_format_create (pixman_format_name_t name)
|
||||
|
@ -53,6 +53,18 @@ pixman_format_create (pixman_format_name_t name)
|
|||
0xf800,
|
||||
0x07e0,
|
||||
0x001f);
|
||||
case PIXMAN_FORMAT_NAME_ABGR32:
|
||||
return pixman_format_create_masks (32,
|
||||
0xff000000,
|
||||
0x000000ff,
|
||||
0x0000ff00,
|
||||
0x00ff0000);
|
||||
case PIXMAN_FORMAT_NAME_BGR24:
|
||||
return pixman_format_create_masks (32,
|
||||
0x0,
|
||||
0x000000ff,
|
||||
0x0000ff00,
|
||||
0x00ff0000);
|
||||
}
|
||||
|
||||
return NULL;
|
||||
|
@ -159,7 +171,6 @@ pixman_format_init (pixman_format_t *format, int format_code)
|
|||
(format->blueMask << format->blue) |
|
||||
(format->greenMask << format->green));
|
||||
}
|
||||
slim_hidden_def(pixman_format_init);
|
||||
|
||||
void
|
||||
pixman_format_destroy (pixman_format_t *format)
|
||||
|
@ -169,11 +180,11 @@ pixman_format_destroy (pixman_format_t *format)
|
|||
|
||||
void
|
||||
pixman_format_get_masks (pixman_format_t *format,
|
||||
int *bpp,
|
||||
int *alpha_mask,
|
||||
int *red_mask,
|
||||
int *green_mask,
|
||||
int *blue_mask)
|
||||
unsigned int *bpp,
|
||||
unsigned int *alpha_mask,
|
||||
unsigned int *red_mask,
|
||||
unsigned int *green_mask,
|
||||
unsigned int *blue_mask)
|
||||
{
|
||||
*bpp = PICT_FORMAT_BPP (format->format_code);
|
||||
|
||||
|
|
|
@ -45,7 +45,6 @@ pixman_image_create (pixman_format_t *format,
|
|||
|
||||
return image;
|
||||
}
|
||||
slim_hidden_def(pixman_image_create);
|
||||
|
||||
pixman_image_t *
|
||||
pixman_image_create_for_data (FbBits *data, pixman_format_t *format, int width, int height, int bpp, int stride)
|
||||
|
@ -188,8 +187,8 @@ _pixman_create_source_image (void)
|
|||
pixman_image_t *image;
|
||||
|
||||
image = (pixman_image_t *) malloc (sizeof (pixman_image_t));
|
||||
image->pDrawable = 0;
|
||||
image->pixels = 0;
|
||||
image->pDrawable = NULL;
|
||||
image->pixels = NULL;
|
||||
image->format_code = PICT_a8r8g8b8;
|
||||
|
||||
pixman_image_init (image);
|
||||
|
@ -206,18 +205,18 @@ pixman_image_create_linear_gradient (const pixman_linear_gradient_t *gradient,
|
|||
pixman_image_t *image;
|
||||
|
||||
if (n_stops < 2)
|
||||
return 0;
|
||||
return NULL;
|
||||
|
||||
image = _pixman_create_source_image ();
|
||||
if (!image)
|
||||
return 0;
|
||||
return NULL;
|
||||
|
||||
linear = malloc (sizeof (pixman_linear_gradient_image_t) +
|
||||
sizeof (pixman_gradient_stop_t) * n_stops);
|
||||
if (!linear)
|
||||
{
|
||||
free (image);
|
||||
return 0;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
linear->stops = (pixman_gradient_stop_t *) (linear + 1);
|
||||
|
@ -233,8 +232,9 @@ pixman_image_create_linear_gradient (const pixman_linear_gradient_t *gradient,
|
|||
|
||||
if (_pixman_init_gradient (&image->pSourcePict->gradient, stops, n_stops))
|
||||
{
|
||||
free (linear);
|
||||
free (image);
|
||||
return 0;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return image;
|
||||
|
@ -250,18 +250,18 @@ pixman_image_create_radial_gradient (const pixman_radial_gradient_t *gradient,
|
|||
double x;
|
||||
|
||||
if (n_stops < 2)
|
||||
return 0;
|
||||
return NULL;
|
||||
|
||||
image = _pixman_create_source_image ();
|
||||
if (!image)
|
||||
return 0;
|
||||
return NULL;
|
||||
|
||||
radial = malloc (sizeof (pixman_radial_gradient_image_t) +
|
||||
sizeof (pixman_gradient_stop_t) * n_stops);
|
||||
if (!radial)
|
||||
{
|
||||
free (image);
|
||||
return 0;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
radial->stops = (pixman_gradient_stop_t *) (radial + 1);
|
||||
|
@ -288,8 +288,9 @@ pixman_image_create_radial_gradient (const pixman_radial_gradient_t *gradient,
|
|||
|
||||
if (_pixman_init_gradient (&image->pSourcePict->gradient, stops, n_stops))
|
||||
{
|
||||
free (radial);
|
||||
free (image);
|
||||
return 0;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return image;
|
||||
|
@ -367,7 +368,6 @@ pixman_image_set_component_alpha (pixman_image_t *image,
|
|||
if (image)
|
||||
image->componentAlpha = component_alpha;
|
||||
}
|
||||
slim_hidden_def(pixman_image_set_component_alpha);
|
||||
|
||||
int
|
||||
pixman_image_set_transform (pixman_image_t *image,
|
||||
|
@ -410,7 +410,6 @@ pixman_image_set_repeat (pixman_image_t *image,
|
|||
if (image)
|
||||
image->repeat = repeat;
|
||||
}
|
||||
slim_hidden_def(pixman_image_set_repeat);
|
||||
|
||||
void
|
||||
pixman_image_set_filter (pixman_image_t *image,
|
||||
|
@ -468,7 +467,7 @@ pixman_image_get_data (pixman_image_t *image)
|
|||
if (image->pixels)
|
||||
return image->pixels->data;
|
||||
|
||||
return 0;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -503,7 +502,6 @@ pixman_image_destroy (pixman_image_t *image)
|
|||
|
||||
free (image);
|
||||
}
|
||||
slim_hidden_def(pixman_image_destroy);
|
||||
|
||||
void
|
||||
pixman_image_destroyClip (pixman_image_t *image)
|
||||
|
|
|
@ -243,7 +243,7 @@ FbComputeCompositeRegion (pixman_region16_t *region,
|
|||
uint16_t width,
|
||||
uint16_t height);
|
||||
|
||||
int
|
||||
pixman_private int
|
||||
miIsSolidAlpha (pixman_image_t *src);
|
||||
|
||||
/*
|
||||
|
|
|
@ -33,8 +33,6 @@
|
|||
#include <string.h>
|
||||
#include <limits.h>
|
||||
|
||||
#include "slim_internal.h"
|
||||
|
||||
#ifndef __GNUC__
|
||||
#define __inline
|
||||
#endif
|
||||
|
@ -813,7 +811,7 @@ fbRasterizeTrapezoid (pixman_image_t *pMask,
|
|||
# endif
|
||||
#else
|
||||
# define ICINT_NEED_IC_ONES
|
||||
int
|
||||
pixman_private int
|
||||
_FbOnes(unsigned long mask);
|
||||
#endif
|
||||
|
||||
|
@ -852,17 +850,6 @@ pixman_private int
|
|||
pixman_transform_point (pixman_transform_t *transform,
|
||||
pixman_vector_t *vector);
|
||||
|
||||
/* Avoid unnessecary PLT entries. */
|
||||
|
||||
slim_hidden_proto(pixman_image_create)
|
||||
slim_hidden_proto(pixman_color_to_pixel)
|
||||
slim_hidden_proto(pixman_format_init)
|
||||
slim_hidden_proto(pixman_image_destroy)
|
||||
slim_hidden_proto(pixman_fill_rectangles)
|
||||
slim_hidden_proto(pixman_image_set_component_alpha)
|
||||
slim_hidden_proto(pixman_image_set_repeat)
|
||||
slim_hidden_proto(pixman_composite)
|
||||
|
||||
#include "icrop.h"
|
||||
|
||||
/* XXX: For now, I'm just wholesale pasting Xserver/render/picture.h here: */
|
||||
|
|
|
@ -363,4 +363,3 @@ bail1:
|
|||
;
|
||||
}
|
||||
}
|
||||
slim_hidden_def(pixman_fill_rectangles);
|
||||
|
|
|
@ -143,7 +143,7 @@ pixman_composite_triangles (pixman_operator_t op,
|
|||
const pixman_triangle_t *tris,
|
||||
int ntris)
|
||||
{
|
||||
pixman_box16_t bounds;
|
||||
pixman_box16_t bounds = {0, 0, 0, 0}; /* shut gcc up */
|
||||
pixman_image_t *image = NULL;
|
||||
int xDst, yDst;
|
||||
int xRel, yRel;
|
||||
|
@ -215,7 +215,7 @@ pixman_composite_tri_strip (pixman_operator_t op,
|
|||
int npoints)
|
||||
{
|
||||
pixman_triangle_t tri;
|
||||
pixman_box16_t bounds;
|
||||
pixman_box16_t bounds = {0, 0, 0, 0}; /* shut gcc up */
|
||||
pixman_image_t *image = NULL;
|
||||
int xDst, yDst;
|
||||
int xRel, yRel;
|
||||
|
@ -292,7 +292,7 @@ pixman_composite_tri_fan (pixman_operator_t op,
|
|||
int npoints)
|
||||
{
|
||||
pixman_triangle_t tri;
|
||||
pixman_box16_t bounds;
|
||||
pixman_box16_t bounds = {0, 0, 0, 0}; /* shut gcc up */
|
||||
pixman_image_t *image = NULL;
|
||||
const pixman_point_fixed_t *first;
|
||||
int xDst, yDst;
|
||||
|
|
|
@ -281,5 +281,5 @@ fbStippleTable(int bits)
|
|||
case 8:
|
||||
return fbStipple8Bits;
|
||||
}
|
||||
return 0;
|
||||
return NULL;
|
||||
}
|
||||
|
|
|
@ -1,79 +1,79 @@
|
|||
#define pixman_add_trapezoids _moz_cairo_pixman_add_trapezoids
|
||||
#define pixman_color_to_pixel _moz_cairo_pixman_color_to_pixel
|
||||
#define composeFunctions _moz_cairo_pixman_compose_functions
|
||||
#define fbComposeSetupMMX _moz_cairo_pixman_compose_setup_mmx
|
||||
#define pixman_composite _moz_cairo_pixman_composite
|
||||
#define fbCompositeCopyAreammx _moz_cairo_pixman_composite_copy_area_mmx
|
||||
#define fbCompositeSolidMask_nx8888x0565Cmmx _moz_cairo_pixman_composite_solid_mask_nx8888x0565Cmmx
|
||||
#define fbCompositeSolidMask_nx8888x8888Cmmx _moz_cairo_pixman_composite_solid_mask_nx8888x8888Cmmx
|
||||
#define fbCompositeSolidMask_nx8x0565mmx _moz_cairo_pixman_composite_solid_mask_nx8x0565mmx
|
||||
#define fbCompositeSolidMask_nx8x8888mmx _moz_cairo_pixman_composite_solid_mask_nx8x8888mmx
|
||||
#define fbCompositeSolidMaskSrc_nx8x8888mmx _moz_cairo_pixman_composite_solid_mask_src_nx8x8888mmx
|
||||
#define fbCompositeSolid_nx0565mmx _moz_cairo_pixman_composite_solid_nx0565mmx
|
||||
#define fbCompositeSolid_nx8888mmx _moz_cairo_pixman_composite_solid_nx8888mmx
|
||||
#define fbCompositeSrc_8888RevNPx0565mmx _moz_cairo_pixman_composite_src_8888RevNPx0565mmx
|
||||
#define fbCompositeSrc_8888RevNPx8888mmx _moz_cairo_pixman_composite_src_8888RevNPx8888_mmx
|
||||
#define fbCompositeSrc_8888x8888mmx _moz_cairo_pixman_composite_src_8888x8888mmx
|
||||
#define fbCompositeSrc_8888x8x8888mmx _moz_cairo_pixman_composite_src_8888x8x8888mmx
|
||||
#define fbCompositeSrcAdd_8000x8000mmx _moz_cairo_pixman_composite_src_add_8000x8000mmx
|
||||
#define fbCompositeSrcAdd_8888x8888mmx _moz_cairo_pixman_composite_src_add_8888x8888mmx
|
||||
#define fbCompositeSrc_x888x8x8888mmx _moz_cairo_pixman_composite_src_x888x8x8888mmx
|
||||
#define pixman_composite_trapezoids _moz_cairo_pixman_composite_trapezoids
|
||||
#define pixman_composite_tri_fan _moz_cairo_pixman_composite_tri_fan
|
||||
#define pixman_composite_tri_strip _moz_cairo_pixman_composite_tri_strip
|
||||
#define pixman_composite_triangles _moz_cairo_pixman_composite_triangles
|
||||
#define fbCopyAreammx _moz_cairo_pixman_copy_area_mmx
|
||||
#define pixman_fill_rectangle _moz_cairo_pixman_fill_rectangle
|
||||
#define pixman_fill_rectangles _moz_cairo_pixman_fill_rectangles
|
||||
#define pixman_format_create _moz_cairo_pixman_format_create
|
||||
#define pixman_format_create_masks _moz_cairo_pixman_format_create_masks
|
||||
#define pixman_format_destroy _moz_cairo_pixman_format_destroy
|
||||
#define pixman_format_get_masks _moz_cairo_pixman_format_get_masks
|
||||
#define pixman_format_init _moz_cairo_pixman_format_init
|
||||
#define pixman_add_trapezoids _cairo_pixman_add_trapezoids
|
||||
#define pixman_color_to_pixel _cairo_pixman_color_to_pixel
|
||||
#define composeFunctions _cairo_pixman_compose_functions
|
||||
#define fbComposeSetupMMX _cairo_pixman_compose_setup_mmx
|
||||
#define pixman_composite _cairo_pixman_composite
|
||||
#define fbCompositeCopyAreammx _cairo_pixman_composite_copy_area_mmx
|
||||
#define fbCompositeSolidMask_nx8888x0565Cmmx _cairo_pixman_composite_solid_mask_nx8888x0565Cmmx
|
||||
#define fbCompositeSolidMask_nx8888x8888Cmmx _cairo_pixman_composite_solid_mask_nx8888x8888Cmmx
|
||||
#define fbCompositeSolidMask_nx8x0565mmx _cairo_pixman_composite_solid_mask_nx8x0565mmx
|
||||
#define fbCompositeSolidMask_nx8x8888mmx _cairo_pixman_composite_solid_mask_nx8x8888mmx
|
||||
#define fbCompositeSolidMaskSrc_nx8x8888mmx _cairo_pixman_composite_solid_mask_src_nx8x8888mmx
|
||||
#define fbCompositeSolid_nx0565mmx _cairo_pixman_composite_solid_nx0565mmx
|
||||
#define fbCompositeSolid_nx8888mmx _cairo_pixman_composite_solid_nx8888mmx
|
||||
#define fbCompositeSrc_8888RevNPx0565mmx _cairo_pixman_composite_src_8888RevNPx0565mmx
|
||||
#define fbCompositeSrc_8888RevNPx8888mmx _cairo_pixman_composite_src_8888RevNPx8888_mmx
|
||||
#define fbCompositeSrc_8888x8888mmx _cairo_pixman_composite_src_8888x8888mmx
|
||||
#define fbCompositeSrc_8888x8x8888mmx _cairo_pixman_composite_src_8888x8x8888mmx
|
||||
#define fbCompositeSrcAdd_8000x8000mmx _cairo_pixman_composite_src_add_8000x8000mmx
|
||||
#define fbCompositeSrcAdd_8888x8888mmx _cairo_pixman_composite_src_add_8888x8888mmx
|
||||
#define fbCompositeSrc_x888x8x8888mmx _cairo_pixman_composite_src_x888x8x8888mmx
|
||||
#define pixman_composite_trapezoids _cairo_pixman_composite_trapezoids
|
||||
#define pixman_composite_tri_fan _cairo_pixman_composite_tri_fan
|
||||
#define pixman_composite_tri_strip _cairo_pixman_composite_tri_strip
|
||||
#define pixman_composite_triangles _cairo_pixman_composite_triangles
|
||||
#define fbCopyAreammx _cairo_pixman_copy_area_mmx
|
||||
#define pixman_fill_rectangle _cairo_pixman_fill_rectangle
|
||||
#define pixman_fill_rectangles _cairo_pixman_fill_rectangles
|
||||
#define pixman_format_create _cairo_pixman_format_create
|
||||
#define pixman_format_create_masks _cairo_pixman_format_create_masks
|
||||
#define pixman_format_destroy _cairo_pixman_format_destroy
|
||||
#define pixman_format_get_masks _cairo_pixman_format_get_masks
|
||||
#define pixman_format_init _cairo_pixman_format_init
|
||||
#if defined(USE_MMX) && !defined(__amd64__) && !defined(__x86_64__)
|
||||
#define fbHaveMMX _moz_cairo_pixman_have_mmx
|
||||
#define fbHaveMMX _cairo_pixman_have_mmx
|
||||
#endif
|
||||
#define pixman_image_create _moz_cairo_pixman_image_create
|
||||
#define pixman_image_create_for_data _moz_cairo_pixman_image_create_for_data
|
||||
#define pixman_image_destroy _moz_cairo_pixman_image_destroy
|
||||
#define pixman_image_get_data _moz_cairo_pixman_image_get_data
|
||||
#define pixman_image_get_depth _moz_cairo_pixman_image_get_depth
|
||||
#define pixman_image_get_format _moz_cairo_pixman_image_get_format
|
||||
#define pixman_image_get_height _moz_cairo_pixman_image_get_height
|
||||
#define pixman_image_get_stride _moz_cairo_pixman_image_get_stride
|
||||
#define pixman_image_get_width _moz_cairo_pixman_image_get_width
|
||||
#define pixman_image_set_clip_region _moz_cairo_pixman_image_set_clip_region
|
||||
#define pixman_image_set_component_alpha _moz_cairo_pixman_image_set_component_alpha
|
||||
#define pixman_image_set_filter _moz_cairo_pixman_image_set_filter
|
||||
#define pixman_image_set_repeat _moz_cairo_pixman_image_set_repeat
|
||||
#define pixman_image_set_transform _moz_cairo_pixman_image_set_transform
|
||||
#define pixman_image_create_linear_gradient _moz_cairo_pixman_image_create_linear_gradient
|
||||
#define pixman_image_create_radial_gradient _moz_cairo_pixman_image_create_radial_gradient
|
||||
#define miIsSolidAlpha _moz_cairo_pixman_is_solid_alpha
|
||||
#define pixman_pixel_to_color _moz_cairo_pixman_pixel_to_color
|
||||
#define pixman_region_append _moz_cairo_pixman_region_append
|
||||
#define pixman_region_contains_point _moz_cairo_pixman_region_contains_point
|
||||
#define pixman_region_contains_rectangle _moz_cairo_pixman_region_contains_rectangle
|
||||
#define pixman_region_copy _moz_cairo_pixman_region_copy
|
||||
#define pixman_region_create _moz_cairo_pixman_region_create
|
||||
#define pixman_region_create_simple _moz_cairo_pixman_region_create_simple
|
||||
#define pixman_region_destroy _moz_cairo_pixman_region_destroy
|
||||
#define pixman_region_empty _moz_cairo_pixman_region_empty
|
||||
#define pixman_region_extents _moz_cairo_pixman_region_extents
|
||||
#define pixman_region_intersect _moz_cairo_pixman_region_intersect
|
||||
#define pixman_region_inverse _moz_cairo_pixman_region_inverse
|
||||
#define pixman_region_not_empty _moz_cairo_pixman_region_not_empty
|
||||
#define pixman_region_num_rects _moz_cairo_pixman_region_num_rects
|
||||
#define pixman_region_rects _moz_cairo_pixman_region_rects
|
||||
#define pixman_region_reset _moz_cairo_pixman_region_reset
|
||||
#define pixman_region_subtract _moz_cairo_pixman_region_subtract
|
||||
#define pixman_region_translate _moz_cairo_pixman_region_translate
|
||||
#define pixman_region_union _moz_cairo_pixman_region_union
|
||||
#define pixman_region_union_rect _moz_cairo_pixman_region_union_rect
|
||||
#define pixman_region_validate _moz_cairo_pixman_region_validate
|
||||
#define RenderEdgeInit _moz_cairo_pixman_render_edge_init
|
||||
#define RenderEdgeStep _moz_cairo_pixman_render_edge_step
|
||||
#define RenderLineFixedEdgeInit _moz_cairo_pixman_render_line_fixed_edge_init
|
||||
#define RenderSampleCeilY _moz_cairo_pixman_render_sample_ceil_y
|
||||
#define RenderSampleFloorY _moz_cairo_pixman_render_sample_floor_y
|
||||
#define fbSolidFillmmx _moz_cairo_pixman_solid_fill_mmx
|
||||
#define pixman_image_create _cairo_pixman_image_create
|
||||
#define pixman_image_create_for_data _cairo_pixman_image_create_for_data
|
||||
#define pixman_image_destroy _cairo_pixman_image_destroy
|
||||
#define pixman_image_get_data _cairo_pixman_image_get_data
|
||||
#define pixman_image_get_depth _cairo_pixman_image_get_depth
|
||||
#define pixman_image_get_format _cairo_pixman_image_get_format
|
||||
#define pixman_image_get_height _cairo_pixman_image_get_height
|
||||
#define pixman_image_get_stride _cairo_pixman_image_get_stride
|
||||
#define pixman_image_get_width _cairo_pixman_image_get_width
|
||||
#define pixman_image_set_clip_region _cairo_pixman_image_set_clip_region
|
||||
#define pixman_image_set_component_alpha _cairo_pixman_image_set_component_alpha
|
||||
#define pixman_image_set_filter _cairo_pixman_image_set_filter
|
||||
#define pixman_image_set_repeat _cairo_pixman_image_set_repeat
|
||||
#define pixman_image_set_transform _cairo_pixman_image_set_transform
|
||||
#define pixman_image_create_linear_gradient _cairo_pixman_image_create_linear_gradient
|
||||
#define pixman_image_create_radial_gradient _cairo_pixman_image_create_radial_gradient
|
||||
#define miIsSolidAlpha _cairo_pixman_is_solid_alpha
|
||||
#define pixman_pixel_to_color _cairo_pixman_pixel_to_color
|
||||
#define pixman_region_append _cairo_pixman_region_append
|
||||
#define pixman_region_contains_point _cairo_pixman_region_contains_point
|
||||
#define pixman_region_contains_rectangle _cairo_pixman_region_contains_rectangle
|
||||
#define pixman_region_copy _cairo_pixman_region_copy
|
||||
#define pixman_region_create _cairo_pixman_region_create
|
||||
#define pixman_region_create_simple _cairo_pixman_region_create_simple
|
||||
#define pixman_region_destroy _cairo_pixman_region_destroy
|
||||
#define pixman_region_empty _cairo_pixman_region_empty
|
||||
#define pixman_region_extents _cairo_pixman_region_extents
|
||||
#define pixman_region_intersect _cairo_pixman_region_intersect
|
||||
#define pixman_region_inverse _cairo_pixman_region_inverse
|
||||
#define pixman_region_not_empty _cairo_pixman_region_not_empty
|
||||
#define pixman_region_num_rects _cairo_pixman_region_num_rects
|
||||
#define pixman_region_rects _cairo_pixman_region_rects
|
||||
#define pixman_region_reset _cairo_pixman_region_reset
|
||||
#define pixman_region_subtract _cairo_pixman_region_subtract
|
||||
#define pixman_region_translate _cairo_pixman_region_translate
|
||||
#define pixman_region_union _cairo_pixman_region_union
|
||||
#define pixman_region_union_rect _cairo_pixman_region_union_rect
|
||||
#define pixman_region_validate _cairo_pixman_region_validate
|
||||
#define RenderEdgeInit _cairo_pixman_render_edge_init
|
||||
#define RenderEdgeStep _cairo_pixman_render_edge_step
|
||||
#define RenderLineFixedEdgeInit _cairo_pixman_render_line_fixed_edge_init
|
||||
#define RenderSampleCeilY _cairo_pixman_render_sample_ceil_y
|
||||
#define RenderSampleFloorY _cairo_pixman_render_sample_floor_y
|
||||
#define fbSolidFillmmx _cairo_pixman_solid_fill_mmx
|
||||
|
|
|
@ -99,6 +99,14 @@ SOFTWARE.
|
|||
|
||||
#include "pixman-remap.h"
|
||||
|
||||
#if (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 3)) && defined(__ELF__)
|
||||
#define pixman_private __attribute__((__visibility__("hidden")))
|
||||
#elif defined(__SUNPRO_C) && (__SUNPRO_C >= 0x550)
|
||||
#define pixman_private __hidden
|
||||
#else /* not gcc >= 3.3 and not Sun Studio >= 8 */
|
||||
#define pixman_private
|
||||
#endif
|
||||
|
||||
#if defined(__cplusplus) || defined(c_plusplus)
|
||||
extern "C" {
|
||||
#endif
|
||||
|
@ -118,37 +126,37 @@ typedef enum {
|
|||
|
||||
/* creation/destruction */
|
||||
|
||||
pixman_region16_t *
|
||||
pixman_private pixman_region16_t *
|
||||
pixman_region_create (void);
|
||||
|
||||
pixman_region16_t *
|
||||
pixman_private pixman_region16_t *
|
||||
pixman_region_create_simple (pixman_box16_t *extents);
|
||||
|
||||
void
|
||||
pixman_private void
|
||||
pixman_region_destroy (pixman_region16_t *region);
|
||||
|
||||
/* manipulation */
|
||||
|
||||
void
|
||||
pixman_private void
|
||||
pixman_region_translate (pixman_region16_t *region, int x, int y);
|
||||
|
||||
pixman_region_status_t
|
||||
pixman_private pixman_region_status_t
|
||||
pixman_region_copy (pixman_region16_t *dest, pixman_region16_t *source);
|
||||
|
||||
pixman_region_status_t
|
||||
pixman_private pixman_region_status_t
|
||||
pixman_region_intersect (pixman_region16_t *newReg, pixman_region16_t *reg1, pixman_region16_t *reg2);
|
||||
|
||||
pixman_region_status_t
|
||||
pixman_private pixman_region_status_t
|
||||
pixman_region_union (pixman_region16_t *newReg, pixman_region16_t *reg1, pixman_region16_t *reg2);
|
||||
|
||||
pixman_region_status_t
|
||||
pixman_private pixman_region_status_t
|
||||
pixman_region_union_rect(pixman_region16_t *dest, pixman_region16_t *source,
|
||||
int x, int y, unsigned int width, unsigned int height);
|
||||
|
||||
pixman_region_status_t
|
||||
pixman_private pixman_region_status_t
|
||||
pixman_region_subtract (pixman_region16_t *regD, pixman_region16_t *regM, pixman_region16_t *regS);
|
||||
|
||||
pixman_region_status_t
|
||||
pixman_private pixman_region_status_t
|
||||
pixman_region_inverse (pixman_region16_t *newReg, pixman_region16_t *reg1, pixman_box16_t *invRect);
|
||||
|
||||
/* XXX: Need to fix this so it doesn't depend on an X data structure
|
||||
|
@ -159,10 +167,10 @@ RectsTopixman_region16_t (int nrects, xRectanglePtr prect, int ctype);
|
|||
/* querying */
|
||||
|
||||
/* XXX: These should proably be combined: pixman_region_get_rects? */
|
||||
int
|
||||
pixman_private int
|
||||
pixman_region_num_rects (pixman_region16_t *region);
|
||||
|
||||
pixman_box16_t *
|
||||
pixman_private pixman_box16_t *
|
||||
pixman_region_rects (pixman_region16_t *region);
|
||||
|
||||
/* XXX: Change to an enum */
|
||||
|
@ -170,36 +178,36 @@ pixman_region_rects (pixman_region16_t *region);
|
|||
#define rgnIN 1
|
||||
#define rgnPART 2
|
||||
|
||||
int
|
||||
pixman_private int
|
||||
pixman_region_contains_point (pixman_region16_t *region, int x, int y, pixman_box16_t *box);
|
||||
|
||||
int
|
||||
pixman_private int
|
||||
pixman_region_contains_rectangle (pixman_region16_t *pixman_region16_t, pixman_box16_t *prect);
|
||||
|
||||
int
|
||||
pixman_private int
|
||||
pixman_region_not_empty (pixman_region16_t *region);
|
||||
|
||||
pixman_box16_t *
|
||||
pixman_private pixman_box16_t *
|
||||
pixman_region_extents (pixman_region16_t *region);
|
||||
|
||||
/* mucking around */
|
||||
|
||||
/* WARNING: calling pixman_region_append may leave dest as an invalid
|
||||
region. Follow-up with pixman_region_validate to fix it up. */
|
||||
pixman_region_status_t
|
||||
pixman_private pixman_region_status_t
|
||||
pixman_region_append (pixman_region16_t *dest, pixman_region16_t *region);
|
||||
|
||||
pixman_region_status_t
|
||||
pixman_private pixman_region_status_t
|
||||
pixman_region_validate (pixman_region16_t *badreg, int *pOverlap);
|
||||
|
||||
/* Unclassified functionality
|
||||
* XXX: Do all of these need to be exported?
|
||||
*/
|
||||
|
||||
void
|
||||
pixman_private void
|
||||
pixman_region_reset (pixman_region16_t *region, pixman_box16_t *pBox);
|
||||
|
||||
void
|
||||
pixman_private void
|
||||
pixman_region_empty (pixman_region16_t *region);
|
||||
|
||||
/* ic.h */
|
||||
|
@ -227,37 +235,39 @@ typedef enum pixman_format_name {
|
|||
PIXMAN_FORMAT_NAME_RGB24,
|
||||
PIXMAN_FORMAT_NAME_A8,
|
||||
PIXMAN_FORMAT_NAME_A1,
|
||||
PIXMAN_FORMAT_NAME_RGB16_565
|
||||
PIXMAN_FORMAT_NAME_RGB16_565,
|
||||
PIXMAN_FORMAT_NAME_ABGR32,
|
||||
PIXMAN_FORMAT_NAME_BGR24
|
||||
} pixman_format_name_t;
|
||||
|
||||
typedef struct pixman_format pixman_format_t;
|
||||
|
||||
pixman_format_t *
|
||||
pixman_private pixman_format_t *
|
||||
pixman_format_create (pixman_format_name_t name);
|
||||
|
||||
pixman_format_t *
|
||||
pixman_private pixman_format_t *
|
||||
pixman_format_create_masks (int bpp,
|
||||
int alpha_mask,
|
||||
int red_mask,
|
||||
int green_mask,
|
||||
int blue_mask);
|
||||
|
||||
void
|
||||
pixman_private void
|
||||
pixman_format_destroy (pixman_format_t *format);
|
||||
|
||||
void
|
||||
pixman_private void
|
||||
pixman_format_get_masks (pixman_format_t *format,
|
||||
int *bpp,
|
||||
int *alpha_mask,
|
||||
int *red_mask,
|
||||
int *green_mask,
|
||||
int *blue_mask);
|
||||
unsigned int *bpp,
|
||||
unsigned int *alpha_mask,
|
||||
unsigned int *red_mask,
|
||||
unsigned int *green_mask,
|
||||
unsigned int *blue_mask);
|
||||
|
||||
/* icimage.c */
|
||||
|
||||
typedef struct pixman_image pixman_image_t;
|
||||
|
||||
pixman_image_t *
|
||||
pixman_private pixman_image_t *
|
||||
pixman_image_create (pixman_format_t *format,
|
||||
int width,
|
||||
int height);
|
||||
|
@ -282,16 +292,16 @@ pixman_image_create (pixman_format_t *format,
|
|||
typedef uint32_t pixman_bits_t;
|
||||
#endif
|
||||
|
||||
pixman_image_t *
|
||||
pixman_private pixman_image_t *
|
||||
pixman_image_create_for_data (pixman_bits_t *data,
|
||||
pixman_format_t *format,
|
||||
int width, int height,
|
||||
int bpp, int stride);
|
||||
|
||||
void
|
||||
pixman_private void
|
||||
pixman_image_destroy (pixman_image_t *image);
|
||||
|
||||
int
|
||||
pixman_private int
|
||||
pixman_image_set_clip_region (pixman_image_t *image,
|
||||
pixman_region16_t *region);
|
||||
|
||||
|
@ -366,11 +376,11 @@ typedef enum {
|
|||
PIXMAN_FILTER_BILINEAR
|
||||
} pixman_filter_t;
|
||||
|
||||
void
|
||||
pixman_private void
|
||||
pixman_image_set_component_alpha (pixman_image_t *image,
|
||||
int component_alpha);
|
||||
|
||||
int
|
||||
pixman_private int
|
||||
pixman_image_set_transform (pixman_image_t *image,
|
||||
pixman_transform_t *transform);
|
||||
|
||||
|
@ -382,57 +392,57 @@ typedef enum {
|
|||
PIXMAN_REPEAT_REFLECT
|
||||
} pixman_repeat_t;
|
||||
|
||||
void
|
||||
pixman_private void
|
||||
pixman_image_set_repeat (pixman_image_t *image,
|
||||
pixman_repeat_t repeat);
|
||||
|
||||
void
|
||||
pixman_private void
|
||||
pixman_image_set_filter (pixman_image_t *image,
|
||||
pixman_filter_t filter);
|
||||
|
||||
int
|
||||
pixman_private int
|
||||
pixman_image_get_width (pixman_image_t *image);
|
||||
|
||||
int
|
||||
pixman_private int
|
||||
pixman_image_get_height (pixman_image_t *image);
|
||||
|
||||
int
|
||||
pixman_private int
|
||||
pixman_image_get_stride (pixman_image_t *image);
|
||||
|
||||
int
|
||||
pixman_private int
|
||||
pixman_image_get_depth (pixman_image_t *image);
|
||||
|
||||
pixman_format_t *
|
||||
pixman_private pixman_format_t *
|
||||
pixman_image_get_format (pixman_image_t *image);
|
||||
|
||||
pixman_bits_t *
|
||||
pixman_private pixman_bits_t *
|
||||
pixman_image_get_data (pixman_image_t *image);
|
||||
|
||||
pixman_image_t *
|
||||
pixman_private pixman_image_t *
|
||||
pixman_image_create_linear_gradient (const pixman_linear_gradient_t *gradient,
|
||||
const pixman_gradient_stop_t *stops,
|
||||
int n_stops);
|
||||
|
||||
pixman_image_t *
|
||||
pixman_private pixman_image_t *
|
||||
pixman_image_create_radial_gradient (const pixman_radial_gradient_t *gradient,
|
||||
const pixman_gradient_stop_t *stops,
|
||||
int n_stops);
|
||||
|
||||
/* iccolor.c */
|
||||
|
||||
void
|
||||
pixman_private void
|
||||
pixman_color_to_pixel (const pixman_format_t *format,
|
||||
const pixman_color_t *color,
|
||||
pixman_bits_t *pixel);
|
||||
|
||||
void
|
||||
pixman_private void
|
||||
pixman_pixel_to_color (const pixman_format_t *format,
|
||||
pixman_bits_t pixel,
|
||||
pixman_color_t *color);
|
||||
|
||||
/* icrect.c */
|
||||
|
||||
void
|
||||
pixman_private void
|
||||
pixman_fill_rectangle (pixman_operator_t op,
|
||||
pixman_image_t *dst,
|
||||
const pixman_color_t *color,
|
||||
|
@ -441,7 +451,7 @@ pixman_fill_rectangle (pixman_operator_t op,
|
|||
unsigned int width,
|
||||
unsigned int height);
|
||||
|
||||
void
|
||||
pixman_private void
|
||||
pixman_fill_rectangles (pixman_operator_t op,
|
||||
pixman_image_t *dst,
|
||||
const pixman_color_t *color,
|
||||
|
@ -450,7 +460,7 @@ pixman_fill_rectangles (pixman_operator_t op,
|
|||
|
||||
/* ictrap.c */
|
||||
|
||||
void
|
||||
pixman_private void
|
||||
pixman_composite_trapezoids (pixman_operator_t op,
|
||||
pixman_image_t *src,
|
||||
pixman_image_t *dst,
|
||||
|
@ -459,7 +469,7 @@ pixman_composite_trapezoids (pixman_operator_t op,
|
|||
const pixman_trapezoid_t *traps,
|
||||
int ntrap);
|
||||
|
||||
void
|
||||
pixman_private void
|
||||
pixman_add_trapezoids (pixman_image_t *dst,
|
||||
int x_off,
|
||||
int y_off,
|
||||
|
@ -468,7 +478,7 @@ pixman_add_trapezoids (pixman_image_t *dst,
|
|||
|
||||
/* ictri.c */
|
||||
|
||||
void
|
||||
pixman_private void
|
||||
pixman_composite_triangles (pixman_operator_t op,
|
||||
pixman_image_t *src,
|
||||
pixman_image_t *dst,
|
||||
|
@ -477,7 +487,7 @@ pixman_composite_triangles (pixman_operator_t op,
|
|||
const pixman_triangle_t *tris,
|
||||
int ntris);
|
||||
|
||||
void
|
||||
pixman_private void
|
||||
pixman_composite_tri_strip (pixman_operator_t op,
|
||||
pixman_image_t *src,
|
||||
pixman_image_t *dst,
|
||||
|
@ -486,7 +496,7 @@ pixman_composite_tri_strip (pixman_operator_t op,
|
|||
const pixman_point_fixed_t *points,
|
||||
int npoints);
|
||||
|
||||
void
|
||||
pixman_private void
|
||||
pixman_composite_tri_fan (pixman_operator_t op,
|
||||
pixman_image_t *src,
|
||||
pixman_image_t *dst,
|
||||
|
@ -497,7 +507,7 @@ pixman_composite_tri_fan (pixman_operator_t op,
|
|||
|
||||
/* ic.c */
|
||||
|
||||
void
|
||||
pixman_private void
|
||||
pixman_composite (pixman_operator_t op,
|
||||
pixman_image_t *iSrc,
|
||||
pixman_image_t *iMask,
|
||||
|
|
|
@ -50,7 +50,6 @@ SOFTWARE.
|
|||
#include <string.h>
|
||||
|
||||
#include "pixregionint.h"
|
||||
#include "slim_internal.h"
|
||||
|
||||
#if defined (__GNUC__) && !defined (NO_INLINES)
|
||||
#define INLINE __inline
|
||||
|
@ -89,10 +88,6 @@ pixman_init (pixman_region16_t *region, pixman_box16_t *rect);
|
|||
static void
|
||||
pixman_uninit (pixman_region16_t *region);
|
||||
|
||||
slim_hidden_proto(pixman_region_create_simple)
|
||||
slim_hidden_proto(pixman_region_copy)
|
||||
slim_hidden_proto(pixman_region_union)
|
||||
|
||||
/*
|
||||
* The functions in this file implement the Region abstraction used extensively
|
||||
* throughout the X11 sample server. A Region is simply a set of disjoint
|
||||
|
@ -327,7 +322,6 @@ pixman_region_create_simple (pixman_box16_t *extents)
|
|||
|
||||
return region;
|
||||
}
|
||||
slim_hidden_def(pixman_region_create_simple);
|
||||
|
||||
/*****************************************************************
|
||||
* RegionInit(pReg, rect, size)
|
||||
|
@ -452,7 +446,6 @@ pixman_region_copy(pixman_region16_t *dst, pixman_region16_t *src)
|
|||
dst->data->numRects * sizeof(pixman_box16_t));
|
||||
return PIXMAN_REGION_STATUS_SUCCESS;
|
||||
}
|
||||
slim_hidden_def(pixman_region_copy);
|
||||
|
||||
/*======================================================================
|
||||
* Generic Region Operator
|
||||
|
@ -988,10 +981,9 @@ pixman_region_intersectO (
|
|||
}
|
||||
|
||||
pixman_region_status_t
|
||||
pixman_region_intersect(newReg, reg1, reg2)
|
||||
pixman_region16_t * newReg; /* destination Region */
|
||||
pixman_region16_t * reg1;
|
||||
pixman_region16_t * reg2; /* source regions */
|
||||
pixman_region_intersect(pixman_region16_t * newReg,
|
||||
pixman_region16_t * reg1,
|
||||
pixman_region16_t * reg2)
|
||||
{
|
||||
good(reg1);
|
||||
good(reg2);
|
||||
|
@ -1233,7 +1225,6 @@ pixman_region_union(pixman_region16_t *newReg, pixman_region16_t *reg1, pixman_r
|
|||
good(newReg);
|
||||
return PIXMAN_REGION_STATUS_SUCCESS;
|
||||
}
|
||||
slim_hidden_def(pixman_region_union);
|
||||
|
||||
/*======================================================================
|
||||
* Batch Rectangle Union
|
||||
|
@ -1257,9 +1248,8 @@ slim_hidden_def(pixman_region_union);
|
|||
*
|
||||
*/
|
||||
pixman_region_status_t
|
||||
pixman_region_append(dstrgn, rgn)
|
||||
pixman_region16_t * dstrgn;
|
||||
pixman_region16_t * rgn;
|
||||
pixman_region_append(pixman_region16_t * dstrgn,
|
||||
pixman_region16_t * rgn)
|
||||
{
|
||||
int numRects, dnumRects, size;
|
||||
pixman_box16_t *new, *old;
|
||||
|
@ -1442,9 +1432,8 @@ QuickSortRects(
|
|||
*/
|
||||
|
||||
pixman_region_status_t
|
||||
pixman_region_validate(badreg, pOverlap)
|
||||
pixman_region16_t * badreg;
|
||||
int *pOverlap;
|
||||
pixman_region_validate(pixman_region16_t * badreg,
|
||||
int *pOverlap)
|
||||
{
|
||||
/* Descriptor for regions under construction in Step 2. */
|
||||
typedef struct {
|
||||
|
@ -1858,10 +1847,9 @@ pixman_region_subtractO (
|
|||
*-----------------------------------------------------------------------
|
||||
*/
|
||||
pixman_region_status_t
|
||||
pixman_region_subtract(regD, regM, regS)
|
||||
pixman_region16_t * regD;
|
||||
pixman_region16_t * regM;
|
||||
pixman_region16_t * regS;
|
||||
pixman_region_subtract(pixman_region16_t * regD,
|
||||
pixman_region16_t * regM,
|
||||
pixman_region16_t * regS)
|
||||
{
|
||||
int overlap; /* result ignored */
|
||||
|
||||
|
@ -1923,10 +1911,9 @@ pixman_region_subtract(regD, regM, regS)
|
|||
*-----------------------------------------------------------------------
|
||||
*/
|
||||
pixman_region_status_t
|
||||
pixman_region_inverse(newReg, reg1, invRect)
|
||||
pixman_region16_t * newReg; /* Destination region */
|
||||
pixman_region16_t * reg1; /* Region to invert */
|
||||
pixman_box16_t * invRect; /* Bounding box for inversion */
|
||||
pixman_region_inverse(pixman_region16_t * newReg, /* Destination region */
|
||||
pixman_region16_t * reg1, /* Region to invert */
|
||||
pixman_box16_t * invRect) /* Bounding box for inversion */
|
||||
{
|
||||
pixman_region16_t invReg; /* Quick and dirty region made from the
|
||||
* bounding box */
|
||||
|
@ -1983,9 +1970,8 @@ pixman_region_inverse(newReg, reg1, invRect)
|
|||
*/
|
||||
|
||||
int
|
||||
pixman_region_contains_rectangle(region, prect)
|
||||
pixman_region16_t * region;
|
||||
pixman_box16_t * prect;
|
||||
pixman_region_contains_rectangle(pixman_region16_t * region,
|
||||
pixman_box16_t * prect)
|
||||
{
|
||||
int x;
|
||||
int y;
|
||||
|
@ -2200,11 +2186,11 @@ pixman_region_reset(pixman_region16_t *region, pixman_box16_t *box)
|
|||
region->data = (pixman_region16_data_t *)NULL;
|
||||
}
|
||||
|
||||
/* box is "return" value */
|
||||
int
|
||||
pixman_region_contains_point(region, x, y, box)
|
||||
pixman_region16_t * region;
|
||||
int x, y;
|
||||
pixman_box16_t * box; /* "return" value */
|
||||
pixman_region_contains_point(pixman_region16_t * region,
|
||||
int x, int y,
|
||||
pixman_box16_t * box)
|
||||
{
|
||||
pixman_box16_t *pbox, *pboxEnd;
|
||||
int numRects;
|
||||
|
@ -2235,8 +2221,7 @@ pixman_region_contains_point(region, x, y, box)
|
|||
}
|
||||
|
||||
int
|
||||
pixman_region_not_empty(region)
|
||||
pixman_region16_t * region;
|
||||
pixman_region_not_empty(pixman_region16_t * region)
|
||||
{
|
||||
good(region);
|
||||
return(!PIXREGION_NIL(region));
|
||||
|
@ -2252,8 +2237,7 @@ pixman_region16_broken(pixman_region16_t * region)
|
|||
*/
|
||||
|
||||
void
|
||||
pixman_region_empty(region)
|
||||
pixman_region16_t * region;
|
||||
pixman_region_empty(pixman_region16_t * region)
|
||||
{
|
||||
good(region);
|
||||
freeData(region);
|
||||
|
@ -2263,8 +2247,7 @@ pixman_region_empty(region)
|
|||
}
|
||||
|
||||
pixman_box16_t *
|
||||
pixman_region_extents(region)
|
||||
pixman_region16_t * region;
|
||||
pixman_region_extents(pixman_region16_t * region)
|
||||
{
|
||||
good(region);
|
||||
return(®ion->extents);
|
||||
|
|
|
@ -128,16 +128,16 @@ typedef struct {
|
|||
} \
|
||||
}
|
||||
|
||||
xFixed
|
||||
pixman_private xFixed
|
||||
RenderSampleCeilY (xFixed y, int bpp);
|
||||
|
||||
xFixed
|
||||
pixman_private xFixed
|
||||
RenderSampleFloorY (xFixed y, int bpp);
|
||||
|
||||
void
|
||||
pixman_private void
|
||||
RenderEdgeStep (RenderEdge *e, int n);
|
||||
|
||||
void
|
||||
pixman_private void
|
||||
RenderEdgeInit (RenderEdge *e,
|
||||
int bpp,
|
||||
xFixed y_start,
|
||||
|
@ -146,7 +146,7 @@ RenderEdgeInit (RenderEdge *e,
|
|||
xFixed x_bot,
|
||||
xFixed y_bot);
|
||||
|
||||
void
|
||||
pixman_private void
|
||||
RenderLineFixedEdgeInit (RenderEdge *e,
|
||||
int bpp,
|
||||
xFixed y,
|
||||
|
|
|
@ -78,8 +78,9 @@
|
|||
level. */
|
||||
|
||||
#if __GNUC__ >= 3 && defined(__ELF__)
|
||||
# define slim_hidden_proto(name) slim_hidden_proto1(name, INT_##name)
|
||||
# define slim_hidden_def(name) slim_hidden_def1(name, INT_##name)
|
||||
# define slim_hidden_proto(name) slim_hidden_proto1(name, slim_hidden_int_name(name))
|
||||
# define slim_hidden_def(name) slim_hidden_def1(name, slim_hidden_int_name(name))
|
||||
# define slim_hidden_int_name(name) INT_##name
|
||||
# define slim_hidden_proto1(name, internal) \
|
||||
extern __typeof (name) name \
|
||||
__asm__ (slim_hidden_asmname (internal)) \
|
||||
|
|
|
@ -1,734 +0,0 @@
|
|||
Index: src/cairo-gstate-private.h
|
||||
===================================================================
|
||||
--- src/cairo-gstate-private.h.orig 2006-02-09 17:51:53.843750000 -0800
|
||||
+++ src/cairo-gstate-private.h 2006-02-09 18:03:23.546875000 -0800
|
||||
@@ -55,7 +55,9 @@
|
||||
|
||||
cairo_clip_t clip;
|
||||
|
||||
- cairo_surface_t *target;
|
||||
+ cairo_surface_t *target; /* The target to which all rendering is directed */
|
||||
+ cairo_surface_t *parent_target; /* The previous target which was receiving rendering */
|
||||
+ cairo_surface_t *original_target; /* The original target the initial gstate was created with */
|
||||
|
||||
cairo_matrix_t ctm;
|
||||
cairo_matrix_t ctm_inverse;
|
||||
Index: src/cairo-gstate.c
|
||||
===================================================================
|
||||
--- src/cairo-gstate.c.orig 2006-02-09 18:01:01.859375000 -0800
|
||||
+++ src/cairo-gstate.c 2006-02-09 18:03:23.562500000 -0800
|
||||
@@ -119,6 +119,8 @@
|
||||
_cairo_clip_init (&gstate->clip, target);
|
||||
|
||||
gstate->target = cairo_surface_reference (target);
|
||||
+ gstate->parent_target = NULL;
|
||||
+ gstate->original_target = cairo_surface_reference (target);
|
||||
|
||||
_cairo_gstate_identity_matrix (gstate);
|
||||
gstate->source_ctm_inverse = gstate->ctm_inverse;
|
||||
@@ -166,6 +168,9 @@
|
||||
_cairo_clip_init_copy (&gstate->clip, &other->clip);
|
||||
|
||||
gstate->target = cairo_surface_reference (other->target);
|
||||
+ /* parent_target is always set to NULL; it's only ever set by redirect_target */
|
||||
+ gstate->parent_target = NULL;
|
||||
+ gstate->original_target = cairo_surface_reference (other->original_target);
|
||||
|
||||
gstate->ctm = other->ctm;
|
||||
gstate->ctm_inverse = other->ctm_inverse;
|
||||
@@ -194,6 +199,12 @@
|
||||
cairo_surface_destroy (gstate->target);
|
||||
gstate->target = NULL;
|
||||
|
||||
+ cairo_surface_destroy (gstate->parent_target);
|
||||
+ gstate->parent_target = NULL;
|
||||
+
|
||||
+ cairo_surface_destroy (gstate->original_target);
|
||||
+ gstate->target = NULL;
|
||||
+
|
||||
cairo_pattern_destroy (gstate->source);
|
||||
gstate->source = NULL;
|
||||
}
|
||||
@@ -248,94 +259,153 @@
|
||||
gstate->target = cairo_surface_reference (target);
|
||||
}
|
||||
|
||||
-/* Push rendering off to an off-screen group. */
|
||||
-/* XXX: Rethinking this API
|
||||
-cairo_status_t
|
||||
-_cairo_gstate_begin_group (cairo_gstate_t *gstate)
|
||||
+static cairo_status_t
|
||||
+_cairo_gstate_recursive_apply_clip_path (cairo_gstate_t *gstate,
|
||||
+ cairo_clip_path_t *cpath)
|
||||
{
|
||||
- Pixmap pix;
|
||||
- unsigned int width, height;
|
||||
-
|
||||
- gstate->parent_surface = gstate->target;
|
||||
-
|
||||
- width = _cairo_surface_get_width (gstate->target);
|
||||
- height = _cairo_surface_get_height (gstate->target);
|
||||
+ cairo_status_t status;
|
||||
|
||||
- pix = XCreatePixmap (gstate->dpy,
|
||||
- _cairo_surface_get_drawable (gstate->target),
|
||||
- width, height,
|
||||
- _cairo_surface_get_depth (gstate->target));
|
||||
- if (pix == 0)
|
||||
- return CAIRO_STATUS_NO_MEMORY;
|
||||
+ if (cpath == NULL)
|
||||
+ return CAIRO_STATUS_SUCCESS;
|
||||
|
||||
- gstate->target = cairo_surface_create (gstate->dpy);
|
||||
- if (gstate->target->status)
|
||||
- return gstate->target->status;
|
||||
-
|
||||
- _cairo_surface_set_drawableWH (gstate->target, pix, width, height);
|
||||
-
|
||||
- status = _cairo_surface_fill_rectangle (gstate->target,
|
||||
- CAIRO_OPERATOR_CLEAR,
|
||||
- CAIRO_COLOR_TRANSPARENT,
|
||||
- 0, 0,
|
||||
- _cairo_surface_get_width (gstate->target),
|
||||
- _cairo_surface_get_height (gstate->target));
|
||||
- if (status)
|
||||
- return status;
|
||||
+ status = _cairo_gstate_recursive_apply_clip_path (gstate, cpath->prev);
|
||||
+ if (status)
|
||||
+ return status;
|
||||
|
||||
- return CAIRO_STATUS_SUCCESS;
|
||||
+ return _cairo_clip_clip (&gstate->clip,
|
||||
+ &cpath->path,
|
||||
+ cpath->fill_rule,
|
||||
+ cpath->tolerance,
|
||||
+ cpath->antialias,
|
||||
+ gstate->target);
|
||||
}
|
||||
-*/
|
||||
|
||||
-/* Complete the current offscreen group, composing its contents onto the parent surface. */
|
||||
-/* XXX: Rethinking this API
|
||||
-cairo_status_t
|
||||
-_cairo_gstate_end_group (cairo_gstate_t *gstate)
|
||||
+/**
|
||||
+ * _cairo_gstate_redirect_target:
|
||||
+ * @gstate: a #cairo_gstate_t
|
||||
+ * @child: the new child target
|
||||
+ *
|
||||
+ * Redirect @gstate rendering to a "child" target. The original
|
||||
+ * "parent" target with which the gstate was created will not be
|
||||
+ * affected. See _cairo_gstate_get_target().
|
||||
+ *
|
||||
+ * Unless the redirected target has the same device offsets as the
|
||||
+ * original #cairo_t target, the clip will be INVALID after this call,
|
||||
+ * and the caller should either recreate or reset the clip.
|
||||
+ **/
|
||||
+void
|
||||
+_cairo_gstate_redirect_target (cairo_gstate_t *gstate, cairo_surface_t *child)
|
||||
{
|
||||
- Pixmap pix;
|
||||
- cairo_color_t mask_color;
|
||||
- cairo_surface_t mask;
|
||||
-
|
||||
- if (gstate->parent_surface == NULL)
|
||||
- return CAIRO_STATUS_INVALID_POP_GROUP;
|
||||
-
|
||||
- _cairo_surface_init (&mask, gstate->dpy);
|
||||
- _cairo_color_init (&mask_color);
|
||||
-
|
||||
- _cairo_surface_set_solid_color (&mask, &mask_color);
|
||||
-
|
||||
- * XXX: This could be made much more efficient by using
|
||||
- _cairo_surface_get_damaged_width/Height if cairo_surface_t actually kept
|
||||
- track of such informaton. *
|
||||
- _cairo_surface_composite (gstate->op,
|
||||
- gstate->target,
|
||||
- mask,
|
||||
- gstate->parent_surface,
|
||||
- 0, 0,
|
||||
- 0, 0,
|
||||
- 0, 0,
|
||||
- _cairo_surface_get_width (gstate->target),
|
||||
- _cairo_surface_get_height (gstate->target));
|
||||
-
|
||||
- _cairo_surface_fini (&mask);
|
||||
-
|
||||
- pix = _cairo_surface_get_drawable (gstate->target);
|
||||
- XFreePixmap (gstate->dpy, pix);
|
||||
-
|
||||
- cairo_surface_destroy (gstate->target);
|
||||
- gstate->target = gstate->parent_surface;
|
||||
- gstate->parent_surface = NULL;
|
||||
+ /* If this gstate is already redirected, this is an error; we need a
|
||||
+ * new gstate to be able to redirect */
|
||||
+ assert (gstate->parent_target == NULL);
|
||||
+
|
||||
+ /* Set up our new parent_target based on our current target;
|
||||
+ * gstate->parent_target will take the ref that is held by gstate->target
|
||||
+ */
|
||||
+ cairo_surface_destroy (gstate->parent_target);
|
||||
+ gstate->parent_target = gstate->target;
|
||||
+
|
||||
+ /* Now set up our new target; we overwrite gstate->target directly,
|
||||
+ * since its ref is now owned by gstate->parent_target */
|
||||
+ gstate->target = cairo_surface_reference (child);
|
||||
+
|
||||
+ /* Check that the new surface's clip mode is compatible */
|
||||
+ if (gstate->clip.mode != _cairo_surface_get_clip_mode (child)) {
|
||||
+ /* clip is not compatible; try to recreate it */
|
||||
+ /* XXX - saving the clip path always might be useful here,
|
||||
+ * so that we could recover non-CLIP_MODE_PATH clips */
|
||||
+ if (gstate->clip.mode == CAIRO_CLIP_MODE_PATH) {
|
||||
+ cairo_clip_t saved_clip = gstate->clip;
|
||||
+
|
||||
+ _cairo_clip_init (&gstate->clip, child);
|
||||
+
|
||||
+ /* unwind the path and re-apply */
|
||||
+ _cairo_gstate_recursive_apply_clip_path (gstate, saved_clip.path);
|
||||
+
|
||||
+ _cairo_clip_fini (&saved_clip);
|
||||
+ } else {
|
||||
+ /* uh, not sure what to do here.. */
|
||||
+ _cairo_clip_fini (&gstate->clip);
|
||||
+ _cairo_clip_init (&gstate->clip, child);
|
||||
+ }
|
||||
+ } else {
|
||||
+ /* clip is compatible; allocate a new serial for the new surface. */
|
||||
+ if (gstate->clip.serial)
|
||||
+ gstate->clip.serial = _cairo_surface_allocate_clip_serial (child);
|
||||
+ }
|
||||
+}
|
||||
|
||||
- return CAIRO_STATUS_SUCCESS;
|
||||
+/**
|
||||
+ * _cairo_gstate_is_redirected
|
||||
+ * @gstate: a #cairo_gstate_t
|
||||
+ *
|
||||
+ * Return value: TRUE if the gstate is redirected to a traget
|
||||
+ * different than the original, FALSE otherwise.
|
||||
+ **/
|
||||
+cairo_bool_t
|
||||
+_cairo_gstate_is_redirected (cairo_gstate_t *gstate)
|
||||
+{
|
||||
+ return (gstate->target != gstate->original_target);
|
||||
}
|
||||
-*/
|
||||
|
||||
+/**
|
||||
+ * _cairo_gstate_get_target:
|
||||
+ * @gstate: a #cairo_gstate_t
|
||||
+ *
|
||||
+ * Return the current drawing target; if drawing is not redirected,
|
||||
+ * this will be the same as _cairo_gstate_get_original_target().
|
||||
+ *
|
||||
+ * Return value: the current target surface
|
||||
+ **/
|
||||
cairo_surface_t *
|
||||
_cairo_gstate_get_target (cairo_gstate_t *gstate)
|
||||
{
|
||||
return gstate->target;
|
||||
}
|
||||
|
||||
+/**
|
||||
+ * _cairo_gstate_get_parent_target:
|
||||
+ * @gstate: a #cairo_gstate_t
|
||||
+ *
|
||||
+ * Return the parent surface of the current drawing target surface;
|
||||
+ * if this particular gstate isn't a redirect gstate, this will return NULL.
|
||||
+ **/
|
||||
+cairo_surface_t *
|
||||
+_cairo_gstate_get_parent_target (cairo_gstate_t *gstate)
|
||||
+{
|
||||
+ return gstate->parent_target;
|
||||
+}
|
||||
+
|
||||
+/**
|
||||
+ * _cairo_gstate_get_original_target:
|
||||
+ * @gstate: a #cairo_gstate_t
|
||||
+ *
|
||||
+ * Return the original target with which @gstate was created. This
|
||||
+ * function always returns the original target independent of any
|
||||
+ * child target that may have been set with
|
||||
+ * _cairo_gstate_redirect_target.
|
||||
+ *
|
||||
+ * Return value: the original target surface
|
||||
+ **/
|
||||
+cairo_surface_t *
|
||||
+_cairo_gstate_get_original_target (cairo_gstate_t *gstate)
|
||||
+{
|
||||
+ return gstate->original_target;
|
||||
+}
|
||||
+
|
||||
+/**
|
||||
+ * _cairo_gstate_get_clip:
|
||||
+ * @gstate: a #cairo_gstate_t
|
||||
+ *
|
||||
+ * Return value: a pointer to the gstate's cairo_clip_t structure.
|
||||
+ */
|
||||
+cairo_clip_t *
|
||||
+_cairo_gstate_get_clip (cairo_gstate_t *gstate)
|
||||
+{
|
||||
+ return &gstate->clip;
|
||||
+}
|
||||
+
|
||||
cairo_status_t
|
||||
_cairo_gstate_set_source (cairo_gstate_t *gstate,
|
||||
cairo_pattern_t *source)
|
||||
Index: src/cairo.c
|
||||
===================================================================
|
||||
--- src/cairo.c.orig 2006-02-09 17:51:53.846750000 -0800
|
||||
+++ src/cairo.c 2006-02-09 18:56:40.375000000 -0800
|
||||
@@ -347,33 +347,133 @@
|
||||
}
|
||||
slim_hidden_def(moz_cairo_set_target);
|
||||
|
||||
-/* XXX: I want to rethink this API
|
||||
+/**
|
||||
+ * cairo_push_group:
|
||||
+ * @cr: a cairo context
|
||||
+ *
|
||||
+ * Pushes a CAIRO_CONTENT_COLOR_ALPHA temporary surface onto
|
||||
+ * the rendering stack, redirecting all rendering into it.
|
||||
+ * See cairo_push_group_with_content().
|
||||
+ */
|
||||
+
|
||||
void
|
||||
cairo_push_group (cairo_t *cr)
|
||||
{
|
||||
- if (cr->status)
|
||||
- return;
|
||||
+ cairo_push_group_with_content (cr, CAIRO_CONTENT_COLOR_ALPHA);
|
||||
+}
|
||||
+slim_hidden_def(cairo_push_group);
|
||||
|
||||
- cr->status = cairoPush (cr);
|
||||
- if (cr->status)
|
||||
- return;
|
||||
+/**
|
||||
+ * cairo_push_group_with_content:
|
||||
+ * @cr: a cairo context
|
||||
+ * @content: a %cairo_content_t indicating the type of group that
|
||||
+ * will be created
|
||||
+ *
|
||||
+ * Pushes a temporary surface onto the rendering stack, redirecting
|
||||
+ * all rendering into it. The surface dimensions are the size of
|
||||
+ * the current clipping bounding box. Initially, this surface
|
||||
+ * is painted with CAIRO_OPERATOR_CLEAR.
|
||||
+ *
|
||||
+ * cairo_push_group() calls cairo_save() so that any changes to the
|
||||
+ * graphics state will not be visible after cairo_pop_group() or
|
||||
+ * cairo_pop_group_with_alpha(). See cairo_pop_group() and
|
||||
+ * cairo_pop_group_with_alpha().
|
||||
+ */
|
||||
|
||||
- cr->status = _cairo_gstate_begin_group (cr->gstate);
|
||||
+void
|
||||
+cairo_push_group_with_content (cairo_t *cr, cairo_content_t content)
|
||||
+{
|
||||
+ cairo_status_t status;
|
||||
+ cairo_rectangle_t extents;
|
||||
+ cairo_surface_t *group_surface = NULL;
|
||||
+
|
||||
+ /* Get the extents that we'll use in creating our new group surface */
|
||||
+ _cairo_surface_get_extents (_cairo_gstate_get_target (cr->gstate), &extents);
|
||||
+ status = _cairo_clip_intersect_to_rectangle (_cairo_gstate_get_clip (cr->gstate), &extents);
|
||||
+ if (status != CAIRO_STATUS_SUCCESS)
|
||||
+ goto bail;
|
||||
+
|
||||
+ group_surface = cairo_surface_create_similar (_cairo_gstate_get_target (cr->gstate),
|
||||
+ content,
|
||||
+ extents.width,
|
||||
+ extents.height);
|
||||
+ status = cairo_surface_status (group_surface);
|
||||
+ if (status)
|
||||
+ goto bail;
|
||||
+
|
||||
+ /* Set device offsets on the new surface so that logically it appears at
|
||||
+ * the same location on the parent surface. */
|
||||
+ cairo_surface_set_device_offset (group_surface, -extents.x, -extents.y);
|
||||
+
|
||||
+ /* create a new gstate for the redirect */
|
||||
+ cairo_save (cr);
|
||||
+ if (cr->status)
|
||||
+ goto bail;
|
||||
+
|
||||
+ _cairo_gstate_redirect_target (cr->gstate, group_surface);
|
||||
+
|
||||
+bail:
|
||||
+ cairo_surface_destroy (group_surface);
|
||||
+ if (status)
|
||||
+ _cairo_set_error (cr, status);
|
||||
}
|
||||
+slim_hidden_def(cairo_push_group_with_content);
|
||||
|
||||
-void
|
||||
+cairo_pattern_t *
|
||||
cairo_pop_group (cairo_t *cr)
|
||||
{
|
||||
- if (cr->status)
|
||||
- return;
|
||||
+ cairo_surface_t *group_surface, *parent_target;
|
||||
+ cairo_pattern_t *group_pattern = NULL;
|
||||
+ cairo_matrix_t group_matrix;
|
||||
+
|
||||
+ /* Grab the active surfaces */
|
||||
+ group_surface = _cairo_gstate_get_target (cr->gstate);
|
||||
+ parent_target = _cairo_gstate_get_parent_target (cr->gstate);
|
||||
+
|
||||
+ /* Verify that we are at the right nesting level */
|
||||
+ if (parent_target == NULL) {
|
||||
+ _cairo_set_error (cr, CAIRO_STATUS_INVALID_POP_GROUP);
|
||||
+ return NULL;
|
||||
+ }
|
||||
+
|
||||
+ /* We need to save group_surface before we restore; we don't need
|
||||
+ * to reference parent_target and original_target, since the
|
||||
+ * gstate will still hold refs to them once we restore. */
|
||||
+ cairo_surface_reference (group_surface);
|
||||
+
|
||||
+ cairo_restore (cr);
|
||||
|
||||
- cr->status = _cairo_gstate_end_group (cr->gstate);
|
||||
if (cr->status)
|
||||
- return;
|
||||
+ goto done;
|
||||
+
|
||||
+ group_pattern = cairo_pattern_create_for_surface (group_surface);
|
||||
+ if (!group_pattern) {
|
||||
+ cr->status = CAIRO_STATUS_NO_MEMORY;
|
||||
+ goto done;
|
||||
+ }
|
||||
+
|
||||
+ _cairo_gstate_get_matrix (cr->gstate, &group_matrix);
|
||||
+ cairo_pattern_set_matrix (group_pattern, &group_matrix);
|
||||
+done:
|
||||
+ cairo_surface_destroy (group_surface);
|
||||
|
||||
- cr->status = cairoPop (cr);
|
||||
+ return group_pattern;
|
||||
}
|
||||
-*/
|
||||
+slim_hidden_def(cairo_pop_group);
|
||||
+
|
||||
+void
|
||||
+cairo_pop_group_to_source (cairo_t *cr)
|
||||
+{
|
||||
+ cairo_pattern_t *group_pattern;
|
||||
+
|
||||
+ group_pattern = cairo_pop_group (cr);
|
||||
+ if (!group_pattern)
|
||||
+ return;
|
||||
+
|
||||
+ cairo_set_source (cr, group_pattern);
|
||||
+ cairo_pattern_destroy (group_pattern);
|
||||
+}
|
||||
+slim_hidden_def(cairo_pop_group_to_source);
|
||||
|
||||
/**
|
||||
* cairo_set_operator:
|
||||
@@ -2421,6 +2521,30 @@
|
||||
if (cr->status)
|
||||
return (cairo_surface_t*) &_cairo_surface_nil;
|
||||
|
||||
+ return _cairo_gstate_get_original_target (cr->gstate);
|
||||
+}
|
||||
+
|
||||
+/**
|
||||
+ * cairo_get_group_target:
|
||||
+ * @cr: a cairo context
|
||||
+ *
|
||||
+ * Gets the target surface for the current transparency group
|
||||
+ * started by the last cairo_push_group() call on the cairo
|
||||
+ * context.
|
||||
+ *
|
||||
+ * This function may return NULL if there is no transparency
|
||||
+ * group on the target.
|
||||
+ *
|
||||
+ * Return value: the target group surface, or NULL if none. This
|
||||
+ * object is owned by cairo. To keep a reference to it, you must call
|
||||
+ * cairo_surface_reference().
|
||||
+ **/
|
||||
+cairo_surface_t *
|
||||
+cairo_get_group_target (cairo_t *cr)
|
||||
+{
|
||||
+ if (cr->status)
|
||||
+ return (cairo_surface_t*) &_cairo_surface_nil;
|
||||
+
|
||||
return _cairo_gstate_get_target (cr->gstate);
|
||||
}
|
||||
|
||||
Index: src/cairo.h
|
||||
===================================================================
|
||||
--- src/cairo.h.orig 2006-02-09 17:51:53.847750000 -0800
|
||||
+++ src/cairo.h 2006-02-09 18:04:02.390625000 -0800
|
||||
@@ -197,6 +197,26 @@
|
||||
} cairo_status_t;
|
||||
|
||||
/**
|
||||
+ * cairo_content_t
|
||||
+ * @CAIRO_CONTENT_COLOR: The surface will hold color content only.
|
||||
+ * @CAIRO_CONTENT_ALPHA: The surface will hold alpha content only.
|
||||
+ * @CAIRO_CONTENT_COLOR_ALPHA: The surface will hold color and alpha content.
|
||||
+ *
|
||||
+ * @cairo_content_t is used to describe the content that a surface will
|
||||
+ * contain, whether color information, alpha information (translucence
|
||||
+ * vs. opacity), or both.
|
||||
+ *
|
||||
+ * Note: The large values here are designed to keep cairo_content_t
|
||||
+ * values distinct from cairo_format_t values so that the
|
||||
+ * implementation can detect the error if users confuse the two types.
|
||||
+ */
|
||||
+typedef enum _cairo_content {
|
||||
+ CAIRO_CONTENT_COLOR = 0x1000,
|
||||
+ CAIRO_CONTENT_ALPHA = 0x2000,
|
||||
+ CAIRO_CONTENT_COLOR_ALPHA = 0x3000
|
||||
+} cairo_content_t;
|
||||
+
|
||||
+/**
|
||||
* cairo_write_func_t:
|
||||
* @closure: the output closure
|
||||
* @data: the buffer containing the data to write
|
||||
@@ -255,13 +275,17 @@
|
||||
cairo_public void
|
||||
moz_cairo_set_target (cairo_t *cr, cairo_surface_t *target);
|
||||
|
||||
-/* XXX: I want to rethink this API
|
||||
cairo_public void
|
||||
cairo_push_group (cairo_t *cr);
|
||||
|
||||
cairo_public void
|
||||
+cairo_push_group_with_content (cairo_t *cr, cairo_content_t content);
|
||||
+
|
||||
+cairo_public cairo_pattern_t *
|
||||
cairo_pop_group (cairo_t *cr);
|
||||
-*/
|
||||
+
|
||||
+cairo_public void
|
||||
+cairo_pop_group_to_source (cairo_t *cr);
|
||||
|
||||
/* Modify state */
|
||||
|
||||
@@ -996,6 +1020,9 @@
|
||||
cairo_public cairo_surface_t *
|
||||
cairo_get_target (cairo_t *cr);
|
||||
|
||||
+cairo_public cairo_surface_t *
|
||||
+cairo_get_group_target (cairo_t *cr);
|
||||
+
|
||||
typedef enum _cairo_path_data_type {
|
||||
CAIRO_PATH_MOVE_TO,
|
||||
CAIRO_PATH_LINE_TO,
|
||||
@@ -1121,26 +1148,6 @@
|
||||
|
||||
/* Surface manipulation */
|
||||
|
||||
-/**
|
||||
- * cairo_content_t
|
||||
- * @CAIRO_CONTENT_COLOR: The surface will hold color content only.
|
||||
- * @CAIRO_CONTENT_ALPHA: The surface will hold alpha content only.
|
||||
- * @CAIRO_CONTENT_COLOR_ALPHA: The surface will hold color and alpha content.
|
||||
- *
|
||||
- * @cairo_content_t is used to describe the content that a surface will
|
||||
- * contain, whether color information, alpha information (translucence
|
||||
- * vs. opacity), or both.
|
||||
- *
|
||||
- * Note: The large values here are designed to keep cairo_content_t
|
||||
- * values distinct from cairo_format_t values so that the
|
||||
- * implementation can detect the error if users confuse the two types.
|
||||
- */
|
||||
-typedef enum _cairo_content {
|
||||
- CAIRO_CONTENT_COLOR = 0x1000,
|
||||
- CAIRO_CONTENT_ALPHA = 0x2000,
|
||||
- CAIRO_CONTENT_COLOR_ALPHA = 0x3000
|
||||
-} cairo_content_t;
|
||||
-
|
||||
cairo_public cairo_surface_t *
|
||||
cairo_surface_create_similar (cairo_surface_t *other,
|
||||
cairo_content_t content,
|
||||
Index: src/cairoint.h
|
||||
===================================================================
|
||||
--- src/cairoint.h.orig 2006-02-09 18:01:01.890625000 -0800
|
||||
+++ src/cairoint.h 2006-02-09 18:51:23.265625000 -0800
|
||||
@@ -1077,9 +1077,24 @@
|
||||
cairo_private void
|
||||
_moz_cairo_gstate_set_target (cairo_gstate_t *gstate, cairo_surface_t *target);
|
||||
|
||||
+cairo_private cairo_bool_t
|
||||
+_cairo_gstate_is_redirected (cairo_gstate_t *gstate);
|
||||
+
|
||||
+cairo_private void
|
||||
+_cairo_gstate_redirect_target (cairo_gstate_t *gstate, cairo_surface_t *child);
|
||||
+
|
||||
cairo_private cairo_surface_t *
|
||||
_cairo_gstate_get_target (cairo_gstate_t *gstate);
|
||||
|
||||
+cairo_private cairo_surface_t *
|
||||
+_cairo_gstate_get_parent_target (cairo_gstate_t *gstate);
|
||||
+
|
||||
+cairo_private cairo_surface_t *
|
||||
+_cairo_gstate_get_original_target (cairo_gstate_t *gstate);
|
||||
+
|
||||
+cairo_private cairo_clip_t *
|
||||
+_cairo_gstate_get_clip (cairo_gstate_t *gstate);
|
||||
+
|
||||
cairo_private cairo_status_t
|
||||
_cairo_gstate_set_source (cairo_gstate_t *gstate, cairo_pattern_t *source);
|
||||
|
||||
@@ -2189,6 +2204,10 @@
|
||||
slim_hidden_proto(cairo_save)
|
||||
slim_hidden_proto(cairo_stroke_preserve)
|
||||
slim_hidden_proto(cairo_surface_destroy)
|
||||
+slim_hidden_proto(cairo_push_group)
|
||||
+slim_hidden_proto(cairo_push_group_with_content)
|
||||
+slim_hidden_proto(cairo_pop_group)
|
||||
+slim_hidden_proto(cairo_pop_group_to_source)
|
||||
slim_hidden_proto(moz_cairo_set_target)
|
||||
|
||||
CAIRO_END_DECLS
|
||||
Index: test/Makefile.am
|
||||
===================================================================
|
||||
--- test/Makefile.am.orig 2006-02-09 17:51:53.912750000 -0800
|
||||
+++ test/Makefile.am 2006-02-09 18:03:23.671875000 -0800
|
||||
@@ -59,7 +59,8 @@
|
||||
unantialiased-shapes \
|
||||
unbounded-operator \
|
||||
user-data \
|
||||
-rel-path
|
||||
+rel-path \
|
||||
+push-group
|
||||
|
||||
if HAVE_PTHREAD
|
||||
TESTS += pthread-show-text
|
||||
@@ -346,6 +347,7 @@
|
||||
user_data_LDADD = $(LDADDS)
|
||||
rel_path_LDADD = $(LDADDS)
|
||||
xlib_surface_LDADD = $(LDADDS)
|
||||
+push_group_LDADD = $(LDADDS)
|
||||
|
||||
noinst_PROGRAMS = imagediff png-flatten
|
||||
imagediff_LDADD = $(LDADDS)
|
||||
Index: test/push-group.c
|
||||
===================================================================
|
||||
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
|
||||
+++ test/push-group.c 2006-02-09 18:03:23.671875000 -0800
|
||||
@@ -0,0 +1,119 @@
|
||||
+/*
|
||||
+ * Copyright © 2005 Mozilla Corporation
|
||||
+ *
|
||||
+ * Permission to use, copy, modify, distribute, and sell this software
|
||||
+ * and its documentation for any purpose is hereby granted without
|
||||
+ * fee, provided that the above copyright notice appear in all copies
|
||||
+ * and that both that copyright notice and this permission notice
|
||||
+ * appear in supporting documentation, and that the name of
|
||||
+ * Mozilla Corporation not be used in advertising or publicity pertaining to
|
||||
+ * distribution of the software without specific, written prior
|
||||
+ * permission. Mozilla Corporation makes no representations about the
|
||||
+ * suitability of this software for any purpose. It is provided "as
|
||||
+ * is" without express or implied warranty.
|
||||
+ *
|
||||
+ * MOZILLA CORPORATION DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
|
||||
+ * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||
+ * FITNESS, IN NO EVENT SHALL MOZILLA CORPORATION BE LIABLE FOR ANY SPECIAL,
|
||||
+ * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
|
||||
+ * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
|
||||
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
|
||||
+ * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
+ *
|
||||
+ * Author: Vladimir Vukicevic <vladimir@pobox.com>
|
||||
+ */
|
||||
+
|
||||
+
|
||||
+#include "cairo-test.h"
|
||||
+
|
||||
+
|
||||
+#define UNIT_SIZE 100
|
||||
+#define PAD 5
|
||||
+#define INNER_PAD 10
|
||||
+
|
||||
+#define WIDTH (UNIT_SIZE + PAD) + PAD
|
||||
+#define HEIGHT (UNIT_SIZE + PAD) + PAD
|
||||
+
|
||||
+cairo_test_t test = {
|
||||
+ "push-group",
|
||||
+ "Verify that cairo_push_group works.",
|
||||
+ WIDTH, HEIGHT
|
||||
+};
|
||||
+
|
||||
+static cairo_test_status_t
|
||||
+draw (cairo_t *cr, int width, int height)
|
||||
+{
|
||||
+ cairo_pattern_t *gradient;
|
||||
+ int i, j;
|
||||
+
|
||||
+ gradient = cairo_pattern_create_linear (UNIT_SIZE - (INNER_PAD*2), 0,
|
||||
+ UNIT_SIZE - (INNER_PAD*2), UNIT_SIZE - (INNER_PAD*2));
|
||||
+ cairo_pattern_add_color_stop_rgba (gradient, 0.0, 0.3, 0.3, 0.3, 1.0);
|
||||
+ cairo_pattern_add_color_stop_rgba (gradient, 1.0, 1.0, 1.0, 1.0, 1.0);
|
||||
+
|
||||
+ for (j = 0; j < 1; j++) {
|
||||
+ for (i = 0; i < 1; i++) {
|
||||
+ double x = (i * UNIT_SIZE) + (i + 1) * PAD;
|
||||
+ double y = (j * UNIT_SIZE) + (j + 1) * PAD;
|
||||
+
|
||||
+ cairo_save (cr);
|
||||
+
|
||||
+ cairo_translate (cr, x, y);
|
||||
+
|
||||
+ /* draw a gradient background */
|
||||
+ cairo_save (cr);
|
||||
+ cairo_translate (cr, INNER_PAD, INNER_PAD);
|
||||
+ cairo_new_path (cr);
|
||||
+ cairo_rectangle (cr, 0, 0,
|
||||
+ UNIT_SIZE - (INNER_PAD*2), UNIT_SIZE - (INNER_PAD*2));
|
||||
+ cairo_set_source (cr, gradient);
|
||||
+ cairo_fill (cr);
|
||||
+ cairo_restore (cr);
|
||||
+
|
||||
+ /* clip to the unit size */
|
||||
+ cairo_rectangle (cr, 0, 0,
|
||||
+ UNIT_SIZE, UNIT_SIZE);
|
||||
+ cairo_clip (cr);
|
||||
+
|
||||
+ cairo_rectangle (cr, 0, 0,
|
||||
+ UNIT_SIZE, UNIT_SIZE);
|
||||
+ cairo_set_source_rgba (cr, 0, 0, 0, 1);
|
||||
+ cairo_set_line_width (cr, 2);
|
||||
+ cairo_stroke (cr);
|
||||
+
|
||||
+ /* start a group */
|
||||
+ cairo_push_group (cr);
|
||||
+
|
||||
+ /* draw diamond */
|
||||
+ cairo_move_to (cr, UNIT_SIZE / 2, 0);
|
||||
+ cairo_line_to (cr, UNIT_SIZE , UNIT_SIZE / 2);
|
||||
+ cairo_line_to (cr, UNIT_SIZE / 2, UNIT_SIZE);
|
||||
+ cairo_line_to (cr, 0 , UNIT_SIZE / 2);
|
||||
+ cairo_close_path (cr);
|
||||
+ cairo_set_source_rgba (cr, 0, 0, 1, 1);
|
||||
+ cairo_fill (cr);
|
||||
+
|
||||
+ /* draw circle */
|
||||
+ cairo_arc (cr,
|
||||
+ UNIT_SIZE / 2, UNIT_SIZE / 2,
|
||||
+ UNIT_SIZE / 3.5,
|
||||
+ 0, M_PI * 2);
|
||||
+ cairo_set_source_rgba (cr, 1, 0, 0, 1);
|
||||
+ cairo_fill (cr);
|
||||
+
|
||||
+ /* end group and paint */
|
||||
+ cairo_pop_group_to_source (cr);
|
||||
+ cairo_paint_with_alpha (cr, 0.5);
|
||||
+
|
||||
+ cairo_restore (cr);
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ return CAIRO_TEST_SUCCESS;
|
||||
+}
|
||||
+
|
||||
+int
|
||||
+main (void)
|
||||
+{
|
||||
+ return cairo_test (&test, draw);
|
||||
+}
|
|
@ -121,11 +121,11 @@ public:
|
|||
|
||||
/* returns TRUE if it succeeded */
|
||||
PRBool GetSolidColor(gfxRGBA& aColor) {
|
||||
return cairo_pattern_get_solid_color(mPattern,
|
||||
&aColor.r,
|
||||
&aColor.g,
|
||||
&aColor.b,
|
||||
&aColor.a) == CAIRO_STATUS_SUCCESS;
|
||||
return cairo_pattern_get_rgba(mPattern,
|
||||
&aColor.r,
|
||||
&aColor.g,
|
||||
&aColor.b,
|
||||
&aColor.a) == CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
protected:
|
||||
|
|
|
@ -114,7 +114,6 @@ _intersect_interval (double a_begin, double a_end, double b_begin, double b_end,
|
|||
return *out_begin < *out_end;
|
||||
}
|
||||
|
||||
#define MAX_STATIC_CLIP_RECTANGLES 50
|
||||
static cairo_bool_t
|
||||
_get_rectangular_clip (cairo_t *cr,
|
||||
int bounds_x, int bounds_y,
|
||||
|
@ -123,24 +122,31 @@ _get_rectangular_clip (cairo_t *cr,
|
|||
XRectangle *rectangles, int max_rectangles,
|
||||
int *num_rectangles)
|
||||
{
|
||||
cairo_clip_rect_t clips[MAX_STATIC_CLIP_RECTANGLES];
|
||||
int count;
|
||||
cairo_rectangle_list_t *cliplist;
|
||||
cairo_rectangle_t *clips;
|
||||
int i;
|
||||
double b_x = bounds_x;
|
||||
double b_y = bounds_y;
|
||||
double b_x_most = bounds_x + bounds_width;
|
||||
double b_y_most = bounds_y + bounds_height;
|
||||
int rect_count = 0;
|
||||
|
||||
if (!cairo_has_clip (cr)) {
|
||||
*need_clip = False;
|
||||
return True;
|
||||
cairo_bool_t retval = True;
|
||||
|
||||
cliplist = cairo_copy_clip_rectangles (cr);
|
||||
if (cliplist->status != CAIRO_STATUS_SUCCESS) {
|
||||
retval = False;
|
||||
goto FINISH;
|
||||
}
|
||||
|
||||
if (!cairo_extract_clip_rectangles (cr, MAX_STATIC_CLIP_RECTANGLES, clips, &count))
|
||||
return False;
|
||||
if (cliplist->num_rectangles == 0) {
|
||||
*num_rectangles = 0;
|
||||
*need_clip = True;
|
||||
goto FINISH;
|
||||
}
|
||||
|
||||
for (i = 0; i < count; ++i) {
|
||||
clips = cliplist->rectangles;
|
||||
|
||||
for (i = 0; i < cliplist->num_rectangles; ++i) {
|
||||
double intersect_x, intersect_y, intersect_x_most, intersect_y_most;
|
||||
|
||||
/* the clip is always in surface backend coordinates (i.e. native backend coords) */
|
||||
|
@ -148,7 +154,7 @@ _get_rectangular_clip (cairo_t *cr,
|
|||
b_y >= clips[i].y && b_y_most <= clips[i].y + clips[i].height) {
|
||||
/* the bounds are entirely inside the clip region so we don't need to clip. */
|
||||
*need_clip = False;
|
||||
return True;
|
||||
goto FINISH;
|
||||
}
|
||||
|
||||
if (_intersect_interval (b_x, b_x_most, clips[i].x, clips[i].x + clips[i].width,
|
||||
|
@ -157,14 +163,19 @@ _get_rectangular_clip (cairo_t *cr,
|
|||
&intersect_y, &intersect_y_most)) {
|
||||
XRectangle *rect = &rectangles[rect_count];
|
||||
|
||||
if (rect_count >= max_rectangles)
|
||||
return False;
|
||||
if (rect_count >= max_rectangles) {
|
||||
retval = False;
|
||||
goto FINISH;
|
||||
}
|
||||
|
||||
if (!_convert_coord_to_short (intersect_x, &rect->x) ||
|
||||
!_convert_coord_to_short (intersect_y, &rect->y) ||
|
||||
!_convert_coord_to_unsigned_short (intersect_x_most - intersect_x, &rect->width) ||
|
||||
!_convert_coord_to_unsigned_short (intersect_y_most - intersect_y, &rect->height))
|
||||
return False;
|
||||
{
|
||||
retval = False;
|
||||
goto FINISH;
|
||||
}
|
||||
|
||||
++rect_count;
|
||||
}
|
||||
|
@ -172,9 +183,15 @@ _get_rectangular_clip (cairo_t *cr,
|
|||
|
||||
*need_clip = True;
|
||||
*num_rectangles = rect_count;
|
||||
return True;
|
||||
|
||||
FINISH:
|
||||
cairo_rectangle_list_destroy (cliplist);
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
#define MAX_STATIC_CLIP_RECTANGLES 50
|
||||
|
||||
/**
|
||||
* Try the direct path.
|
||||
* @param status the status returned by the callback, if we took the direct path
|
||||
|
|
|
@ -569,11 +569,11 @@ gfxContext::SetColor(const gfxRGBA& c)
|
|||
PRBool
|
||||
gfxContext::GetColor(gfxRGBA& c)
|
||||
{
|
||||
return cairo_pattern_get_solid_color(cairo_get_source(mCairo),
|
||||
&c.r,
|
||||
&c.g,
|
||||
&c.b,
|
||||
&c.a) == CAIRO_STATUS_SUCCESS;
|
||||
return cairo_pattern_get_rgba(cairo_get_source(mCairo),
|
||||
&c.r,
|
||||
&c.g,
|
||||
&c.b,
|
||||
&c.a) == CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
void
|
||||
|
|
Загрузка…
Ссылка в новой задаче