Update to the latest and greatest Cairo.
authorhyatt <hyatt@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 19 May 2006 01:25:48 +0000 (01:25 +0000)
committerhyatt <hyatt@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 19 May 2006 01:25:48 +0000 (01:25 +0000)
git-svn-id: https://svn.webkit.org/repository/webkit/trunk@14482 268f45cc-cd09-0410-ab3c-d52691b4dbfc

54 files changed:
WebCore/platform/cairo/cairo/src/cairo-atsui-font.c
WebCore/platform/cairo/cairo/src/cairo-clip-private.h
WebCore/platform/cairo/cairo/src/cairo-clip.c
WebCore/platform/cairo/cairo/src/cairo-debug.h
WebCore/platform/cairo/cairo/src/cairo-directfb-surface.c
WebCore/platform/cairo/cairo/src/cairo-font.c
WebCore/platform/cairo/cairo/src/cairo-ft-font.c
WebCore/platform/cairo/cairo/src/cairo-glitz-surface.c
WebCore/platform/cairo/cairo/src/cairo-gstate.c
WebCore/platform/cairo/cairo/src/cairo-image-surface.c
WebCore/platform/cairo/cairo/src/cairo-meta-surface.c
WebCore/platform/cairo/cairo/src/cairo-output-stream.c
WebCore/platform/cairo/cairo/src/cairo-paginated-surface-private.h
WebCore/platform/cairo/cairo/src/cairo-paginated-surface.c
WebCore/platform/cairo/cairo/src/cairo-path.c
WebCore/platform/cairo/cairo/src/cairo-pattern.c
WebCore/platform/cairo/cairo/src/cairo-pdf-surface.c
WebCore/platform/cairo/cairo/src/cairo-platform.h
WebCore/platform/cairo/cairo/src/cairo-ps-surface.c
WebCore/platform/cairo/cairo/src/cairo-quartz-surface.c
WebCore/platform/cairo/cairo/src/cairo-quartz2-surface.c
WebCore/platform/cairo/cairo/src/cairo-scaled-font.c
WebCore/platform/cairo/cairo/src/cairo-surface-fallback.c
WebCore/platform/cairo/cairo/src/cairo-surface.c
WebCore/platform/cairo/cairo/src/cairo-svg-surface.c
WebCore/platform/cairo/cairo/src/cairo-wideint.c
WebCore/platform/cairo/cairo/src/cairo-wideint.h
WebCore/platform/cairo/cairo/src/cairo-win32-font.c
WebCore/platform/cairo/cairo/src/cairo-win32-private.h
WebCore/platform/cairo/cairo/src/cairo-win32-surface.c
WebCore/platform/cairo/cairo/src/cairo-win32.h
WebCore/platform/cairo/cairo/src/cairo-xcb-surface.c
WebCore/platform/cairo/cairo/src/cairo-xlib-surface.c
WebCore/platform/cairo/cairo/src/cairo-xlib-test.h
WebCore/platform/cairo/cairo/src/cairo.c
WebCore/platform/cairo/cairo/src/cairo.h
WebCore/platform/cairo/cairo/src/cairoint.h
WebCore/platform/cairo/cairo/src/test-fallback-surface.c
WebCore/platform/cairo/cairo/src/test-meta-surface.c
WebCore/platform/cairo/pixman/src/fbcompose.c
WebCore/platform/cairo/pixman/src/fbedge.c
WebCore/platform/cairo/pixman/src/fbedgeimp.h
WebCore/platform/cairo/pixman/src/fbpict.c
WebCore/platform/cairo/pixman/src/fbpict.h
WebCore/platform/cairo/pixman/src/fbtrap.c
WebCore/platform/cairo/pixman/src/iccolor.c
WebCore/platform/cairo/pixman/src/icpixels.c
WebCore/platform/cairo/pixman/src/ictrap.c
WebCore/platform/cairo/pixman/src/pixman-remap.h
WebCore/platform/cairo/pixman/src/pixman.h
WebCore/platform/cairo/pixman/src/pixregion.c
WebCore/platform/cairo/pixman/src/pixregionint.h
WebCore/platform/cairo/pixman/src/renderedge.c
WebCore/platform/cairo/pixman/src/renderedge.h

index bd622afe924f378a1c191b12406dd90ef4d2861f..9497cb35b3aaab239e3283dc8ca214d390f68378 100644 (file)
@@ -111,6 +111,7 @@ _cairo_atsui_font_face_scaled_font_create (void     *abstract_face,
 }
 
 static const cairo_font_face_backend_t _cairo_atsui_font_face_backend = {
+    CAIRO_FONT_TYPE_ATSUI,
     _cairo_atsui_font_face_destroy,
     _cairo_atsui_font_face_scaled_font_create
 };
@@ -149,7 +150,7 @@ CreateSizedCopyOfStyle(ATSUStyle inStyle, const cairo_matrix_t *scale)
     ATSUStyle style;
     OSStatus err;
 
-    // Set the style's size
+    /* Set the style's size */
     CGAffineTransform theTransform =
         CGAffineTransformMakeWithCairoFontScale(scale);
     Fixed theSize =
@@ -191,7 +192,7 @@ _cairo_atsui_font_set_metrics (cairo_atsui_font_t *font)
             extents.height = metrics.capHeight;
             extents.max_x_advance = metrics.maxAdvanceWidth;
 
-            // The FT backend doesn't handle max_y_advance either, so we'll ignore it for now. 
+            /* The FT backend doesn't handle max_y_advance either, so we'll ignore it for now. */
             extents.max_y_advance = 0.0;
 
                _cairo_scaled_font_set_metrics (&font->base, &extents);
@@ -292,7 +293,7 @@ _cairo_atsui_font_create_toy(cairo_toy_font_face_t *toy_face,
                                kFontNoLanguageCode, &fontID);
 
     if (err != noErr) {
-       // couldn't get the font - remap css names and try again
+       /* couldn't get the font - remap css names and try again */
 
        if (!strcmp(family, "serif"))
            family = "Times";
@@ -304,7 +305,7 @@ _cairo_atsui_font_create_toy(cairo_toy_font_face_t *toy_face,
            family = "Gadget";
        else if (!strcmp(family, "monospace"))
            family = "Courier";
-       else // anything else - return error instead?
+       else /* anything else - return error instead? */
            family = "Courier";
 
        err = ATSUFindFontFromName(family, strlen(family),
@@ -545,7 +546,7 @@ _cairo_atsui_font_text_to_glyphs (void              *abstract_font,
 
     err = ATSUSetTextPointerLocation(textLayout, utf16, 0, n16, n16);
 
-    // Set the style for all of the text
+    /* Set the style for all of the text */
     err = ATSUSetRunStyle(textLayout,
                          font->style, kATSUFromTextBeginning, kATSUToTextEnd);
 
@@ -606,7 +607,7 @@ _cairo_atsui_font_old_show_glyphs (void                    *abstract_font,
                                      &rect,
                                      &extra);
 
-    // Create a CGBitmapContext for the dest surface for drawing into
+    /* Create a CGBitmapContext for the dest surface for drawing into */
     if (destImageSurface->depth == 1) {
         colorSpace = CGColorSpaceCreateDeviceGray();
         bits_per_comp = 1;
@@ -651,7 +652,7 @@ _cairo_atsui_font_old_show_glyphs (void                    *abstract_font,
     CGContextSetFontSize(myBitmapContext, 1.0);
     CGContextSetTextMatrix(myBitmapContext, textTransform);
 
-    if (pattern->type == CAIRO_PATTERN_SOLID &&
+    if (pattern->type == CAIRO_PATTERN_TYPE_SOLID &&
        _cairo_pattern_is_opaque_solid(pattern))
     {
        cairo_solid_pattern_t *solid = (cairo_solid_pattern_t *)pattern;
@@ -693,11 +694,12 @@ _cairo_atsui_font_old_show_glyphs (void                  *abstract_font,
                /* XXX: Need to get the text clipped */
        }
        
-    // TODO - bold and italic text
-    //
-    // We could draw the text using ATSUI and get bold, italics
-    // etc. for free, but ATSUI does a lot of text layout work
-    // that we don't really need...
+    /* TODO - bold and italic text
+     *
+     * We could draw the text using ATSUI and get bold, italics
+     * etc. for free, but ATSUI does a lot of text layout work
+     * that we don't really need...
+     */
 
        
     for (i = 0; i < num_glyphs; i++) {
@@ -723,6 +725,7 @@ _cairo_atsui_font_old_show_glyphs (void                    *abstract_font,
 }
 
 const cairo_scaled_font_backend_t cairo_atsui_scaled_font_backend = {
+    CAIRO_FONT_TYPE_ATSUI,
     _cairo_atsui_font_create_toy,
     _cairo_atsui_font_fini,
     _cairo_atsui_font_scaled_glyph_init,
index bb96d66d3b56b0ae4cb9526dc297973a444ef577..a714356dd1c1beb1cddca8135981773300a9ed64 100644 (file)
@@ -87,6 +87,11 @@ _cairo_clip_fini (cairo_clip_t *clip);
 cairo_private void
 _cairo_clip_init_copy (cairo_clip_t *clip, cairo_clip_t *other);
 
+cairo_private void
+_cairo_clip_init_deep_copy (cairo_clip_t    *clip,
+                            cairo_clip_t    *other,
+                            cairo_surface_t *target);
+
 cairo_private cairo_status_t
 _cairo_clip_reset (cairo_clip_t *clip);
 
@@ -119,8 +124,13 @@ _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);
+                                int max_rectangles,
+                                cairo_clip_rect_t *rectangles_out,
+                                int *num_rectangles_out);
+
+cairo_private void
+_cairo_clip_translate (cairo_clip_t  *clip,
+                       cairo_fixed_t  tx,
+                       cairo_fixed_t  ty);
 
 #endif /* CAIRO_CLIP_PRIVATE_H */
index 0fce861c2b29aca8d6b049832a1b80b31ac28fda..b174df40f09980842dc74be385403f3ed5be7fa1 100644 (file)
@@ -234,8 +234,7 @@ _cairo_clip_intersect_path (cairo_clip_t       *clip,
                            cairo_path_fixed_t *path,
                            cairo_fill_rule_t   fill_rule,
                            double              tolerance,
-                           cairo_antialias_t   antialias,
-                           cairo_surface_t    *target)
+                           cairo_antialias_t   antialias)
 {
     cairo_clip_path_t *clip_path;
     cairo_status_t status;
@@ -248,8 +247,10 @@ _cairo_clip_intersect_path (cairo_clip_t       *clip,
        return CAIRO_STATUS_NO_MEMORY;
 
     status = _cairo_path_fixed_init_copy (&clip_path->path, path);
-    if (status)
+    if (status) {
+       free (clip_path);
        return status;
+    }
 
     clip_path->ref_count = 1;
     clip_path->fill_rule = fill_rule;
@@ -257,7 +258,6 @@ _cairo_clip_intersect_path (cairo_clip_t       *clip,
     clip_path->antialias = antialias;
     clip_path->prev = clip->path;
     clip->path = clip_path;
-    clip->serial = _cairo_surface_allocate_clip_serial (target);
 
     return CAIRO_STATUS_SUCCESS;
 }
@@ -433,13 +433,26 @@ _cairo_clip_clip (cairo_clip_t       *clip,
 {
     cairo_status_t status;
     cairo_traps_t traps;
+    cairo_path_fixed_t path_transformed;
+
+    if (_cairo_surface_has_device_offset_or_scale (target)) {
+       _cairo_path_fixed_init_copy (&path_transformed, path);
+       _cairo_path_fixed_offset (&path_transformed,
+                                 _cairo_fixed_from_double (target->device_x_offset),
+                                 _cairo_fixed_from_double (target->device_y_offset));
+       path = &path_transformed;
+    }
     
     status = _cairo_clip_intersect_path (clip,
                                         path, fill_rule, tolerance,
-                                        antialias, target);
+                                        antialias);
+    if (status == CAIRO_STATUS_SUCCESS)
+        clip->serial = _cairo_surface_allocate_clip_serial (target);
+
     if (status != CAIRO_INT_STATUS_UNSUPPORTED)
        return status;
 
+
     _cairo_traps_init (&traps);
     status = _cairo_path_fixed_fill_to_traps (path,
                                              fill_rule,
@@ -456,6 +469,8 @@ _cairo_clip_clip (cairo_clip_t       *clip,
        
  bail:
     _cairo_traps_fini (&traps);
+    if (path == &path_transformed)
+       _cairo_path_fixed_fini (&path_transformed);
 
     return status;
 }
@@ -509,3 +524,70 @@ _cairo_clip_extract_rectangles (cairo_clip_t *clip,
     return _cairo_region_to_clip_rectangles (clip->region,
         max_rectangles, rectangles_out, num_rectangles_out);
 }
+
+void
+_cairo_clip_translate (cairo_clip_t  *clip,
+                       cairo_fixed_t  tx,
+                       cairo_fixed_t  ty)
+{
+    if (clip->region) {
+        pixman_region_translate (clip->region,
+                                 _cairo_fixed_integer_part (tx),
+                                 _cairo_fixed_integer_part (ty));
+    }
+
+    if (clip->surface) {
+        clip->surface_rect.x += _cairo_fixed_integer_part (tx);
+        clip->surface_rect.y += _cairo_fixed_integer_part (ty);
+    }
+
+    if (clip->path) {
+        cairo_clip_path_t *clip_path = clip->path;
+        while (clip_path) {
+            _cairo_path_fixed_offset (&clip_path->path, tx, ty);
+            clip_path = clip_path->prev;
+        }
+    }
+}
+
+static void
+_cairo_clip_path_reapply_clip_path (cairo_clip_t      *clip,
+                                    cairo_clip_path_t *clip_path)
+{
+    if (clip_path->prev)
+        _cairo_clip_path_reapply_clip_path (clip, clip_path->prev);
+
+    _cairo_clip_intersect_path (clip,
+                                &clip_path->path,
+                                clip_path->fill_rule,
+                                clip_path->tolerance,
+                                clip_path->antialias);
+}
+
+void
+_cairo_clip_init_deep_copy (cairo_clip_t    *clip,
+                            cairo_clip_t    *other,
+                            cairo_surface_t *target)
+{
+    _cairo_clip_init (clip, target);
+
+    if (other->mode != clip->mode) {
+        /* We should reapply the original clip path in this case, and let
+         * whatever the right handling is happen */
+    } else {
+        if (other->region) {
+            clip->region = pixman_region_create ();
+            pixman_region_copy (clip->region, other->region);
+        }
+
+        if (other->surface) {
+            _cairo_surface_clone_similar (target, clip->surface, &clip->surface);
+            clip->surface_rect = other->surface_rect;
+        }
+
+        if (other->path) {
+            _cairo_clip_path_reapply_clip_path (clip, other->path);
+        }
+    }
+}
+
index 2a7c3af88a493c8afb7c332d56d343a94cc2887f..3e0ddfac7470f8c50deb73ab372b64baeed4cc03 100644 (file)
@@ -46,21 +46,21 @@ struct _cairo_traps;
 struct _cairo_trapezoid;
 struct _cairo_clip;
 
-void
+cairo_public void
 cairo_debug_reset_static_data (void);
 
-void
+cairo_public void
 cairo_debug_dump_clip (struct _cairo_clip *clip,
                        FILE *fp);
-void
+cairo_public void
 cairo_debug_dump_path (struct _cairo_path_fixed *path,
                        FILE *fp);
 
-void
+cairo_public void
 cairo_debug_dump_traps (struct _cairo_traps *traps,
                         FILE *fp);
 
-void
+cairo_public void
 cairo_debug_dump_trapezoid_array (struct _cairo_trapezoid *traps,
                                   int num_traps,
                                   FILE *fp);
index be1791584f644c670a10d4468c626a2f5ff7bd50..fcd5dd781344504903cac1bb563f62be0e7f045b 100644 (file)
@@ -150,7 +150,7 @@ static inline int cairo_to_directfb_format(cairo_format_t format ) {
                                                return DSPF_A1; 
                                default:
                                {
-                                               //assert(0);
+                                               /*assert(0);*/
                                                return DSPF_UNKNOWN; 
                                }
                }
@@ -483,9 +483,9 @@ _cairo_directfb_surface_composite (cairo_operator_t op,
        if( _dfb_set_operator(op,surface->buffer) == DFB_UNSUPPORTED ) 
                return CAIRO_INT_STATUS_UNSUPPORTED;
 
-    if (src_pattern->type == CAIRO_PATTERN_SOLID ) { 
+    if (src_pattern->type == CAIRO_PATTERN_TYPE_SOLID ) { 
 
-    } else if (src_pattern->type != CAIRO_PATTERN_SURFACE ||
+    } else if (src_pattern->type != CAIRO_PATTERN_TYPE_SURFACE ||
                        src_pattern->extend != CAIRO_EXTEND_NONE) {
                return CAIRO_INT_STATUS_UNSUPPORTED;
        }
@@ -494,7 +494,7 @@ _cairo_directfb_surface_composite (cairo_operator_t op,
        /* FIXME: When we fully support RENDER style 4-channel
         * masks we need to check r/g/b != 1.0.
         */
-       if (mask_pattern->type != CAIRO_PATTERN_SOLID)
+       if (mask_pattern->type != CAIRO_PATTERN_TYPE_SOLID)
            return CAIRO_INT_STATUS_UNSUPPORTED;
 
                alpha = ((cairo_solid_pattern_t *)mask_pattern)->color.alpha_short >> 8;
@@ -662,6 +662,7 @@ _cairo_directfb_surface_scaled_glyph_fini (cairo_scaled_glyph_t *scaled_glyph,
 
 
 static const cairo_surface_backend_t cairo_directfb_surface_backend = {
+               CAIRO_SURFACE_TYPE_DIRECTFB,    
                _cairo_directfb_surface_create_similar,
                _cairo_directfb_surface_finish,
                _cairo_directfb_surface_acquire_source_image,
index b0fab1b4a0c4b49f716b471d0bb81ace77aeed94..65124803d25ab1b569699f5d4727a4eaf9af6af0 100644 (file)
@@ -130,6 +130,18 @@ cairo_font_face_destroy (cairo_font_face_t *font_face)
     free (font_face);
 }
 
+/**
+ * cairo_font_face_get_type:
+ * @font_face: a #cairo_font_face_t
+ * 
+ * Return value: The type of @font_face. See #cairo_font_type_t.
+ **/
+cairo_font_type_t
+cairo_font_face_get_type (cairo_font_face_t *font_face)
+{
+    return font_face->backend->type;
+}
+
 /**
  * cairo_font_face_status:
  * @font_face: a #cairo_font_face_t
@@ -409,6 +421,7 @@ _cairo_toy_font_face_scaled_font_create (void                *abstract_font_face
 }
 
 static const cairo_font_face_backend_t _cairo_toy_font_face_backend = {
+    CAIRO_FONT_TYPE_TOY,
     _cairo_toy_font_face_destroy,
     _cairo_toy_font_face_scaled_font_create
 };
index da1adaa408ecb720e2c53dcdfa2caba070ed50a3..092838ab4fcaa570971366c918334bcec2d1b537 100644 (file)
@@ -715,191 +715,184 @@ _get_bitmap_surface (FT_Bitmap               *bitmap,
     width = bitmap->width;
     height = bitmap->rows;
     
-    if (width * height == 0) {
-       if (own_buffer && bitmap->buffer)
-           free (bitmap->buffer);
-       
-       *surface = NULL;
-    } else {
-       switch (bitmap->pixel_mode) {
-       case FT_PIXEL_MODE_MONO:
-           stride = (((width + 31) & ~31) >> 3);
-           if (own_buffer) {
-               data = bitmap->buffer;
-               assert (stride == bitmap->pitch);
-           } else {
-               data = malloc (stride * height);
-               if (!data)
-                   return CAIRO_STATUS_NO_MEMORY;
+    switch (bitmap->pixel_mode) {
+    case FT_PIXEL_MODE_MONO:
+       stride = (((width + 31) & ~31) >> 3);
+       if (own_buffer) {
+           data = bitmap->buffer;
+           assert (stride == bitmap->pitch);
+       } else {
+           data = malloc (stride * height);
+           if (!data)
+               return CAIRO_STATUS_NO_MEMORY;
 
-               if (stride == bitmap->pitch) {
-                   memcpy (data, bitmap->buffer, stride * height);
-               } else {
-                   int i;
-                   unsigned char *source, *dest;
+           if (stride == bitmap->pitch) {
+               memcpy (data, bitmap->buffer, stride * height);
+           } else {
+               int i;
+               unsigned char *source, *dest;
                
-                   source = bitmap->buffer;
-                   dest = data;
-                   for (i = height; i; i--) {
-                       memcpy (dest, source, bitmap->pitch);
-                       memset (dest + bitmap->pitch, '\0', stride - bitmap->pitch);
+               source = bitmap->buffer;
+               dest = data;
+               for (i = height; i; i--) {
+                   memcpy (dest, source, bitmap->pitch);
+                   memset (dest + bitmap->pitch, '\0', stride - bitmap->pitch);
                        
-                       source += bitmap->pitch;
-                       dest += stride;
-                   }
+                   source += bitmap->pitch;
+                   dest += stride;
                }
            }
+       }
            
-           if (_native_byte_order_lsb())
-           {
-               unsigned char   *d = data, c;
-               int             count = stride * height;
+       if (_native_byte_order_lsb())
+       {
+           unsigned char   *d = data, c;
+           int         count = stride * height;
                
-               while (count--) {
-                   c = *d;
-                   c = ((c << 1) & 0xaa) | ((c >> 1) & 0x55);
-                   c = ((c << 2) & 0xcc) | ((c >> 2) & 0x33);
-                   c = ((c << 4) & 0xf0) | ((c >> 4) & 0x0f);
-                   *d++ = c;
-               }
+           while (count--) {
+               c = *d;
+               c = ((c << 1) & 0xaa) | ((c >> 1) & 0x55);
+               c = ((c << 2) & 0xcc) | ((c >> 2) & 0x33);
+               c = ((c << 4) & 0xf0) | ((c >> 4) & 0x0f);
+               *d++ = c;
            }
-           format = CAIRO_FORMAT_A1;
-           break;
+       }
+       format = CAIRO_FORMAT_A1;
+       break;
 
-       case FT_PIXEL_MODE_LCD:
-        case FT_PIXEL_MODE_LCD_V:
-       case FT_PIXEL_MODE_GRAY:
-           switch (font_options->antialias) {
-           case CAIRO_ANTIALIAS_DEFAULT:
-           case CAIRO_ANTIALIAS_GRAY:
-           case CAIRO_ANTIALIAS_NONE:
+    case FT_PIXEL_MODE_LCD:
+    case FT_PIXEL_MODE_LCD_V:
+    case FT_PIXEL_MODE_GRAY:
+       switch (font_options->antialias) {
+       case CAIRO_ANTIALIAS_DEFAULT:
+       case CAIRO_ANTIALIAS_GRAY:
+       case CAIRO_ANTIALIAS_NONE:
+       default:
+           stride = bitmap->pitch;
+           if (own_buffer) {
+               data = bitmap->buffer;
+           } else {
+               data = malloc (stride * height);
+               if (!data)
+                   return CAIRO_STATUS_NO_MEMORY;
+               memcpy (data, bitmap->buffer, stride * height);
+           }
+           format = CAIRO_FORMAT_A8;
+           break;
+       case CAIRO_ANTIALIAS_SUBPIXEL: {
+           int             x, y;
+           unsigned char   *in_line, *out_line, *in;
+           unsigned int    *out;
+           unsigned int    red, green, blue;
+           int             rf, gf, bf;
+           int             s;
+           int             o, os;
+           unsigned char   *data_rgba;
+           unsigned int    width_rgba, stride_rgba;
+           int             vmul = 1;
+           int             hmul = 1;
+               
+           switch (font_options->subpixel_order) {
+           case CAIRO_SUBPIXEL_ORDER_DEFAULT:
+           case CAIRO_SUBPIXEL_ORDER_RGB:
+           case CAIRO_SUBPIXEL_ORDER_BGR:
            default:
-               stride = bitmap->pitch;
-               if (own_buffer) {
-                   data = bitmap->buffer;
-               } else {
-                   data = malloc (stride * height);
-                   if (!data)
-                       return CAIRO_STATUS_NO_MEMORY;
-                   memcpy (data, bitmap->buffer, stride * height);
-               }
-               format = CAIRO_FORMAT_A8;
+               width /= 3;
+               hmul = 3;
                break;
-           case CAIRO_ANTIALIAS_SUBPIXEL: {
-               int                 x, y;
-               unsigned char   *in_line, *out_line, *in;
-               unsigned int    *out;
-               unsigned int    red, green, blue;
-               int                 rf, gf, bf;
-               int                 s;
-               int                 o, os;
-               unsigned char   *data_rgba;
-               unsigned int    width_rgba, stride_rgba;
-               int                 vmul = 1;
-               int                 hmul = 1;
-               
-               switch (font_options->subpixel_order) {
-               case CAIRO_SUBPIXEL_ORDER_DEFAULT:
-               case CAIRO_SUBPIXEL_ORDER_RGB:
-               case CAIRO_SUBPIXEL_ORDER_BGR:
-               default:
-                   width /= 3;
-                   hmul = 3;
-                   break;
-               case CAIRO_SUBPIXEL_ORDER_VRGB:
-               case CAIRO_SUBPIXEL_ORDER_VBGR:
-                   vmul = 3;
-                   height /= 3;
-                   break;
-               }
-               /*
-                * Filter the glyph to soften the color fringes
-                */
-               width_rgba = width;
-               stride = bitmap->pitch;
-               stride_rgba = (width_rgba * 4 + 3) & ~3;
-               data_rgba = calloc (1, stride_rgba * height);
+           case CAIRO_SUBPIXEL_ORDER_VRGB:
+           case CAIRO_SUBPIXEL_ORDER_VBGR:
+               vmul = 3;
+               height /= 3;
+               break;
+           }
+           /*
+            * Filter the glyph to soften the color fringes
+            */
+           width_rgba = width;
+           stride = bitmap->pitch;
+           stride_rgba = (width_rgba * 4 + 3) & ~3;
+           data_rgba = calloc (1, stride_rgba * height);
     
-               os = 1;
-               switch (font_options->subpixel_order) {
-               case CAIRO_SUBPIXEL_ORDER_VRGB:
-                   os = stride;
-               case CAIRO_SUBPIXEL_ORDER_DEFAULT:
-               case CAIRO_SUBPIXEL_ORDER_RGB:
-               default:
-                   rf = 0;
-                   gf = 1;
-                   bf = 2;
-                   break;
-               case CAIRO_SUBPIXEL_ORDER_VBGR:
-                   os = stride;
-               case CAIRO_SUBPIXEL_ORDER_BGR:
-                   bf = 0;
-                   gf = 1;
-                   rf = 2;
-                   break;
-               }
-               in_line = bitmap->buffer;
-               out_line = data_rgba;
-               for (y = 0; y < height; y++)
+           os = 1;
+           switch (font_options->subpixel_order) {
+           case CAIRO_SUBPIXEL_ORDER_VRGB:
+               os = stride;
+           case CAIRO_SUBPIXEL_ORDER_DEFAULT:
+           case CAIRO_SUBPIXEL_ORDER_RGB:
+           default:
+               rf = 0;
+               gf = 1;
+               bf = 2;
+               break;
+           case CAIRO_SUBPIXEL_ORDER_VBGR:
+               os = stride;
+           case CAIRO_SUBPIXEL_ORDER_BGR:
+               bf = 0;
+               gf = 1;
+               rf = 2;
+               break;
+           }
+           in_line = bitmap->buffer;
+           out_line = data_rgba;
+           for (y = 0; y < height; y++)
+           {
+               in = in_line;
+               out = (unsigned int *) out_line;
+               in_line += stride * vmul;
+               out_line += stride_rgba;
+               for (x = 0; x < width * hmul; x += hmul)
                {
-                   in = in_line;
-                   out = (unsigned int *) out_line;
-                   in_line += stride * vmul;
-                   out_line += stride_rgba;
-                   for (x = 0; x < width * hmul; x += hmul)
+                   red = green = blue = 0;
+                   o = 0;
+                   for (s = 0; s < 3; s++)
                    {
-                       red = green = blue = 0;
-                       o = 0;
-                       for (s = 0; s < 3; s++)
-                       {
-                           red += filters[rf][s]*in[x+o];
-                           green += filters[gf][s]*in[x+o];
-                           blue += filters[bf][s]*in[x+o];
-                           o += os;
-                       }
-                       red = red / 65536;
-                       green = green / 65536;
-                       blue = blue / 65536;
-                       *out++ = (green << 24) | (red << 16) | (green << 8) | blue;
+                       red += filters[rf][s]*in[x+o];
+                       green += filters[gf][s]*in[x+o];
+                       blue += filters[bf][s]*in[x+o];
+                       o += os;
                    }
+                   red = red / 65536;
+                   green = green / 65536;
+                   blue = blue / 65536;
+                   *out++ = (green << 24) | (red << 16) | (green << 8) | blue;
                }
+           }
     
-               /* Images here are stored in native format. The
-                * backend must convert to its own format as needed
-                */
+           /* Images here are stored in native format. The
+            * backend must convert to its own format as needed
+            */
     
-               if (own_buffer)
-                   free (bitmap->buffer);
-               data = data_rgba;
-               stride = stride_rgba;
-               format = CAIRO_FORMAT_ARGB32;
-               subpixel = TRUE;
-               break;
-           }
-           }
+           if (own_buffer)
+               free (bitmap->buffer);
+           data = data_rgba;
+           stride = stride_rgba;
+           format = CAIRO_FORMAT_ARGB32;
+           subpixel = TRUE;
            break;
-       case FT_PIXEL_MODE_GRAY2:
-       case FT_PIXEL_MODE_GRAY4:
-           /* These could be triggered by very rare types of TrueType fonts */
-       default:
-           return CAIRO_STATUS_NO_MEMORY;
        }
-    
-       *surface = (cairo_image_surface_t *)
-           cairo_image_surface_create_for_data (data,
-                                                format,
-                                                width, height, stride);
-       if ((*surface)->base.status) {
-           free (data);
-           return CAIRO_STATUS_NO_MEMORY;
        }
+       break;
+    case FT_PIXEL_MODE_GRAY2:
+    case FT_PIXEL_MODE_GRAY4:
+       /* These could be triggered by very rare types of TrueType fonts */
+    default:
+       return CAIRO_STATUS_NO_MEMORY;
+    }
+    
+    *surface = (cairo_image_surface_t *)
+       cairo_image_surface_create_for_data (data,
+                                            format,
+                                            width, height, stride);
+    if ((*surface)->base.status) {
+       free (data);
+       return CAIRO_STATUS_NO_MEMORY;
+    }
        
-       if (subpixel)
-           pixman_image_set_component_alpha ((*surface)->pixman_image, TRUE);
+    if (subpixel)
+       pixman_image_set_component_alpha ((*surface)->pixman_image, TRUE);
 
-       _cairo_image_surface_assume_ownership_of_data ((*surface));
-    }
+    _cairo_image_surface_assume_ownership_of_data ((*surface));
 
     return CAIRO_STATUS_SUCCESS;
 }
@@ -1074,7 +1067,9 @@ _render_glyph_bitmap (FT_Face                   face,
     if (error)
        return CAIRO_STATUS_NO_MEMORY;
 
-    _get_bitmap_surface (&glyphslot->bitmap, FALSE, font_options, surface);
+    status = _get_bitmap_surface (&glyphslot->bitmap, FALSE, font_options, surface);
+    if (status)
+       return status;
     
     /*
      * Note: the font's coordinate system is upside down from ours, so the
@@ -1906,6 +1901,7 @@ _cairo_ft_show_glyphs (void                      *abstract_font,
 }
 
 const cairo_scaled_font_backend_t cairo_ft_scaled_font_backend = {
+    CAIRO_FONT_TYPE_FT,
     _cairo_ft_scaled_font_create_toy,
     _cairo_ft_scaled_font_fini,
     _cairo_ft_scaled_glyph_init,
@@ -2009,6 +2005,7 @@ _cairo_ft_font_face_scaled_font_create (void                     *abstract_face,
 }
 
 static const cairo_font_face_backend_t _cairo_ft_font_face_backend = {
+    CAIRO_FONT_TYPE_FT,
     _cairo_ft_font_face_destroy,
     _cairo_ft_font_face_scaled_font_create
 };
index b62547236b3b4efb474ef9cd324f72e58a35bcd7..c000917acfe372576d64eaeba29df47f5abde533 100644 (file)
@@ -551,8 +551,8 @@ _cairo_glitz_pattern_acquire_surface (cairo_pattern_t                     *pattern,
     attr->acquired = FALSE;
 
     switch (pattern->type) {
-    case CAIRO_PATTERN_LINEAR:
-    case CAIRO_PATTERN_RADIAL: {
+    case CAIRO_PATTERN_TYPE_LINEAR:
+    case CAIRO_PATTERN_TYPE_RADIAL: {
        cairo_gradient_pattern_t    *gradient =
            (cairo_gradient_pattern_t *) pattern;
        char                        *data;
@@ -587,7 +587,7 @@ _cairo_glitz_pattern_acquire_surface (cairo_pattern_t                     *pattern,
        if (!CAIRO_GLITZ_FEATURE_OK (dst->surface, FRAGMENT_PROGRAM))
            break;
 
-       if (pattern->type == CAIRO_PATTERN_RADIAL)
+       if (pattern->type == CAIRO_PATTERN_TYPE_RADIAL)
            n_base_params = 6;
        else
            n_base_params = 4;
@@ -639,7 +639,7 @@ _cairo_glitz_pattern_acquire_surface (cairo_pattern_t                     *pattern,
 
        glitz_buffer_destroy (buffer);
 
-       if (pattern->type == CAIRO_PATTERN_LINEAR)
+       if (pattern->type == CAIRO_PATTERN_TYPE_LINEAR)
        {
            cairo_linear_pattern_t *grad = (cairo_linear_pattern_t *) pattern;
 
@@ -776,8 +776,8 @@ _cairo_glitz_pattern_acquire_surfaces (cairo_pattern_t                      *src,
      * information in mask, so this will need to change when we
      * support RENDER-style 4-channel masks. */
 
-    if (src->type == CAIRO_PATTERN_SOLID &&
-       mask->type == CAIRO_PATTERN_SOLID)
+    if (src->type == CAIRO_PATTERN_TYPE_SOLID &&
+       mask->type == CAIRO_PATTERN_TYPE_SOLID)
     {
        cairo_color_t combined;
        cairo_solid_pattern_t *src_solid = (cairo_solid_pattern_t *) src;
@@ -1018,7 +1018,7 @@ _cairo_glitz_surface_composite_trapezoids (cairo_operator_t  op,
     if (_glitz_ensure_target (dst->surface))
        return CAIRO_INT_STATUS_UNSUPPORTED;
 
-    if (pattern->type == CAIRO_PATTERN_SURFACE)
+    if (pattern->type == CAIRO_PATTERN_TYPE_SURFACE)
     {
        _cairo_pattern_init_copy (&tmp_src_pattern.base, pattern);
 
@@ -2121,6 +2121,7 @@ _cairo_glitz_surface_flush (void *abstract_surface)
 }
 
 static const cairo_surface_backend_t cairo_glitz_surface_backend = {
+    CAIRO_SURFACE_TYPE_GLITZ,
     _cairo_glitz_surface_create_similar,
     _cairo_glitz_surface_finish,
     _cairo_glitz_surface_acquire_source_image,
index ca7c111e6f867f3d2b74eef0e6445835dd99e59d..8f3397d6e6754afb08fa61fab16c9b72c5a19711 100644 (file)
@@ -252,13 +252,6 @@ _cairo_gstate_clone (cairo_gstate_t *other)
     return gstate;
 }
 
-void
-_moz_cairo_gstate_set_target (cairo_gstate_t *gstate, cairo_surface_t *target)
-{
-    cairo_surface_destroy (gstate->target);
-    gstate->target = cairo_surface_reference (target);
-}
-
 static cairo_status_t
 _cairo_gstate_recursive_apply_clip_path (cairo_gstate_t *gstate,
                                         cairo_clip_path_t *cpath)
@@ -310,30 +303,14 @@ _cairo_gstate_redirect_target (cairo_gstate_t *gstate, cairo_surface_t *child)
      * 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);
-    }
+    _cairo_clip_fini (&gstate->clip);
+    _cairo_clip_init_deep_copy (&gstate->clip, &gstate->next->clip, child);
+
+    /* The clip is in surface backend coordinates for the previous target;
+     * translate it into the child's backend coordinates. */
+    _cairo_clip_translate (&gstate->clip,
+                           _cairo_fixed_from_double (child->device_x_offset - gstate->parent_target->device_x_offset),
+                           _cairo_fixed_from_double (child->device_y_offset - gstate->parent_target->device_y_offset));
 }
 
 /**
@@ -394,6 +371,51 @@ _cairo_gstate_get_original_target (cairo_gstate_t *gstate)
     return gstate->original_target;
 }
 
+/**
+ * _cairo_gstate_get_target_offsets_from_original
+ * @gstate: a #cairo_gstate_t
+ * @dx: device offset from gstate original target
+ * @dy: device offset from gstate original target
+ *
+ * Return the device offsets in dx, dy for the current group target
+ * from the original target at the top of the gstate chain.
+ **/
+void
+_cairo_gstate_get_target_offsets_from_original (cairo_gstate_t *gstate,
+                                                double *dx,
+                                                double *dy)
+{
+    /* Because the device offsets for the current group target are
+     * always relative to its parent, we have to walk up the gstate
+     * stack to figure out the actual device offsets. */
+
+    double x = 0.0, y = 0.0;
+    double prevx = 0.0, prevy = 0.0;
+    while (gstate) {
+        if (gstate->parent_target) {
+            /* The device offset on a group surface is relative to its
+             * parent; we need to recover the offset to the actual
+             * top-level surface origin.  So we increase the offsets
+             * by the difference between the previous (child) and the
+             * current (parent).  We only check for
+             * gstate->parent_target to catch the actual redirection
+             * levels; we then use the target field in the gstate,
+             * which is the actual group target at that point.*/
+            x += (prevx - gstate->target->device_x_offset);
+            y += (prevy - gstate->target->device_y_offset);
+
+            prevx = gstate->target->device_x_offset;
+            prevy = gstate->target->device_y_offset;
+        }
+        gstate = gstate->next;
+    }
+
+    if (dx)
+        *dx = x;
+    if (dy)
+        *dy = y;
+}
+
 /**
  * _cairo_gstate_get_clip:
  * @gstate: a #cairo_gstate_t
@@ -744,8 +766,24 @@ _cairo_gstate_copy_transformed_pattern (cairo_gstate_t  *gstate,
                                        cairo_pattern_t *original,
                                        cairo_matrix_t  *ctm_inverse)
 {
+    cairo_surface_pattern_t *surface_pattern;
+    cairo_surface_t *surface;
+    cairo_matrix_t offset_matrix;
+
     _cairo_pattern_init_copy (pattern, original);
     _cairo_pattern_transform (pattern, ctm_inverse);
+
+    if (cairo_pattern_get_type (original) == CAIRO_PATTERN_TYPE_SURFACE) {
+        surface_pattern = (cairo_surface_pattern_t *) original;
+        surface = surface_pattern->surface;
+        if (_cairo_surface_has_device_offset_or_scale (surface)) {
+            cairo_matrix_init_translate (&offset_matrix,
+                                         surface->device_x_offset,
+                                         surface->device_y_offset);
+            _cairo_pattern_transform (pattern, &offset_matrix);
+        }
+    }
+
 }
 
 static void
index 108e89b5e9d127f03817a110044bb060a6970d2c..06219464cc1d039f29b7572d0d305d8002486344 100644 (file)
@@ -903,6 +903,7 @@ _cairo_surface_is_image (const cairo_surface_t *surface)
 }
 
 const cairo_surface_backend_t cairo_image_surface_backend = {
+    CAIRO_SURFACE_TYPE_IMAGE,
     _cairo_image_surface_create_similar,
     _cairo_image_surface_finish,
     _cairo_image_surface_acquire_source_image,
index a314150bc11828ba308ca42f6dadcd9e631520b8..f7aeb719c8c8e1f7940abc4a8deb5af84fac15e0 100644 (file)
@@ -201,7 +201,7 @@ _init_pattern_with_snapshot (cairo_pattern_t       *pattern,
 {
     _cairo_pattern_init_copy (pattern, other);
 
-    if (pattern->type == CAIRO_PATTERN_SURFACE) {
+    if (pattern->type == CAIRO_PATTERN_TYPE_SURFACE) {
        cairo_surface_pattern_t *surface_pattern =
            (cairo_surface_pattern_t *) pattern;
        cairo_surface_t *surface = surface_pattern->surface;
@@ -557,6 +557,7 @@ _cairo_surface_is_meta (const cairo_surface_t *surface)
 }
 
 static const cairo_surface_backend_t cairo_meta_surface_backend = {
+    CAIRO_INTERNAL_SURFACE_TYPE_META,
     _cairo_meta_surface_create_similar,
     _cairo_meta_surface_finish,
     _cairo_meta_surface_acquire_source_image,
index a6db091989bcb24f8ee2de85a0ce741fe42cf6e1..6fd61813a43379b0679b18aa24f91df1a0dfd0fb 100644 (file)
@@ -114,6 +114,69 @@ _cairo_output_stream_write_hex_string (cairo_output_stream_t *stream,
     }
 }
 
+static cairo_bool_t
+convert_four_tuple (const unsigned char *four_tuple, char five_tuple[5])
+{
+    cairo_bool_t all_zero;
+    uint32_t value;
+    int digit, i;
+    
+    value = four_tuple[0] << 24 | four_tuple[1] << 16 | four_tuple[2] << 8 | four_tuple[3];
+    all_zero = TRUE;
+    for (i = 0; i < 5; i++) {
+       digit = value % 85;
+       if (digit != 0)
+           all_zero = FALSE;
+       five_tuple[4-i] = digit + 33;
+       value = value / 85;
+    }
+    return all_zero;
+}
+
+void
+_cairo_output_stream_write_base85_string (cairo_output_stream_t *stream,
+                                         const char *data,
+                                         size_t length)
+{
+    unsigned char *ptr;
+    unsigned char four_tuple[4];
+    char five_tuple[5];
+    int column;
+    
+    ptr = (unsigned char *)data;
+    column = 0;
+    while (length > 0) {
+       if (length >= 4) {
+           if (convert_four_tuple (ptr, five_tuple)) {
+               column += 1;
+               _cairo_output_stream_write (stream, "z", 1);
+           } else {
+               column += 5;
+               _cairo_output_stream_write (stream, five_tuple, 5);
+           }
+           length -= 4;
+           ptr += 4;
+       } else { /* length < 4 */
+           memset (four_tuple, 0, 4);
+           memcpy (four_tuple, ptr, length);
+           convert_four_tuple (four_tuple, five_tuple);
+           column += length + 1;
+           _cairo_output_stream_write (stream, five_tuple, length + 1);
+           length = 0;
+       }
+       if (column >= 72) {
+           _cairo_output_stream_write (stream, "\n", 1);
+           column = 0;
+       }
+    }
+
+    if (column > 0) {
+       _cairo_output_stream_write (stream, "\n", 1);
+    }
+}
+
+
+
 /* Format a double in a locale independent way and trim trailing
  * zeros.  Based on code from Alex Larson <alexl@redhat.com>.
  * http://mail.gnome.org/archives/gtk-devel-list/2001-October/msg00087.html
@@ -305,9 +368,11 @@ _cairo_output_stream_create_for_file (const char *filename)
        return NULL;
     
     stream = _cairo_output_stream_create (stdio_write, fp);
-    if (stream == NULL)
+
+    if (stream)
+       stream->owns_closure_is_file = TRUE;
+    else
        fclose (fp);
-    stream->owns_closure_is_file = TRUE;
 
     return stream;
 }
index 2f918293ba465faeca2b8e3f976df7a096f5b350..79438e4abdd3b31144695ecad78af249c7be3eed 100644 (file)
@@ -47,7 +47,7 @@ _cairo_paginated_surface_create (cairo_surface_t      *target,
 cairo_private cairo_surface_t *
 _cairo_paginated_surface_get_target (cairo_surface_t *surface);
 
-cairo_bool_t
+cairo_private cairo_bool_t
 _cairo_surface_is_paginated (cairo_surface_t *surface);
 
 #endif /* CAIRO_PAGINATED_SURFACE_H */
index 6317d708353fd01104d8eb552f72850b4693502c..acfe44ad3a0bb577e93099823b5c25033bdcf720 100644 (file)
@@ -97,6 +97,24 @@ const cairo_private cairo_surface_backend_t cairo_paginated_surface_backend;
 static cairo_int_status_t
 _cairo_paginated_surface_show_page (void *abstract_surface);
 
+/* XXX: This would seem the natural thing to do here. But currently,
+ * PDF and PS surfaces do not yet work as source surfaces. So instead,
+ * we don't implement create_similar for the paginate_surface which
+ * means that any create_similar() call on a paginated_surfacae will
+ * result in a new image surface. */
+#if 0
+static cairo_surface_t *
+_cairo_paginated_surface_create_similar (void                  *abstract_surface,
+                                        cairo_content_t         content,
+                                        int                     width,
+                                        int                     height)
+{
+    cairo_paginated_surface_t *surface = abstract_surface;
+    return cairo_surface_create_similar (surface->target, content,
+                                        width, height);
+}
+#endif
+
 cairo_surface_t *
 _cairo_paginated_surface_create (cairo_surface_t       *target,
                                 cairo_content_t         content,
@@ -111,6 +129,10 @@ _cairo_paginated_surface_create (cairo_surface_t   *target,
 
     _cairo_surface_init (&surface->base, &cairo_paginated_surface_backend);
 
+    /* Override surface->base.type with target's type so we don't leak
+     * evidence of the paginated wrapper out to the user. */
+    surface->base.type = cairo_surface_get_type (target);
+
     surface->content = content;
     surface->width = width;
     surface->height = height;
@@ -381,7 +403,8 @@ _cairo_paginated_surface_snapshot (void *abstract_other)
 }
 
 const cairo_surface_backend_t cairo_paginated_surface_backend = {
-    NULL, /* create_similar */
+    CAIRO_INTERNAL_SURFACE_TYPE_PAGINATED,
+    NULL, /* create_similar --- see note for _cairo_paginated_surface_create_similar */
     _cairo_paginated_surface_finish,
     _cairo_paginated_surface_acquire_source_image,
     _cairo_paginated_surface_release_source_image,
index 35c76b89e1a6964781c6375badd2d0e90b6ba6dd..6c227f39408372f9acdb91097f07d916f4268604 100644 (file)
@@ -549,12 +549,12 @@ _cairo_path_fixed_interpret (cairo_path_fixed_t                   *path,
     return CAIRO_STATUS_SUCCESS;
 }
 
-void
+static void
 _cairo_path_fixed_offset_and_scale (cairo_path_fixed_t *path,
-                                    cairo_fixed_t offx,
-                                    cairo_fixed_t offy,
-                                    cairo_fixed_t scalex,
-                                    cairo_fixed_t scaley)
+                                   cairo_fixed_t offx,
+                                   cairo_fixed_t offy,
+                                   cairo_fixed_t scalex,
+                                   cairo_fixed_t scaley)
 {
     cairo_path_arg_buf_t *arg_buf = path->arg_buf_head;
     int i;
@@ -563,8 +563,7 @@ _cairo_path_fixed_offset_and_scale (cairo_path_fixed_t *path,
 
     while (arg_buf) {
         for (i = 0; i < arg_buf->num_points; i++) {
-            /* CAIRO_FIXED_ONE? */
-            if (scalex == 0x00010000) {
+            if (scalex == CAIRO_FIXED_ONE) {
                 arg_buf->points[i].x += offx;
             } else {
                 fixedtemp = arg_buf->points[i].x + offx;
@@ -572,7 +571,7 @@ _cairo_path_fixed_offset_and_scale (cairo_path_fixed_t *path,
                 arg_buf->points[i].x = _cairo_int64_to_int32(_cairo_int64_rsl (i64temp, 16));
             }
 
-            if (scaley == 0x00010000) {
+            if (scaley == CAIRO_FIXED_ONE) {
                 arg_buf->points[i].y += offy;
             } else {
                 fixedtemp = arg_buf->points[i].y + offy;
@@ -585,3 +584,13 @@ _cairo_path_fixed_offset_and_scale (cairo_path_fixed_t *path,
     }
 }
 
+void
+_cairo_path_fixed_offset (cairo_path_fixed_t *path,
+                         cairo_fixed_t offx,
+                         cairo_fixed_t offy)
+{
+    _cairo_path_fixed_offset_and_scale (path, offx, offy,
+                                       CAIRO_FIXED_ONE,
+                                       CAIRO_FIXED_ONE);
+}
+
index d7b73693b2f5bb92310143af6b4ec9f778eaec22..8aa2969884d9437b537bcea863ec8cc349df1719 100644 (file)
@@ -30,7 +30,7 @@
 #include "cairoint.h"
 
 const cairo_solid_pattern_t cairo_pattern_nil = {
-    { CAIRO_PATTERN_SOLID,     /* type */
+    { CAIRO_PATTERN_TYPE_SOLID,        /* type */
       (unsigned int)-1,                /* ref_count */
       CAIRO_STATUS_NO_MEMORY,  /* status */
       { 1., 0., 0., 1., 0., 0., }, /* matrix */
@@ -39,7 +39,7 @@ const cairo_solid_pattern_t cairo_pattern_nil = {
 };
 
 static const cairo_solid_pattern_t cairo_pattern_nil_null_pointer = {
-    { CAIRO_PATTERN_SOLID,     /* type */
+    { CAIRO_PATTERN_TYPE_SOLID,        /* type */
       (unsigned int)-1,                /* ref_count */
       CAIRO_STATUS_NULL_POINTER,/* status */
       { 1., 0., 0., 1., 0., 0., }, /* matrix */
@@ -48,7 +48,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_SOLID,     /* type */
+    { CAIRO_PATTERN_TYPE_SOLID,        /* type */
       (unsigned int)-1,                /* ref_count */
       CAIRO_STATUS_FILE_NOT_FOUND, /* status */
       { 1., 0., 0., 1., 0., 0., }, /* matrix */
@@ -57,7 +57,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_SOLID,     /* type */
+    { CAIRO_PATTERN_TYPE_SOLID,        /* type */
       (unsigned int)-1,                /* ref_count */
       CAIRO_STATUS_READ_ERROR, /* status */
       { 1., 0., 0., 1., 0., 0., }, /* matrix */
@@ -117,7 +117,7 @@ _cairo_pattern_init (cairo_pattern_t *pattern, cairo_pattern_type_t type)
     pattern->ref_count = 1;
     pattern->status    = CAIRO_STATUS_SUCCESS;
 
-    if (type == CAIRO_PATTERN_SURFACE)
+    if (type == CAIRO_PATTERN_TYPE_SURFACE)
        pattern->extend = CAIRO_EXTEND_SURFACE_DEFAULT;
     else
        pattern->extend = CAIRO_EXTEND_GRADIENT_DEFAULT;
@@ -131,7 +131,7 @@ static void
 _cairo_gradient_pattern_init_copy (cairo_gradient_pattern_t      *pattern,
                                   const cairo_gradient_pattern_t *other)
 {
-    if (other->base.type == CAIRO_PATTERN_LINEAR)
+    if (other->base.type == CAIRO_PATTERN_TYPE_LINEAR)
     {
        cairo_linear_pattern_t *dst = (cairo_linear_pattern_t *) pattern;
        cairo_linear_pattern_t *src = (cairo_linear_pattern_t *) other;
@@ -170,21 +170,21 @@ _cairo_pattern_init_copy (cairo_pattern_t *pattern,
     }
 
     switch (other->type) {
-    case CAIRO_PATTERN_SOLID: {
+    case CAIRO_PATTERN_TYPE_SOLID: {
        cairo_solid_pattern_t *dst = (cairo_solid_pattern_t *) pattern;
        cairo_solid_pattern_t *src = (cairo_solid_pattern_t *) other;
 
        *dst = *src;
     } break;
-    case CAIRO_PATTERN_SURFACE: {
+    case CAIRO_PATTERN_TYPE_SURFACE: {
        cairo_surface_pattern_t *dst = (cairo_surface_pattern_t *) pattern;
        cairo_surface_pattern_t *src = (cairo_surface_pattern_t *) other;
        
        *dst = *src;
        cairo_surface_reference (dst->surface);
     } break;
-    case CAIRO_PATTERN_LINEAR:
-    case CAIRO_PATTERN_RADIAL: {
+    case CAIRO_PATTERN_TYPE_LINEAR:
+    case CAIRO_PATTERN_TYPE_RADIAL: {
        cairo_gradient_pattern_t *dst = (cairo_gradient_pattern_t *) pattern;
        cairo_gradient_pattern_t *src = (cairo_gradient_pattern_t *) other;
        
@@ -199,16 +199,16 @@ void
 _cairo_pattern_fini (cairo_pattern_t *pattern)
 {
     switch (pattern->type) {
-    case CAIRO_PATTERN_SOLID:
+    case CAIRO_PATTERN_TYPE_SOLID:
        break;
-    case CAIRO_PATTERN_SURFACE: {
+    case CAIRO_PATTERN_TYPE_SURFACE: {
        cairo_surface_pattern_t *surface_pattern =
            (cairo_surface_pattern_t *) pattern;
        
        cairo_surface_destroy (surface_pattern->surface);
     } break;
-    case CAIRO_PATTERN_LINEAR:
-    case CAIRO_PATTERN_RADIAL: {
+    case CAIRO_PATTERN_TYPE_LINEAR:
+    case CAIRO_PATTERN_TYPE_RADIAL: {
        cairo_gradient_pattern_t *gradient =
            (cairo_gradient_pattern_t *) pattern;
        
@@ -222,7 +222,7 @@ void
 _cairo_pattern_init_solid (cairo_solid_pattern_t *pattern,
                           const cairo_color_t   *color)
 {
-    _cairo_pattern_init (&pattern->base, CAIRO_PATTERN_SOLID);
+    _cairo_pattern_init (&pattern->base, CAIRO_PATTERN_TYPE_SOLID);
     pattern->color = *color;
 }
 
@@ -232,12 +232,12 @@ _cairo_pattern_init_for_surface (cairo_surface_pattern_t *pattern,
 {
     if (surface->status) {
        /* Force to solid to simplify the pattern_fini process. */
-       pattern->base.type = CAIRO_PATTERN_SOLID;
+       pattern->base.type = CAIRO_PATTERN_TYPE_SOLID;
        _cairo_pattern_set_error (&pattern->base, surface->status);
        return;
     }
 
-    _cairo_pattern_init (&pattern->base, CAIRO_PATTERN_SURFACE);
+    _cairo_pattern_init (&pattern->base, CAIRO_PATTERN_TYPE_SURFACE);
     
     pattern->surface = cairo_surface_reference (surface);
 }
@@ -256,7 +256,7 @@ void
 _cairo_pattern_init_linear (cairo_linear_pattern_t *pattern,
                            double x0, double y0, double x1, double y1)
 {
-    _cairo_pattern_init_gradient (&pattern->base, CAIRO_PATTERN_LINEAR);
+    _cairo_pattern_init_gradient (&pattern->base, CAIRO_PATTERN_TYPE_LINEAR);
 
     pattern->gradient.p1.x = _cairo_fixed_from_double (x0);
     pattern->gradient.p1.y = _cairo_fixed_from_double (y0);
@@ -269,7 +269,7 @@ _cairo_pattern_init_radial (cairo_radial_pattern_t *pattern,
                            double cx0, double cy0, double radius0,
                            double cx1, double cy1, double radius1)
 {
-    _cairo_pattern_init_gradient (&pattern->base, CAIRO_PATTERN_RADIAL);
+    _cairo_pattern_init_gradient (&pattern->base, CAIRO_PATTERN_TYPE_RADIAL);
 
     pattern->gradient.inner.x     = _cairo_fixed_from_double (cx0);
     pattern->gradient.inner.y     = _cairo_fixed_from_double (cy0);
@@ -524,6 +524,18 @@ cairo_pattern_reference (cairo_pattern_t *pattern)
     return pattern;
 }
 
+/**
+ * cairo_pattern_get_type:
+ * @pattern: a #cairo_pattern_t
+ * 
+ * Return value: The type of @pattern. See #cairo_pattern_type_t.
+ **/
+cairo_pattern_type_t
+cairo_pattern_get_type (cairo_pattern_t *pattern)
+{
+    return pattern->type;
+}
+
 /**
  * cairo_pattern_status:
  * @pattern: a #cairo_pattern_t
@@ -641,8 +653,8 @@ cairo_pattern_add_color_stop_rgb (cairo_pattern_t *pattern,
     if (pattern->status)
        return;
 
-    if (pattern->type != CAIRO_PATTERN_LINEAR &&
-       pattern->type != CAIRO_PATTERN_RADIAL)
+    if (pattern->type != CAIRO_PATTERN_TYPE_LINEAR &&
+       pattern->type != CAIRO_PATTERN_TYPE_RADIAL)
     {
        _cairo_pattern_set_error (pattern, CAIRO_STATUS_PATTERN_TYPE_MISMATCH);
        return;
@@ -689,8 +701,8 @@ cairo_pattern_add_color_stop_rgba (cairo_pattern_t *pattern,
     if (pattern->status)
        return;
 
-    if (pattern->type != CAIRO_PATTERN_LINEAR &&
-       pattern->type != CAIRO_PATTERN_RADIAL)
+    if (pattern->type != CAIRO_PATTERN_TYPE_LINEAR &&
+       pattern->type != CAIRO_PATTERN_TYPE_RADIAL)
     {
        _cairo_pattern_set_error (pattern, CAIRO_STATUS_PATTERN_TYPE_MISMATCH);
        return;
@@ -894,7 +906,7 @@ _cairo_pattern_acquire_surface_for_gradient (cairo_gradient_pattern_t *pattern,
     cairo_status_t       status;
     cairo_bool_t         repeat = FALSE;
 
-    if (pattern->base.type == CAIRO_PATTERN_LINEAR)
+    if (pattern->base.type == CAIRO_PATTERN_TYPE_LINEAR)
     {
        cairo_linear_pattern_t *linear = (cairo_linear_pattern_t *) pattern;
 
@@ -936,7 +948,7 @@ _cairo_pattern_acquire_surface_for_gradient (cairo_gradient_pattern_t *pattern,
        return CAIRO_STATUS_SUCCESS;
     }
 
-    if (pattern->base.type == CAIRO_PATTERN_LINEAR) {
+    if (pattern->base.type == CAIRO_PATTERN_TYPE_LINEAR) {
        cairo_bool_t is_horizontal;
        cairo_bool_t is_vertical;
 
@@ -1055,7 +1067,7 @@ _cairo_pattern_is_opaque_solid (cairo_pattern_t *pattern)
 {
     cairo_solid_pattern_t *solid;
 
-    if (pattern->type != CAIRO_PATTERN_SOLID)
+    if (pattern->type != CAIRO_PATTERN_TYPE_SOLID)
        return FALSE;
 
     solid = (cairo_solid_pattern_t *) pattern;
@@ -1151,7 +1163,7 @@ _cairo_pattern_acquire_surface (cairo_pattern_t              *pattern,
     }
 
     switch (pattern->type) {
-    case CAIRO_PATTERN_SOLID: {
+    case CAIRO_PATTERN_TYPE_SOLID: {
        cairo_solid_pattern_t *src = (cairo_solid_pattern_t *) pattern;
        
        status = _cairo_pattern_acquire_surface_for_solid (src, dst,
@@ -1159,8 +1171,8 @@ _cairo_pattern_acquire_surface (cairo_pattern_t              *pattern,
                                                           surface_out,
                                                           attributes);
        } break;
-    case CAIRO_PATTERN_LINEAR:
-    case CAIRO_PATTERN_RADIAL: {
+    case CAIRO_PATTERN_TYPE_LINEAR:
+    case CAIRO_PATTERN_TYPE_RADIAL: {
        cairo_gradient_pattern_t *src = (cairo_gradient_pattern_t *) pattern;
 
        /* fast path for gradients with less than 2 color stops */
@@ -1203,7 +1215,7 @@ _cairo_pattern_acquire_surface (cairo_pattern_t              *pattern,
                                                                  attributes);
        }
     } break;
-    case CAIRO_PATTERN_SURFACE: {
+    case CAIRO_PATTERN_TYPE_SURFACE: {
        cairo_surface_pattern_t *src = (cairo_surface_pattern_t *) pattern;
        
        status = _cairo_pattern_acquire_surface_for_surface (src, dst,
@@ -1235,7 +1247,7 @@ _cairo_pattern_release_surface (cairo_pattern_t              *pattern,
     {
        cairo_surface_pattern_t *surface_pattern;
 
-       assert (pattern->type == CAIRO_PATTERN_SURFACE);
+       assert (pattern->type == CAIRO_PATTERN_TYPE_SURFACE);
        surface_pattern = (cairo_surface_pattern_t *) pattern;
 
        _cairo_surface_release_source_image (surface_pattern->surface,
@@ -1277,8 +1289,8 @@ _cairo_pattern_acquire_surfaces (cairo_pattern_t      *src,
     /* XXX: This optimization assumes that there is no color
      * information in mask, so this will need to change when we
      * support RENDER-style 4-channel masks. */
-    if (src->type == CAIRO_PATTERN_SOLID &&
-       mask && mask->type == CAIRO_PATTERN_SOLID)
+    if (src->type == CAIRO_PATTERN_TYPE_SOLID &&
+       mask && mask->type == CAIRO_PATTERN_TYPE_SOLID)
     {
        cairo_color_t combined;
        cairo_solid_pattern_t *src_solid = (cairo_solid_pattern_t *) src;
@@ -1346,7 +1358,7 @@ _cairo_pattern_get_extents (cairo_pattern_t       *pattern,
                            cairo_rectangle_t   *extents)
 {
     if (pattern->extend == CAIRO_EXTEND_NONE &&
-       pattern->type == CAIRO_PATTERN_SURFACE)
+       pattern->type == CAIRO_PATTERN_TYPE_SURFACE)
     {
        cairo_status_t status;
        cairo_rectangle_t surface_extents;
index ee5c482cf424f0785e325bc9acf08a3152500416..6d18196b59561dac995f1f1fa3898bafaed24bb2 100644 (file)
@@ -654,8 +654,10 @@ emit_image_rgb_data (cairo_pdf_document_t *document,
        opaque = cairo_image_surface_create (CAIRO_FORMAT_RGB24,
                                             image->width,
                                             image->height);
-       if (opaque->status)
+       if (opaque->status) {
+           free (rgb);
            return 0;
+       }
     
        _cairo_pattern_init_for_surface (&pattern.surface, &image->base);
     
@@ -841,7 +843,7 @@ _cairo_pdf_surface_composite (cairo_operator_t      op,
     if (mask_pattern)
        return CAIRO_STATUS_SUCCESS;
     
-    if (src_pattern->type != CAIRO_PATTERN_SURFACE)
+    if (src_pattern->type != CAIRO_PATTERN_TYPE_SURFACE)
        return CAIRO_STATUS_SUCCESS;
 
     if (src->surface->backend == &cairo_pdf_surface_backend)
@@ -1237,16 +1239,16 @@ static cairo_status_t
 emit_pattern (cairo_pdf_surface_t *surface, cairo_pattern_t *pattern)
 {
     switch (pattern->type) {
-    case CAIRO_PATTERN_SOLID:  
+    case CAIRO_PATTERN_TYPE_SOLID:
        return emit_solid_pattern (surface, (cairo_solid_pattern_t *) pattern);
 
-    case CAIRO_PATTERN_SURFACE:
+    case CAIRO_PATTERN_TYPE_SURFACE:
        return emit_surface_pattern (surface, (cairo_surface_pattern_t *) pattern);
 
-    case CAIRO_PATTERN_LINEAR:
+    case CAIRO_PATTERN_TYPE_LINEAR:
        return emit_linear_pattern (surface, (cairo_linear_pattern_t *) pattern);
 
-    case CAIRO_PATTERN_RADIAL:
+    case CAIRO_PATTERN_TYPE_RADIAL:
        return emit_radial_pattern (surface, (cairo_radial_pattern_t *) pattern);
     }
 
@@ -1657,6 +1659,7 @@ _cairo_pdf_surface_get_font_options (void                  *abstract_surface,
 }
 
 static const cairo_surface_backend_t cairo_pdf_surface_backend = {
+    CAIRO_SURFACE_TYPE_PDF,
     _cairo_pdf_surface_create_similar,
     _cairo_pdf_surface_finish,
     NULL, /* acquire_source_image */
index c07066d93408e752e5a666bdb6035e62f3fc86cd..4d75e9027a3d786e0a3eaf145a96cbe50aa1dc89 100644 (file)
 #ifndef CAIRO_PLATFORM_H
 #define CAIRO_PLATFORM_H
 
-#if defined(_MSC_VER)
+#if defined(MOZ_ENABLE_LIBXUL)
+
+#ifdef HAVE_VISIBILITY_HIDDEN_ATTRIBUTE
+#define CVISIBILITY_HIDDEN __attribute__((visibility("hidden")))
+#else
+#define CVISIBILITY_HIDDEN
+#endif
+
+// In libxul builds we don't ever want to export cairo symbols
+#define cairo_public extern CVISIBILITY_HIDDEN
+#define CCALLBACK
+#define CCALLBACK_DECL
+#define CSTATIC_CALLBACK(__x) static __x
+
+#elif defined(XP_WIN)
 
 #define cairo_public extern __declspec(dllexport)
 #define CCALLBACK
@@ -67,7 +81,7 @@
 
 #else /* Unix */
 
-#ifdef HAVE_VISIBILITY_PRAGMA
+#ifdef HAVE_VISIBILITY_ATTRIBUTE
 #define CVISIBILITY_DEFAULT __attribute__((visibility("default")))
 #else
 #define CVISIBILITY_DEFAULT
@@ -80,5 +94,8 @@
 
 #endif
 
+#ifdef MOZILLA_VERSION
+#include "cairo-rename.h"
+#endif
 
 #endif /* CAIRO_PLATFORM_H */
index 6cf8621706b35c74cfb8b0cc9126119513a556a7..e5ebc9e17ccf8a98126b8a9eb33ba187adce316d 100644 (file)
@@ -50,8 +50,6 @@
  *
  * - Add document structure convention comments where appropriate.
  *
- * - Fix image compression.
- *
  * - Create a set of procs to use... specifically a trapezoid proc.
  */
 
@@ -101,11 +99,9 @@ _cairo_ps_surface_emit_header (cairo_ps_surface_t *surface)
                                 surface->width,
                                 surface->height);
 
-    /* The "/FlateDecode filter" currently used is a feature of
-     * LanguageLevel 3 */
     _cairo_output_stream_printf (surface->stream,
-                                "%%%%DocumentData: Binary\n"
-                                "%%%%LanguageLevel: 3\n"
+                                "%%%%DocumentData: Clean7Bit\n"
+                                "%%%%LanguageLevel: 2\n"
                                 "%%%%Orientation: Portrait\n"
                                 "%%%%EndComments\n");
 }
@@ -141,10 +137,6 @@ _cairo_ps_surface_create_for_stream_internal (cairo_output_stream_t *stream,
     surface->height = height;
     surface->x_dpi = PS_SURFACE_DPI_DEFAULT;
     surface->y_dpi = PS_SURFACE_DPI_DEFAULT;
-#if DONE_ADDING_DEVICE_SCALE_SUPPORT_AFTER_SWITCHING_TO_PAGINATED
-    surface->base.device_x_scale = surface->x_dpi / 72.0;
-    surface->base.device_y_scale = surface->y_dpi / 72.0;
-#endif
 
     surface->need_start_page = TRUE;
     surface->num_pages = 0;
@@ -275,11 +267,6 @@ cairo_ps_surface_set_dpi (cairo_surface_t *surface,
 
     ps_surface->x_dpi = x_dpi;    
     ps_surface->y_dpi = y_dpi;
-
-#if DONE_ADDING_DEVICE_SCALE_SUPPORT_AFTER_SWITCHING_TO_PAGINATED
-    ps_surface->base.device_x_scale = ps_surface->x_dpi / 72.0;
-    ps_surface->base.device_y_scale = ps_surface->y_dpi / 72.0;
-#endif
 }
 
 /* XXX */
@@ -318,8 +305,7 @@ _cairo_ps_surface_start_page (cairo_ps_surface_t *surface)
     _cairo_output_stream_printf (surface->stream,
                                 "gsave %f %f translate %f %f scale \n",
                                 0.0, surface->height,
-                                1.0/surface->base.device_x_scale,
-                                -1.0/surface->base.device_y_scale);
+                                1.0, -1.0);
 
     surface->need_start_page = FALSE;
 }
@@ -546,12 +532,12 @@ pattern_is_translucent (const cairo_pattern_t *abstract_pattern)
 
     pattern = (cairo_pattern_union_t *) abstract_pattern;
     switch (pattern->base.type) {
-    case CAIRO_PATTERN_SOLID:
+    case CAIRO_PATTERN_TYPE_SOLID:
        return color_is_translucent (&pattern->solid.color);
-    case CAIRO_PATTERN_SURFACE:
+    case CAIRO_PATTERN_TYPE_SURFACE:
        return surface_is_translucent (pattern->surface.surface);
-    case CAIRO_PATTERN_LINEAR:
-    case CAIRO_PATTERN_RADIAL:
+    case CAIRO_PATTERN_TYPE_LINEAR:
+    case CAIRO_PATTERN_TYPE_RADIAL:
        return gradient_is_translucent (&pattern->gradient.base);
     }  
 
@@ -637,7 +623,7 @@ color_operation_needs_fallback (cairo_operator_t op,
 static cairo_bool_t
 pattern_type_supported (const cairo_pattern_t *pattern)
 {
-    if (pattern->type == CAIRO_PATTERN_SOLID)
+    if (pattern->type == CAIRO_PATTERN_TYPE_SOLID)
        return TRUE;
     return FALSE;
 }
@@ -658,23 +644,6 @@ pattern_operation_needs_fallback (cairo_operator_t op,
 /* PS Output - this section handles output of the parts of the meta
  * surface we can render natively in PS. */
 
-static void *
-compress_dup (const void *data, unsigned long data_size,
-             unsigned long *compressed_size)
-{
-    void *compressed;
-
-    /* Bound calculation taken from zlib. */
-    *compressed_size = data_size + (data_size >> 12) + (data_size >> 14) + 11;
-    compressed = malloc (*compressed_size);
-    if (compressed == NULL)
-       return NULL;
-
-    compress (compressed, compressed_size, data, data_size);
-
-    return compressed;
-}
-
 static cairo_status_t
 emit_image (cairo_ps_surface_t    *surface,
            cairo_image_surface_t *image,
@@ -745,7 +714,7 @@ emit_image (cairo_ps_surface_t    *surface,
        }
     }
 
-    compressed = compress_dup (rgb, rgb_size, &compressed_size);
+    compressed = _cairo_compress_lzw (rgb, rgb_size, &compressed_size);
     if (compressed == NULL) {
        status = CAIRO_STATUS_NO_MEMORY;
        goto bail2;
@@ -765,7 +734,7 @@ emit_image (cairo_ps_surface_t    *surface,
                                 "      /Height %d\n"
                                 "      /BitsPerComponent 8\n"
                                 "      /Decode [ 0 1 0 1 0 1 ]\n"
-                                "      /DataSource currentfile\n"
+                                "      /DataSource currentfile /ASCII85Decode filter /LZWDecode filter \n"
                                 "      /ImageMatrix [ %f %f %f %f %f %f ]\n"
                                 ">>\n"
                                 "image\n",
@@ -775,13 +744,13 @@ emit_image (cairo_ps_surface_t    *surface,
                                 d2i.xy, d2i.yy,
                                 d2i.x0, d2i.y0);
 
-    /* Compressed image data */
-    _cairo_output_stream_write (surface->stream, rgb, rgb_size);
+    /* Compressed image data (Base85 encoded) */
+    _cairo_output_stream_write_base85_string (surface->stream, (char *)compressed, compressed_size);
     status = CAIRO_STATUS_SUCCESS;
 
+    /* Mark end of base85 data */
     _cairo_output_stream_printf (surface->stream,
-                                "\n");
-
+                                "~>\n");
     free (compressed);
  bail2:
     free (rgb);
@@ -837,19 +806,19 @@ emit_pattern (cairo_ps_surface_t *surface, cairo_pattern_t *pattern)
      * different pattern. */
 
     switch (pattern->type) {
-    case CAIRO_PATTERN_SOLID:  
+    case CAIRO_PATTERN_TYPE_SOLID:     
        emit_solid_pattern (surface, (cairo_solid_pattern_t *) pattern);
        break;
 
-    case CAIRO_PATTERN_SURFACE:
+    case CAIRO_PATTERN_TYPE_SURFACE:
        emit_surface_pattern (surface, (cairo_surface_pattern_t *) pattern);
        break;
 
-    case CAIRO_PATTERN_LINEAR:
+    case CAIRO_PATTERN_TYPE_LINEAR:
        emit_linear_pattern (surface, (cairo_linear_pattern_t *) pattern);
        break;
 
-    case CAIRO_PATTERN_RADIAL:
+    case CAIRO_PATTERN_TYPE_RADIAL:
        emit_radial_pattern (surface, (cairo_radial_pattern_t *) pattern);
        break;      
     }
@@ -890,12 +859,12 @@ _cairo_ps_surface_composite (cairo_operator_t     op,
 
     status = CAIRO_STATUS_SUCCESS;
     switch (src_pattern->type) {
-    case CAIRO_PATTERN_SOLID:
+    case CAIRO_PATTERN_TYPE_SOLID:
        _cairo_output_stream_printf (stream,
                                     "%% _cairo_ps_surface_composite: solid\n");
        goto bail;
 
-    case CAIRO_PATTERN_SURFACE:
+    case CAIRO_PATTERN_TYPE_SURFACE:
        surface_pattern = (cairo_surface_pattern_t *) src_pattern;
 
        if (src_pattern->extend != CAIRO_EXTEND_NONE) {
@@ -920,8 +889,8 @@ _cairo_ps_surface_composite (cairo_operator_t       op,
                                             image, image_extra);
        break;
 
-    case CAIRO_PATTERN_LINEAR:
-    case CAIRO_PATTERN_RADIAL:
+    case CAIRO_PATTERN_TYPE_LINEAR:
+    case CAIRO_PATTERN_TYPE_RADIAL:
        _cairo_output_stream_printf (stream,
                                     "%% _cairo_ps_surface_composite: gradient\n");
        goto bail;
@@ -1322,6 +1291,7 @@ _cairo_ps_surface_fill (void                      *abstract_surface,
 }
 
 static const cairo_surface_backend_t cairo_ps_surface_backend = {
+    CAIRO_SURFACE_TYPE_PS,
     NULL, /* create_similar */
     _cairo_ps_surface_finish,
     NULL, /* acquire_source_image */
index d7defc98e6209db6c436481d6df64239bc4b5891..5bf01bb12da4e51c167f6fc52f926edb39474c03 100644 (file)
@@ -73,10 +73,11 @@ _cairo_quartz_surface_acquire_source_image(void *abstract_surface,
     UInt32 imageDataSize, rowBytes;
     CGDataProviderRef dataProvider;
 
-    // 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. 
+    /* 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);
 
@@ -216,6 +217,7 @@ _cairo_quartz_surface_get_extents (void *abstract_surface,
 }
 
 static const struct _cairo_surface_backend cairo_quartz_surface_backend = {
+    CAIRO_SURFACE_TYPE_QUARTZ,
     NULL, /* create_similar */
     _cairo_quartz_surface_finish,
     _cairo_quartz_surface_acquire_source_image,
@@ -257,7 +259,7 @@ cairo_surface_t *cairo_quartz_surface_create(CGContextRef context,
        surface->clip_region = NULL;
     surface->flipped = flipped;
 
-    // Set up the image surface which Cairo draws into and we blit to & from.
+    /* 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);
 
index 22042197b6860135a6d63a2315cd0ac7baa766ed..5bf67f021049614342c094f5b6021366b33e70af 100644 (file)
@@ -360,8 +360,8 @@ _cairo_quartzgl_cairo_gradient_pattern_to_quartz (cairo_pattern_t *abspat)
     cairo_matrix_t mat;
     double x0, y0;
 
-    if (abspat->type != CAIRO_PATTERN_LINEAR &&
-       abspat->type != CAIRO_PATTERN_RADIAL)
+    if (abspat->type != CAIRO_PATTERN_TYPE_LINEAR &&
+       abspat->type != CAIRO_PATTERN_TYPE_RADIAL)
        return NULL;
 
     /* We can only do this if we have an identity pattern matrix;
@@ -376,7 +376,7 @@ _cairo_quartzgl_cairo_gradient_pattern_to_quartz (cairo_pattern_t *abspat)
     x0 = mat.x0;
     y0 = mat.y0;
 
-    if (abspat->type == CAIRO_PATTERN_LINEAR) {
+    if (abspat->type == CAIRO_PATTERN_TYPE_LINEAR) {
        cairo_linear_pattern_t *lpat = (cairo_linear_pattern_t*) abspat;
        CGShadingRef shading;
        CGPoint start, end;
@@ -400,7 +400,7 @@ _cairo_quartzgl_cairo_gradient_pattern_to_quartz (cairo_pattern_t *abspat)
        return shading;
     }
 
-    if (abspat->type == CAIRO_PATTERN_RADIAL) {
+    if (abspat->type == CAIRO_PATTERN_TYPE_RADIAL) {
        cairo_radial_pattern_t *rpat = (cairo_radial_pattern_t*) abspat;
        CGShadingRef shading;
        CGPoint start, end;
@@ -517,7 +517,7 @@ _cairo_quartzgl_cairo_repeating_surface_pattern_to_quartz (cairo_quartzgl_surfac
     float rw, rh;
 
     /* SURFACE is the only type we'll handle here */
-    if (abspat->type != CAIRO_PATTERN_SURFACE)
+    if (abspat->type != CAIRO_PATTERN_TYPE_SURFACE)
        return NULL;
 
     spat = (cairo_surface_pattern_t *) abspat;
@@ -596,7 +596,7 @@ _cairo_quartzgl_setup_source (cairo_quartzgl_surface_t *surface,
 {
     assert (!(surface->sourceImage || surface->sourceShading || surface->sourcePattern));
 
-    if (source->type == CAIRO_PATTERN_SOLID) {
+    if (source->type == CAIRO_PATTERN_TYPE_SOLID) {
        cairo_solid_pattern_t *solid = (cairo_solid_pattern_t *) source;
 
        CGContextSetRGBStrokeColor (surface->cgContext,
@@ -609,15 +609,15 @@ _cairo_quartzgl_setup_source (cairo_quartzgl_surface_t *surface,
                                  solid->color.green,
                                  solid->color.blue,
                                  solid->color.alpha);
-    } else if (source->type == CAIRO_PATTERN_LINEAR ||
-              source->type == CAIRO_PATTERN_RADIAL)
+    } else if (source->type == CAIRO_PATTERN_TYPE_LINEAR ||
+              source->type == CAIRO_PATTERN_TYPE_RADIAL)
     {
        CGShadingRef shading = _cairo_quartzgl_cairo_gradient_pattern_to_quartz (source);
        if (!shading)
            return CAIRO_INT_STATUS_UNSUPPORTED;
 
        surface->sourceShading = shading;
-    } else if (source->type == CAIRO_PATTERN_SURFACE) {
+    } else if (source->type == CAIRO_PATTERN_TYPE_SURFACE) {
        CGPatternRef pattern = _cairo_quartzgl_cairo_repeating_surface_pattern_to_quartz (surface, source);
        if (!pattern)
            return CAIRO_INT_STATUS_UNSUPPORTED;
@@ -1413,6 +1413,7 @@ _cairo_quartzgl_surface_intersect_clip_path (void *abstract_surface,
 }
 
 static const struct _cairo_surface_backend cairo_quartzgl_surface_backend = {
+    CAIRO_SURFACE_TYPE_QUARTZ2,
     _cairo_quartzgl_surface_create_similar,
     _cairo_quartzgl_surface_finish,
     _cairo_quartzgl_surface_acquire_source_image,
index 3b0af1d21f409d7011ff36e8d251297b69652699..f87e92bb87f7e5a090efc7feacf0f2dce12dbb0f 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: cairo-scaled-font.c,v 1.4 2006/02/03 04:49:23 vladimir%pobox.com Exp $
+/* $Id: cairo-scaled-font.c,v 1.8 2006/04/01 00:36:09 vladimir%pobox.com Exp $
  *
  * Copyright © 2005 Keith Packard
  *
@@ -118,6 +118,18 @@ _cairo_scaled_font_set_error (cairo_scaled_font_t *scaled_font,
     _cairo_error (status);
 }
 
+/**
+ * cairo_scaled_font_get_type:
+ * @scaled_font: a #cairo_scaled_font_t
+ * 
+ * Return value: The type of @scaled_font. See #cairo_font_type_t.
+ **/
+cairo_font_type_t
+cairo_scaled_font_get_type (cairo_scaled_font_t *scaled_font)
+{
+    return scaled_font->backend->type;
+}
+
 /**
  * cairo_scaled_font_status:
  * @scaled_font: a #cairo_scaled_font_t
index fd2170133cc80f4c7404e4f0104c1e690ddef446..a6ae80fdb81ac3f2574ad91897166994ed766ff7 100644 (file)
@@ -214,21 +214,6 @@ _clip_and_composite_combine (cairo_clip_t            *clip,
      */
     _cairo_pattern_init_for_surface (&dst_pattern, dst);
 
-    /* Set a translation on dst_pattern equivalent to the surface
-     * device offset, to make sure it's in the right place when
-     * composited.
-     */
-    if (dst->device_x_offset != 0.0 ||
-        dst->device_y_offset != 0.0 ||
-        dst->device_x_scale != 1.0 ||
-        dst->device_y_scale != 1.0)
-    {
-       cairo_matrix_t txmat;
-        cairo_matrix_init_scale (&txmat, dst->device_x_scale, dst->device_y_scale);
-        cairo_matrix_translate (&txmat, dst->device_x_offset, dst->device_y_offset);
-       cairo_pattern_set_matrix ((cairo_pattern_t*) &dst_pattern, &txmat);
-    }
-
     status = _cairo_surface_composite (CAIRO_OPERATOR_SOURCE,
                                       &dst_pattern.base, NULL, intermediate,
                                       extents->x,     extents->y,
@@ -564,6 +549,9 @@ _clip_and_composite_trapezoids (cairo_pattern_t *src,
                return status;
            
            clear_region = _cairo_region_create_from_rectangle (&extents);
+           if (clear_region == NULL)
+               return CAIRO_STATUS_NO_MEMORY;
+
            status = _cairo_clip_intersect_to_region (clip, clear_region);
            if (status)
                return status;
@@ -591,7 +579,7 @@ _clip_and_composite_trapezoids (cairo_pattern_t *src,
     {
        cairo_surface_t *clip_surface = clip ? clip->surface : NULL;
        
-       if ((src->type == CAIRO_PATTERN_SOLID || op == CAIRO_OPERATOR_CLEAR) &&
+       if ((src->type == CAIRO_PATTERN_TYPE_SOLID || op == CAIRO_OPERATOR_CLEAR) &&
            !clip_surface)
        {
            const cairo_color_t *color;
@@ -1000,8 +988,6 @@ _cairo_surface_fallback_snapshot (cairo_surface_t *surface)
 
     snapshot->device_x_offset = surface->device_x_offset;
     snapshot->device_y_offset = surface->device_y_offset;
-    snapshot->device_x_scale = surface->device_x_scale;
-    snapshot->device_y_scale = surface->device_y_scale;
 
     snapshot->is_snapshot = TRUE;
 
@@ -1141,7 +1127,6 @@ _cairo_surface_fallback_composite_trapezoids (cairo_operator_t            op,
     fallback_state_t state;
     cairo_trapezoid_t *offset_traps = NULL;
     cairo_status_t status;
-    int i;
 
     status = _fallback_init (&state, dst, dst_x, dst_y, width, height);
     if (status) {
index a405dcbee6e4e05dc94e21d9ef7816a02ef394d3..20a80f562ce22939c146f6a5fc1b2b6b8e067645 100644 (file)
@@ -43,6 +43,7 @@
 
 const cairo_surface_t _cairo_surface_nil = {
     &cairo_image_surface_backend,      /* backend */
+    CAIRO_SURFACE_TYPE_IMAGE,
     -1,                                        /* ref_count */
     CAIRO_STATUS_NO_MEMORY,            /* status */
     FALSE,                             /* finished */
@@ -59,6 +60,7 @@ const cairo_surface_t _cairo_surface_nil = {
 
 const cairo_surface_t _cairo_surface_nil_file_not_found = {
     &cairo_image_surface_backend,      /* backend */
+    CAIRO_SURFACE_TYPE_IMAGE,
     -1,                                        /* ref_count */
     CAIRO_STATUS_FILE_NOT_FOUND,       /* status */
     FALSE,                             /* finished */
@@ -75,6 +77,7 @@ const cairo_surface_t _cairo_surface_nil_file_not_found = {
 
 const cairo_surface_t _cairo_surface_nil_read_error = {
     &cairo_image_surface_backend,      /* backend */
+    CAIRO_SURFACE_TYPE_IMAGE,
     -1,                                        /* ref_count */
     CAIRO_STATUS_READ_ERROR,           /* status */
     FALSE,                             /* finished */
@@ -89,21 +92,13 @@ const cairo_surface_t _cairo_surface_nil_read_error = {
     0                                  /* current_clip_serial */
 };
 
-/* N.B.: set_device_offset already transforms the device offsets by the scale
- * before storing in device_[xy]_scale
- */
-
 /* Helper macros for transforming surface coords to backend coords */
-#define BACKEND_X(_surf, _sx)  ((_sx)*((_surf)->device_x_scale)+((_surf)->device_x_offset))
-#define BACKEND_Y(_surf, _sy)  ((_sy)*((_surf)->device_y_scale)+((_surf)->device_y_offset))
-#define BACKEND_X_SIZE(_surf, _sx)  ((_sx)*((_surf)->device_x_scale))
-#define BACKEND_Y_SIZE(_surf, _sy)  ((_sy)*((_surf)->device_y_scale))
+#define SURFACE_TO_BACKEND_X(_surf, _sx)  ((_sx)+((_surf)->device_x_offset))
+#define SURFACE_TO_BACKEND_Y(_surf, _sy)  ((_sy)+((_surf)->device_y_offset))
 
-/* Helper macros for transforming backend coords to surface coords */
-#define SURFACE_X(_surf, _bx)  (((_bx)-((_surf)->device_x_offset))/((_surf)->device_x_scale))
-#define SURFACE_Y(_surf, _by)  (((_by)-((_surf)->device_y_offset))/((_surf)->device_y_scale))
-#define SURFACE_X_SIZE(_surf, _bx)  ((_bx)/((_surf)->device_x_scale))
-#define SURFACE_Y_SIZE(_surf, _by)  ((_by)/((_surf)->device_y_scale))
+static void _cairo_surface_copy_pattern_for_destination (const cairo_pattern_t *pattern,
+                                                         cairo_surface_t *destination,
+                                                         cairo_pattern_t *pattern_out);
 
 /**
  * _cairo_surface_set_error:
@@ -134,6 +129,22 @@ _cairo_surface_set_error (cairo_surface_t *surface,
     _cairo_error (status);
 }
 
+/**
+ * cairo_surface_get_type:
+ * @surface: a #cairo_surface_t
+ * 
+ * Return value: The type of @surface. See #cairo_surface_type_t.
+ **/
+cairo_surface_type_t
+cairo_surface_get_type (cairo_surface_t *surface)
+{
+    /* We don't use surface->backend->type here so that some of the
+     * special "wrapper" surfaces such as cairo_paginated_surface_t
+     * can override surface->type with the type of the "child"
+     * surface. */
+    return surface->type;
+}
+
 /**
  * cairo_surface_status:
  * @surface: a #cairo_surface_t
@@ -157,6 +168,8 @@ _cairo_surface_init (cairo_surface_t                        *surface,
                     const cairo_surface_backend_t      *backend)
 {
     surface->backend = backend;
+    
+    surface->type = backend->type;
 
     surface->ref_count = 1;
     surface->status = CAIRO_STATUS_SUCCESS;
@@ -166,8 +179,6 @@ _cairo_surface_init (cairo_surface_t                        *surface,
 
     surface->device_x_offset = 0.0;
     surface->device_y_offset = 0.0;
-    surface->device_x_scale = 1.0;
-    surface->device_y_scale = 1.0;
 
     surface->clip = NULL;
     surface->next_clip_serial = 0;
@@ -202,7 +213,8 @@ _cairo_surface_create_similar_scratch (cairo_surface_t *other,
  * 
  * 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.
+ * @other unless that is not possible for some reason. The type of the
+ * returned surface may be examined with cairo_surface_get_type().
  * 
  * Return value: a pointer to the newly allocated surface. The caller
  * owns the surface and should call cairo_surface_destroy when done
@@ -540,9 +552,10 @@ cairo_surface_mark_dirty_rectangle (cairo_surface_t *surface,
        return;
     }
 
-    /* Always reset the clip here, to avoid having a SaveDC/RestoreDC around
-     * cairo calls that update the surface clip resulting in a desync between
-     * the cairo clip and the backend clip.
+    /* Always reset the clip here, to avoid having external calls to
+     * clip manipulation functions of the underlying device clip result
+     * in a desync between the cairo clip and the backend clip, due to
+     * the clip caching.
      */
     surface->current_clip_serial = -1;
 
@@ -550,8 +563,8 @@ cairo_surface_mark_dirty_rectangle (cairo_surface_t *surface,
        cairo_status_t status;
        
        status = surface->backend->mark_dirty_rectangle (surface,
-                                                         BACKEND_X(surface, x),
-                                                         BACKEND_Y(surface, y),
+                                                         SURFACE_TO_BACKEND_X(surface, x),
+                                                         SURFACE_TO_BACKEND_Y(surface, y),
                                                         width, height);
        
        if (status)
@@ -592,8 +605,8 @@ cairo_surface_set_device_offset (cairo_surface_t *surface,
        return;
     }
 
-    surface->device_x_offset = x_offset * surface->device_x_scale;
-    surface->device_y_offset = y_offset * surface->device_y_scale;
+    surface->device_x_offset = x_offset;
+    surface->device_y_offset = y_offset;
 }
 
 /**
@@ -615,6 +628,13 @@ cairo_surface_get_device_offset (cairo_surface_t *surface,
     *y_offset = surface->device_y_offset;
 }
 
+cairo_bool_t
+_cairo_surface_has_device_offset_or_scale (cairo_surface_t *surface)
+{
+    return (surface->device_x_offset != 0.0 ||
+           surface->device_y_offset != 0.0);
+}
+
 /**
  * _cairo_surface_acquire_source_image:
  * @surface: a #cairo_surface_t
@@ -699,26 +719,11 @@ _cairo_surface_acquire_dest_image (cairo_surface_t         *surface,
                                   cairo_rectangle_t       *image_rect,
                                   void                   **image_extra)
 {
-    cairo_rectangle_t dev_interest_rect;
-    cairo_status_t status;
-
     assert (!surface->finished);
 
-    if (interest_rect) {
-       dev_interest_rect = *interest_rect;
-        dev_interest_rect.x = BACKEND_X(surface, dev_interest_rect.x);
-        dev_interest_rect.y = BACKEND_Y(surface, dev_interest_rect.y);
-    }
-
-    status = surface->backend->acquire_dest_image (surface,
-                                                  interest_rect ? &dev_interest_rect : NULL,
-                                                  image_out, image_rect, image_extra);
-
-    /* move image_rect back into surface coordinates from backend device coordinates */
-    image_rect->x = SURFACE_X(surface, image_rect->x);
-    image_rect->y = SURFACE_Y(surface, image_rect->y);
-
-    return status;
+    return surface->backend->acquire_dest_image (surface,
+                                                interest_rect,
+                                                image_out, image_rect, image_extra);
 }
 
 /**
@@ -740,22 +745,10 @@ _cairo_surface_release_dest_image (cairo_surface_t        *surface,
                                   cairo_rectangle_t      *image_rect,
                                   void                   *image_extra)
 {
-    cairo_rectangle_t dev_interest_rect;
-
     assert (!surface->finished);
 
-    /* move image_rect into backend device coords (opposite of acquire_dest_image) */
-    image_rect->x = BACKEND_X(surface, image_rect->x);
-    image_rect->y = BACKEND_Y(surface, image_rect->y);
-
-    if (interest_rect) {
-       dev_interest_rect = *interest_rect;
-        dev_interest_rect.x = BACKEND_X(surface, dev_interest_rect.x);
-        dev_interest_rect.y = BACKEND_Y(surface, dev_interest_rect.y);
-    }
-
     if (surface->backend->release_dest_image)
-       surface->backend->release_dest_image (surface, &dev_interest_rect,
+       surface->backend->release_dest_image (surface, interest_rect,
                                              image, image_rect, image_extra);
 }
 
@@ -794,8 +787,6 @@ _cairo_surface_clone_similar (cairo_surface_t  *surface,
     if (status == CAIRO_STATUS_SUCCESS) {
         (*clone_out)->device_x_offset = src->device_x_offset;
         (*clone_out)->device_y_offset = src->device_y_offset;
-        (*clone_out)->device_x_scale = src->device_x_scale;
-        (*clone_out)->device_y_scale = src->device_y_scale;
     }
 
     if (status != CAIRO_INT_STATUS_UNSUPPORTED)
@@ -809,8 +800,6 @@ _cairo_surface_clone_similar (cairo_surface_t  *surface,
     if (status == CAIRO_STATUS_SUCCESS) {
         (*clone_out)->device_x_offset = src->device_x_offset;
         (*clone_out)->device_y_offset = src->device_y_offset;
-        (*clone_out)->device_x_scale = src->device_x_scale;
-        (*clone_out)->device_y_scale = src->device_y_scale;
     }
 
     /* If the above failed point, we could implement a full fallback
@@ -884,29 +873,11 @@ _cairo_surface_composite (cairo_operator_t        op,
        return CAIRO_STATUS_SURFACE_FINISHED;
 
     if (dst->backend->composite) {
-        int backend_src_x = src_x;
-        int backend_src_y = src_y;
-        int backend_mask_x = mask_x;
-        int backend_mask_y = mask_y;
-
-        if (src->type == CAIRO_PATTERN_SURFACE) {
-            cairo_surface_t *src_surface = ((cairo_surface_pattern_t*)src)->surface;
-            backend_src_x = BACKEND_X(src_surface, src_x);
-            backend_src_y = BACKEND_Y(src_surface, src_y);
-        }
-
-        if (mask && mask->type == CAIRO_PATTERN_SURFACE) {
-            cairo_surface_t *mask_surface = ((cairo_surface_pattern_t*)mask)->surface;
-            backend_mask_x = BACKEND_X(mask_surface, mask_x);
-            backend_mask_y = BACKEND_Y(mask_surface, mask_y);
-        }
-
        status = dst->backend->composite (op,
                                          src, mask, dst,
-                                          backend_src_x, backend_src_y,
-                                          backend_mask_x, backend_mask_y,
-                                          BACKEND_X(dst, dst_x),
-                                          BACKEND_Y(dst, dst_y),
+                                          src_x, src_y,
+                                          mask_x, mask_y,
+                                          dst_x, dst_y,
                                          width, height);
        if (status != CAIRO_INT_STATUS_UNSUPPORTED)
            return status;
@@ -1035,8 +1006,6 @@ _cairo_surface_fill_rectangles (cairo_surface_t           *surface,
                                int                     num_rects)
 {
     cairo_int_status_t status;
-    cairo_rectangle_t *dev_rects = NULL;
-    int i;
 
     assert (! surface->is_snapshot);
 
@@ -1050,26 +1019,8 @@ _cairo_surface_fill_rectangles (cairo_surface_t          *surface,
        return CAIRO_STATUS_SUCCESS;
 
     if (surface->backend->fill_rectangles) {
-       if (surface->device_x_offset != 0.0 ||
-           surface->device_y_offset != 0.0 ||
-           surface->device_x_scale != 1.0 ||
-           surface->device_y_scale != 1.0)
-       {
-           dev_rects = malloc(sizeof(cairo_rectangle_t) * num_rects);
-           for (i = 0; i < num_rects; i++) {
-               dev_rects[i].x = BACKEND_X(surface, rects[i].x);
-               dev_rects[i].y = BACKEND_Y(surface, rects[i].y);
-
-               dev_rects[i].width = BACKEND_X_SIZE(surface, rects[i].width);
-               dev_rects[i].height = BACKEND_Y_SIZE(surface, rects[i].height);
-           }
-       }
-
-       status = surface->backend->fill_rectangles (surface,
-                                                   op,
-                                                   color,
-                                                   dev_rects ? dev_rects : rects, num_rects);
-       free (dev_rects);
+       status = surface->backend->fill_rectangles (surface, op, color,
+                                                   rects, num_rects);
        if (status != CAIRO_INT_STATUS_UNSUPPORTED)
            return status;
     }
@@ -1084,16 +1035,24 @@ _cairo_surface_paint (cairo_surface_t   *surface,
                      cairo_pattern_t   *source)
 {
     cairo_status_t status;
+    cairo_pattern_union_t dev_source;
 
     assert (! surface->is_snapshot);
 
+    _cairo_surface_copy_pattern_for_destination (source, surface, &dev_source.base);
+
     if (surface->backend->paint) {
-       status = surface->backend->paint (surface, op, source);
+       status = surface->backend->paint (surface, op, &dev_source.base);
        if (status != CAIRO_INT_STATUS_UNSUPPORTED)
-           return status;
+            goto FINISH;
     }
 
-    return _cairo_surface_fallback_paint (surface, op, source);
+    status = _cairo_surface_fallback_paint (surface, op, &dev_source.base);
+
+FINISH:
+    _cairo_pattern_fini (&dev_source.base);
+
+    return status;
 }
 
 cairo_status_t
@@ -1103,16 +1062,27 @@ _cairo_surface_mask (cairo_surface_t    *surface,
                     cairo_pattern_t    *mask)
 {
     cairo_status_t status;
+    cairo_pattern_union_t dev_source;
+    cairo_pattern_union_t dev_mask;
 
     assert (! surface->is_snapshot);
 
+    _cairo_surface_copy_pattern_for_destination (source, surface, &dev_source.base);
+    _cairo_surface_copy_pattern_for_destination (mask, surface, &dev_mask.base);
+
     if (surface->backend->mask) {
-       status = surface->backend->mask (surface, op, source, mask);
+       status = surface->backend->mask (surface, op, &dev_source.base, &dev_mask.base);
        if (status != CAIRO_INT_STATUS_UNSUPPORTED)
-           return status;
+            goto FINISH;
     }
 
-    return _cairo_surface_fallback_mask (surface, op, source, mask);
+    status = _cairo_surface_fallback_mask (surface, op, &dev_source.base, &dev_mask.base);
+
+FINISH:
+    _cairo_pattern_fini (&dev_source.base);
+    _cairo_pattern_fini (&dev_mask.base);
+    
+    return status;
 }
 
 cairo_status_t
@@ -1126,43 +1096,45 @@ _cairo_surface_stroke (cairo_surface_t          *surface,
                       double                    tolerance,
                       cairo_antialias_t         antialias)
 {
+    cairo_status_t status;
+    cairo_pattern_union_t dev_source;
+    cairo_path_fixed_t *dev_path = path;
+    cairo_path_fixed_t real_dev_path;
+
     assert (! surface->is_snapshot);
 
-    if (surface->backend->stroke) {
-       cairo_status_t status;
-       cairo_path_fixed_t *dev_path = path;
-       cairo_path_fixed_t real_dev_path;
-
-       if (surface->device_x_offset != 0.0 ||
-           surface->device_y_offset != 0.0 ||
-           surface->device_x_scale != 1.0 ||
-           surface->device_y_scale != 1.0)
-        {
-           _cairo_path_fixed_init_copy (&real_dev_path, path);
-           _cairo_path_fixed_offset_and_scale (&real_dev_path,
-                                               _cairo_fixed_from_double (surface->device_x_offset),
-                                               _cairo_fixed_from_double (surface->device_y_offset),
-                                               _cairo_fixed_from_double (surface->device_x_scale),
-                                               _cairo_fixed_from_double (surface->device_y_scale));
-           dev_path = &real_dev_path;
-       }
+    _cairo_surface_copy_pattern_for_destination (source, surface, &dev_source.base);
 
-       status = surface->backend->stroke (surface, op, source,
+    if (_cairo_surface_has_device_offset_or_scale (surface))
+    {
+        _cairo_path_fixed_init_copy (&real_dev_path, path);
+        _cairo_path_fixed_offset (&real_dev_path,
+                                 _cairo_fixed_from_double (surface->device_x_offset),
+                                 _cairo_fixed_from_double (surface->device_y_offset));
+        dev_path = &real_dev_path;
+    }
+
+    if (surface->backend->stroke) {
+       status = surface->backend->stroke (surface, op, &dev_source.base,
                                           dev_path, stroke_style,
                                           ctm, ctm_inverse,
                                           tolerance, antialias);
 
-       if (dev_path == &real_dev_path)
-           _cairo_path_fixed_fini (&real_dev_path);
-
        if (status != CAIRO_INT_STATUS_UNSUPPORTED)
-           return status;
+            goto FINISH;
     }
 
-    return _cairo_surface_fallback_stroke (surface, op, source,
-                                          path, stroke_style,
-                                          ctm, ctm_inverse,
-                                          tolerance, antialias);
+    status = _cairo_surface_fallback_stroke (surface, op, &dev_source.base,
+                                             dev_path, stroke_style,
+                                             ctm, ctm_inverse,
+                                             tolerance, antialias);
+
+FINISH:
+    if (dev_path == &real_dev_path)
+        _cairo_path_fixed_fini (&real_dev_path);
+    _cairo_pattern_fini (&dev_source.base);
+
+    return status;
 }
 
 cairo_status_t
@@ -1175,40 +1147,42 @@ _cairo_surface_fill (cairo_surface_t    *surface,
                     cairo_antialias_t   antialias)
 {
     cairo_status_t status;
+    cairo_pattern_union_t dev_source;
     cairo_path_fixed_t *dev_path = path;
     cairo_path_fixed_t real_dev_path;
 
     assert (! surface->is_snapshot);
 
-    if (surface->backend->fill) {
-        if (surface->device_x_offset != 0.0 ||
-            surface->device_y_offset != 0.0 ||
-            surface->device_x_scale != 1.0 ||
-            surface->device_y_scale != 1.0)
-        {
-            _cairo_path_fixed_init_copy (&real_dev_path, path);
-            _cairo_path_fixed_offset_and_scale (&real_dev_path,
-                                                _cairo_fixed_from_double (surface->device_x_offset),
-                                                _cairo_fixed_from_double (surface->device_y_offset),
-                                                _cairo_fixed_from_double (surface->device_x_scale),
-                                                _cairo_fixed_from_double (surface->device_y_scale));
-            dev_path = &real_dev_path;
-        }
+    _cairo_surface_copy_pattern_for_destination (source, surface, &dev_source.base);
+
+    if (_cairo_surface_has_device_offset_or_scale (surface))
+    {
+        _cairo_path_fixed_init_copy (&real_dev_path, path);
+        _cairo_path_fixed_offset (&real_dev_path,
+                                 _cairo_fixed_from_double (surface->device_x_offset),
+                                 _cairo_fixed_from_double (surface->device_y_offset));
+        dev_path = &real_dev_path;
+    }
 
-       status = surface->backend->fill (surface, op, source,
+    if (surface->backend->fill) {
+       status = surface->backend->fill (surface, op, &dev_source.base,
                                         dev_path, fill_rule,
                                         tolerance, antialias);
 
-        if (dev_path == &real_dev_path)
-            _cairo_path_fixed_fini (&real_dev_path);
-
        if (status != CAIRO_INT_STATUS_UNSUPPORTED)
-           return status;
+            goto FINISH;
     }
 
-    return _cairo_surface_fallback_fill (surface, op, source,
-                                        path, fill_rule,
-                                        tolerance, antialias);
+    status = _cairo_surface_fallback_fill (surface, op, &dev_source.base,
+                                           dev_path, fill_rule,
+                                           tolerance, antialias);
+
+FINISH:
+    if (dev_path == &real_dev_path)
+        _cairo_path_fixed_fini (&real_dev_path);
+    _cairo_pattern_fini (&dev_source.base);
+
+    return status;
 }
   
 cairo_status_t
@@ -1226,7 +1200,6 @@ _cairo_surface_composite_trapezoids (cairo_operator_t             op,
                                     int                        num_traps)
 {
     cairo_int_status_t status;
-    cairo_trapezoid_t *dev_traps = NULL;
 
     assert (! dst->is_snapshot);
 
@@ -1242,36 +1215,13 @@ _cairo_surface_composite_trapezoids (cairo_operator_t           op,
        return CAIRO_STATUS_SURFACE_FINISHED;
 
     if (dst->backend->composite_trapezoids) {
-       if (dst->device_x_offset != 0.0 ||
-           dst->device_y_offset != 0.0 ||
-           dst->device_x_scale != 1.0 ||
-           dst->device_y_scale != 1.0)
-       {
-           dev_traps = malloc (sizeof (cairo_trapezoid_t) * num_traps);
-           if (!dev_traps)
-               return CAIRO_STATUS_NO_MEMORY;
-
-           _cairo_trapezoid_array_translate_and_scale
-               (dev_traps, traps, num_traps,
-                dst->device_x_offset,
-                dst->device_y_offset,
-                dst->device_x_scale,
-                dst->device_y_scale);
-       }
-
-
        status = dst->backend->composite_trapezoids (op,
                                                     pattern, dst,
                                                     antialias,
                                                     src_x, src_y,
-                                                    BACKEND_X(dst, dst_x),
-                                                    BACKEND_Y(dst, dst_y),
-                                                    // XXX what the heck do I do with width/height?
-                                                    // they're not the same for src and dst!
+                                                     dst_x, dst_y,
                                                     width, height,
-                                                    dev_traps ? dev_traps : traps, num_traps);
-       free (dev_traps);
-
+                                                    traps, num_traps);
        if (status != CAIRO_INT_STATUS_UNSUPPORTED)
            return status;
     }
@@ -1418,7 +1368,6 @@ _cairo_surface_set_clip_region (cairo_surface_t       *surface,
                                pixman_region16_t   *region,
                                unsigned int        serial)
 {
-    pixman_region16_t *dev_region = NULL;
     cairo_status_t status;
 
     if (surface->status)
@@ -1429,48 +1378,10 @@ _cairo_surface_set_clip_region (cairo_surface_t     *surface,
     
     assert (surface->backend->set_clip_region != NULL);
 
-    if (surface->device_x_offset != 0.0 ||
-       surface->device_y_offset != 0.0 ||
-       surface->device_x_scale != 1.0 ||
-       surface->device_y_scale != 1.0)
-    {
-       dev_region = pixman_region_create ();
-       if (surface->device_x_scale == 1.0 &&
-           surface->device_y_scale == 1.0)
-       {
-           pixman_region_copy (dev_region, region);
-           pixman_region_translate (dev_region, surface->device_x_offset, surface->device_y_offset);
-       } else {
-           int i, nr = pixman_region_num_rects (region);
-           pixman_box16_t *rects = pixman_region_rects (region);
-           for (i = 0; i < nr; i++) {
-               pixman_box16_t tmpb;
-               pixman_region16_t *tmpr;
-
-               tmpb.x1 = BACKEND_X(surface, rects[i].x1);
-               tmpb.y1 = BACKEND_Y(surface, rects[i].y1);
-               tmpb.x2 = BACKEND_X(surface, rects[i].x2);
-               tmpb.y2 = BACKEND_Y(surface, rects[i].y2);
-
-               tmpr = pixman_region_create_simple (&tmpb);
-
-               pixman_region_append (dev_region, tmpr);
-               pixman_region_destroy (tmpr);
-           }
-
-           pixman_region_validate (dev_region, &i);
-       }
-
-       region = dev_region;
-    }
-
     surface->current_clip_serial = serial;
 
     status = surface->backend->set_clip_region (surface, region);
 
-    if (dev_region)
-       pixman_region_destroy (dev_region);
-
     return status;
 }
 
@@ -1482,7 +1393,6 @@ _cairo_surface_intersect_clip_path (cairo_surface_t    *surface,
                                    cairo_antialias_t   antialias)
 {
     cairo_path_fixed_t *dev_path = path;
-    cairo_path_fixed_t real_dev_path;
     cairo_status_t status;
 
     if (surface->status)
@@ -1493,29 +1403,12 @@ _cairo_surface_intersect_clip_path (cairo_surface_t    *surface,
     
     assert (surface->backend->intersect_clip_path != NULL);
 
-    if (surface->device_x_offset != 0.0 ||
-       surface->device_y_offset != 0.0 ||
-       surface->device_x_scale != 1.0 ||
-       surface->device_y_scale != 1.0)
-    {
-       _cairo_path_fixed_init_copy (&real_dev_path, path);
-       _cairo_path_fixed_offset_and_scale (&real_dev_path,
-                                           _cairo_fixed_from_double (surface->device_x_offset),
-                                           _cairo_fixed_from_double (surface->device_y_offset),
-                                           _cairo_fixed_from_double (surface->device_x_scale),
-                                           _cairo_fixed_from_double (surface->device_y_scale));
-       dev_path = &real_dev_path;
-    }
-
     status = surface->backend->intersect_clip_path (surface,
                                                    dev_path,
                                                    fill_rule,
                                                    tolerance,
                                                    antialias);
 
-    if (dev_path == &real_dev_path)
-       _cairo_path_fixed_fini (&real_dev_path);
-
     return status;
 }
 
@@ -1649,8 +1542,10 @@ _cairo_surface_get_extents (cairo_surface_t   *surface,
 
     status = surface->backend->get_extents (surface, rectangle);
 
-    rectangle->x = SURFACE_X(surface, rectangle->x);
-    rectangle->y = SURFACE_Y(surface, rectangle->y);
+    rectangle->x = SURFACE_TO_BACKEND_X(surface, rectangle->x);
+    rectangle->y = SURFACE_TO_BACKEND_Y(surface, rectangle->y);
+    rectangle->width = rectangle->width - surface->device_x_offset;
+    rectangle->height = rectangle->height - surface->device_y_offset;
 
     return status;
 }
@@ -1664,41 +1559,48 @@ _cairo_surface_show_glyphs (cairo_surface_t     *surface,
                            cairo_scaled_font_t *scaled_font)
 {
     cairo_status_t status;
-    cairo_glyph_t *dev_glyphs = NULL;
+    cairo_glyph_t *dev_glyphs = (cairo_glyph_t*) glyphs;
+    cairo_pattern_union_t dev_source;
 
     assert (! surface->is_snapshot);
 
-    if (surface->backend->show_glyphs) {
-       if (surface->device_x_offset != 0.0 ||
-           surface->device_y_offset != 0.0 ||
-           surface->device_x_scale != 1.0 ||
-           surface->device_y_scale != 1.0)
-       {
-            int i;
-
-            dev_glyphs = malloc (sizeof(cairo_glyph_t) * num_glyphs);
-            if (!dev_glyphs)
-                return CAIRO_STATUS_NO_MEMORY;
-
-            for (i = 0; i < num_glyphs; i++) {
-                dev_glyphs[i].index = glyphs[i].index;
-               // err, we really should scale the size of the glyphs, no?
-                dev_glyphs[i].x = BACKEND_X(surface, glyphs[i].x);
-                dev_glyphs[i].y = BACKEND_Y(surface, glyphs[i].y);
-            }
+    _cairo_surface_copy_pattern_for_destination (source,
+                                                 surface,
+                                                 &dev_source.base);
+
+    if (_cairo_surface_has_device_offset_or_scale (surface))
+    {
+        int i;
+
+        dev_glyphs = malloc (sizeof(cairo_glyph_t) * num_glyphs);
+        if (!dev_glyphs)
+            return CAIRO_STATUS_NO_MEMORY;
+
+        for (i = 0; i < num_glyphs; i++) {
+            dev_glyphs[i].index = glyphs[i].index;
+            /* XXX: err, we really should scale the size of the glyphs, no? */
+            dev_glyphs[i].x = SURFACE_TO_BACKEND_X(surface, glyphs[i].x);
+            dev_glyphs[i].y = SURFACE_TO_BACKEND_Y(surface, glyphs[i].y);
         }
+    }
 
-       status = surface->backend->show_glyphs (surface, op, source,
-                                               dev_glyphs ? dev_glyphs : glyphs,
-                                               num_glyphs, scaled_font);
-       free (dev_glyphs);
+    if (surface->backend->show_glyphs) {
+       status = surface->backend->show_glyphs (surface, op, &dev_source.base,
+                                               dev_glyphs, num_glyphs,
+                                                scaled_font);
        if (status != CAIRO_INT_STATUS_UNSUPPORTED)
-           return status;
+            goto FINISH;
     }
 
-    return _cairo_surface_fallback_show_glyphs (surface, op, source,
-                                               glyphs, num_glyphs,
-                                               scaled_font);
+    status = _cairo_surface_fallback_show_glyphs (surface, op, &dev_source.base,
+                                                  dev_glyphs, num_glyphs,
+                                                  scaled_font);
+
+FINISH:
+    if (dev_glyphs != glyphs)
+        free (dev_glyphs);
+
+    return status;
 }
 
 /* XXX: Previously, we had a function named _cairo_surface_show_glyphs
@@ -1721,7 +1623,6 @@ _cairo_surface_old_show_glyphs (cairo_scaled_font_t       *scaled_font,
                                int                      num_glyphs)
 {
     cairo_status_t status;
-    cairo_glyph_t *dev_glyphs = NULL;
 
     assert (! dst->is_snapshot);
 
@@ -1731,35 +1632,14 @@ _cairo_surface_old_show_glyphs (cairo_scaled_font_t     *scaled_font,
     if (dst->finished)
        return CAIRO_STATUS_SURFACE_FINISHED;
 
-    if (dst->backend->old_show_glyphs) {
-       if (dst->device_x_offset != 0.0 ||
-           dst->device_y_offset != 0.0 ||
-           dst->device_x_scale != 1.0 ||
-           dst->device_y_scale != 1.0)
-       {
-           int i;
-
-           dev_glyphs = malloc(sizeof(cairo_glyph_t) * num_glyphs);
-           for (i = 0; i < num_glyphs; i++) {
-               dev_glyphs[i] = glyphs[i];
-               // err, we really should scale the size of the glyphs, no?
-               dev_glyphs[i].x = BACKEND_X(dst, dev_glyphs[i].x);
-               dev_glyphs[i].y = BACKEND_Y(dst, dev_glyphs[i].y);
-           }
-
-           glyphs = dev_glyphs;
-       }
-
+    if (dst->backend->old_show_glyphs)
        status = dst->backend->old_show_glyphs (scaled_font,
                                                op, pattern, dst,
                                                source_x, source_y,
-                                               BACKEND_X(dst, dest_x),
-                                               BACKEND_Y(dst, dest_y),
+                                               dest_x, dest_y,
                                                width, height,
                                                glyphs, num_glyphs);
-
-       free (dev_glyphs);
-    } else
+    else
        status = CAIRO_INT_STATUS_UNSUPPORTED;
 
     return status;
@@ -1869,15 +1749,7 @@ _cairo_surface_composite_fixup_unbounded (cairo_surface_t            *dst,
     cairo_rectangle_t *mask_rectangle = NULL;
 
     assert (! dst->is_snapshot);
-
-    /* This is a little odd; this function is called from the xlib/image surfaces,
-     * where the coordinates have already been transformed by the device_xy_offset.
-     * We need to undo this before running through this function,
-     * otherwise those offsets get applied twice.
-     */
-    dst_x = SURFACE_X(dst, dst_x);
-    dst_y = SURFACE_Y(dst, dst_y);
-
+  
     /* The RENDER/libpixman operators are clipped to the bounds of the untransformed,
      * non-repeating sources and masks. Other sources and masks can be ignored.
      */
@@ -1952,10 +1824,6 @@ _cairo_surface_composite_shape_fixup_unbounded (cairo_surface_t            *dst,
     cairo_rectangle_t *mask_rectangle = NULL;
 
     assert (! dst->is_snapshot);
-
-    /* See comment at start of _cairo_surface_composite_fixup_unbounded */
-    dst_x = SURFACE_X(dst, dst_x);
-    dst_y = SURFACE_Y(dst, dst_y);
   
     /* The RENDER/libpixman operators are clipped to the bounds of the untransformed,
      * non-repeating sources and masks. Other sources and masks can be ignored.
@@ -1981,3 +1849,29 @@ _cairo_surface_composite_shape_fixup_unbounded (cairo_surface_t            *dst,
     return _cairo_surface_composite_fixup_unbounded_internal (dst, src_rectangle, mask_rectangle,
                                                              dst_x, dst_y, width, height);
 }
+
+/**
+ * _cairo_surface_copy_pattern_for_destination
+ * @pattern: the pattern to copy
+ * @destination: the destination surface for which the pattern is being copied
+ * @pattern_out: the location to hold the copy
+ *
+ * Copies the given pattern, taking into account device scale and offsets
+ * of the destination surface.
+ */
+void
+_cairo_surface_copy_pattern_for_destination (const cairo_pattern_t *pattern,
+                                             cairo_surface_t *destination,
+                                             cairo_pattern_t *pattern_out)
+{
+    _cairo_pattern_init_copy (pattern_out, pattern);
+
+    if (_cairo_surface_has_device_offset_or_scale (destination)) {
+       cairo_matrix_t device_to_surface;
+       cairo_matrix_init_translate (&device_to_surface,
+                                    - destination->device_x_offset,
+                                    - destination->device_y_offset);
+
+       _cairo_pattern_transform (pattern_out, &device_to_surface);
+    }
+}
index 1e280d69dc11f64cedc0d246b0d880cb365c46c2..5d569bd6b7da613dd18a95c308c1a81777e5af75 100644 (file)
@@ -74,6 +74,7 @@ struct cairo_svg_document {
     unsigned int pattern_id;
     unsigned int filter_id;
     unsigned int clip_id;
+    unsigned int mask_id;
 };
 
 struct cairo_svg_surface {
@@ -87,8 +88,12 @@ struct cairo_svg_surface {
     cairo_svg_document_t *document;
 
     xmlNodePtr  xml_node;
+    xmlNodePtr  xml_root_node;
 
     unsigned int clip_level;
+
+    cairo_bool_t modified;
+    unsigned int previous_id;
 };
 
 static cairo_svg_document_t *
@@ -208,15 +213,16 @@ _cairo_svg_surface_create_for_document (cairo_svg_document_t      *document,
     _cairo_dtostr (buffer, sizeof buffer, height);
     xmlSetProp (clip_rect, CC2XML ("height"), C2XML (buffer));
     
-    surface->xml_node = xmlNewChild (surface->id == 0 ? 
-                                    document->xml_node_main : 
-                                    document->xml_node_defs, 
-                                    NULL, CC2XML ("g"), NULL);
+    surface->xml_node = xmlNewNode (NULL, CC2XML ("g"));
+    surface->xml_root_node = surface->xml_node;
        
     snprintf (buffer, sizeof buffer, "surface%d", surface->id);
     xmlSetProp (surface->xml_node, CC2XML ("id"), C2XML (buffer));
     snprintf (buffer, sizeof buffer, "url(#clip%d)", clip_id);
     xmlSetProp (surface->xml_node, CC2XML ("clip-path"), C2XML (buffer));
+
+    surface->modified = TRUE;
+    surface->previous_id = surface->id;
     
     return &surface->base;
 }
@@ -239,14 +245,19 @@ _cairo_svg_surface_finish (void *abstract_surface)
     cairo_status_t status;
     cairo_svg_surface_t *surface = abstract_surface;
     cairo_svg_document_t *document = surface->document;
+    
 
-    if (document->owner == &surface->base)
+    if (document->owner == &surface->base) {
+       xmlAddChild (document->xml_node_main, xmlCopyNode (surface->xml_root_node, 1));
        status = _cairo_svg_document_finish (document);
-    else
+    else
        status = CAIRO_STATUS_SUCCESS;
 
     _cairo_svg_document_destroy (document);
 
+    xmlFreeNode (surface->xml_root_node);
+    surface->xml_node = NULL;
+
     return status;
 }
 
@@ -262,22 +273,22 @@ emit_transform (xmlNodePtr node,
     xmlBufferCat (matrix_buffer, CC2XML ("matrix("));
     _cairo_dtostr (buffer, sizeof buffer, matrix->xx);
     xmlBufferCat (matrix_buffer, C2XML (buffer));
-    xmlBufferCat (matrix_buffer, ",");
+    xmlBufferCat (matrix_buffer, CC2XML (","));
     _cairo_dtostr (buffer, sizeof buffer, matrix->yx);
     xmlBufferCat (matrix_buffer, C2XML (buffer));
-    xmlBufferCat (matrix_buffer, ",");
+    xmlBufferCat (matrix_buffer, CC2XML (","));
     _cairo_dtostr (buffer, sizeof buffer, matrix->xy);
     xmlBufferCat (matrix_buffer, C2XML (buffer));
-    xmlBufferCat (matrix_buffer, ",");
+    xmlBufferCat (matrix_buffer, CC2XML (","));
     _cairo_dtostr (buffer, sizeof buffer, matrix->yy);
     xmlBufferCat (matrix_buffer, C2XML (buffer));
-    xmlBufferCat (matrix_buffer, ",");
+    xmlBufferCat (matrix_buffer, CC2XML (","));
     _cairo_dtostr (buffer, sizeof buffer, matrix->x0);
     xmlBufferCat (matrix_buffer, C2XML (buffer));
-    xmlBufferCat (matrix_buffer, ",");
+    xmlBufferCat (matrix_buffer, CC2XML(","));
     _cairo_dtostr (buffer, sizeof buffer, matrix->y0);
     xmlBufferCat (matrix_buffer, C2XML (buffer));
-    xmlBufferCat (matrix_buffer, ")");
+    xmlBufferCat (matrix_buffer, CC2XML (")"));
     xmlSetProp (node, CC2XML (attribute_str), C2XML (xmlBufferContent (matrix_buffer)));
     xmlBufferFree (matrix_buffer);
 }
@@ -291,7 +302,7 @@ typedef struct {
     unsigned int trailing;
 } base64_write_closure_t;
 
-static unsigned char const *base64_table =
+static char const *base64_table =
 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
 
 static cairo_status_t
@@ -324,7 +335,7 @@ base64_write_func (void *closure,
        info->count++;
        if (info->count >= 18) {
            info->count = 0;
-           xmlBufferCat (info->buffer, "\r\n");
+           xmlBufferCat (info->buffer, CC2XML ("\r\n"));
        }
        dst[0] = base64_table[src[0] >> 2];
        dst[1] = base64_table[(src[0] & 0x03) << 4 | src[1] >> 4];
@@ -392,7 +403,7 @@ _cairo_surface_base64_encode (cairo_surface_t *surface,
     return CAIRO_STATUS_SUCCESS;
 }
 
-static cairo_int_status_t
+static xmlNodePtr
 emit_composite_image_pattern (xmlNodePtr node,
                              cairo_surface_pattern_t *pattern,
                              double *width,
@@ -410,11 +421,11 @@ emit_composite_image_pattern (xmlNodePtr node,
 
     status = _cairo_surface_acquire_source_image (surface, &image, &image_extra);
     if (status)
-       return status;
+       return NULL;
 
     status = _cairo_surface_base64_encode (surface, &image_buffer);
     if (status)
-       return status;
+       return NULL;
 
     child = xmlNewChild (node, NULL, CC2XML ("image"), NULL);
     _cairo_dtostr (buffer, sizeof buffer, image->width);
@@ -438,10 +449,10 @@ emit_composite_image_pattern (xmlNodePtr node,
 
     _cairo_surface_release_source_image (pattern->surface, image, image_extra);
 
-    return status;
+    return child;
 }
 
-static cairo_int_status_t
+static xmlNodePtr
 emit_composite_svg_pattern (xmlNodePtr node, 
                            cairo_surface_pattern_t *pattern,
                            double *width, 
@@ -449,16 +460,16 @@ emit_composite_svg_pattern (xmlNodePtr node,
                            cairo_bool_t is_pattern)
 {
     cairo_svg_surface_t *surface = (cairo_svg_surface_t *) pattern->surface;
+    cairo_svg_document_t *document = surface->document;
     cairo_matrix_t p2u;
     xmlNodePtr child;
     char buffer[CAIRO_SVG_DTOSTR_BUFFER_LEN];
 
-    /* FIXME: self copy is not supported yet */
-    if (surface->id == 0)
-       return CAIRO_STATUS_SUCCESS;
+    if (surface->modified)
+           xmlAddChild (document->xml_node_defs, xmlCopyNode (surface->xml_root_node, 1));
     
     child = xmlNewChild (node, NULL, CC2XML("use"), NULL);
-    snprintf (buffer, sizeof buffer, "#surface%d", surface->id);
+    snprintf (buffer, sizeof buffer, "#surface%d", surface->previous_id);
     xmlSetProp (child, CC2XML ("xlink:href"), C2XML (buffer));
 
     if (!is_pattern) {
@@ -472,10 +483,18 @@ emit_composite_svg_pattern (xmlNodePtr node,
     if (height != NULL)
            *height = surface->height;
 
-    return CAIRO_STATUS_SUCCESS;
+    if (surface->modified) {
+           surface->modified = FALSE;
+           surface->previous_id = surface->id;
+           surface->id = document->surface_id++;
+           snprintf (buffer, sizeof buffer, "surface%d", surface->id);
+           xmlSetProp (surface->xml_root_node, CC2XML ("id"), C2XML (buffer));
+    }
+
+    return child;
 }
 
-static cairo_int_status_t
+static xmlNodePtr
 emit_composite_pattern (xmlNodePtr node, 
                        cairo_surface_pattern_t *pattern,
                        double *width,
@@ -488,69 +507,27 @@ emit_composite_pattern (xmlNodePtr node,
        return emit_composite_image_pattern (node, pattern, width, height, is_pattern);
 }
 
-static cairo_int_status_t
-_cairo_svg_surface_composite (cairo_operator_t op,
-                             cairo_pattern_t   *src_pattern,
-                             cairo_pattern_t   *mask_pattern,
-                             void              *abstract_dst,
-                             int               src_x,
-                             int               src_y,
-                             int               mask_x,
-                             int               mask_y,
-                             int               dst_x,
-                             int               dst_y,
-                             unsigned int      width,
-                             unsigned int      height)
-{
-    cairo_svg_surface_t *dst = abstract_dst;
-    cairo_surface_pattern_t *src = (cairo_surface_pattern_t *) src_pattern;
-
-    if (mask_pattern)
-       return CAIRO_STATUS_SUCCESS;
-    
-    if (src_pattern->type != CAIRO_PATTERN_SURFACE)
-       return CAIRO_STATUS_SUCCESS;
-
-    return emit_composite_pattern (dst->xml_node, src, NULL, NULL, FALSE);
-}
+/* FIXME: Here we use a SVG 1.2 feature. We should probably have
+ * an API to limit output SVG version, and fallback to image when
+ * necessary. */
 
 static void
-emit_operator (cairo_operator_t op, cairo_svg_surface_t *surface,
-              xmlBufferPtr style)
+emit_operator (xmlNodePtr node, cairo_operator_t op)
 {
     char const *op_str[] = {
-       NULL,
-       NULL, NULL, "in", "out", "atop",
-       NULL, NULL, NULL, NULL, NULL, 
-       "xor", NULL, NULL };
-    
-    cairo_svg_document_t *document = surface->document;
-    xmlNodePtr child, primitive;
-    xmlBufferPtr id;
-    char buffer[CAIRO_SVG_DTOSTR_BUFFER_LEN];
-
-    if (op_str[op] == NULL)
-       return;
-
-    child = xmlNewChild (document->xml_node_defs, NULL, CC2XML ("filter"), NULL);
-    primitive = xmlNewChild (child, NULL, CC2XML ("feComposite"), NULL);
-    xmlSetProp (primitive, CC2XML ("operator"), CC2XML (op_str[op]));
-    xmlSetProp (primitive, CC2XML ("in"), CC2XML ("SourceGraphic"));
-    xmlSetProp (primitive, CC2XML ("in2"), CC2XML ("BackgroundImage"));
-
-    id = xmlBufferCreate ();
-    xmlBufferCat (id, CC2XML ("filter"));
-    snprintf (buffer, sizeof buffer, "%d", document->filter_id);
-    xmlBufferCat (id, C2XML (buffer));
-    xmlSetProp (child, CC2XML ("id"), C2XML (xmlBufferContent (id)));
-    
-    xmlBufferCat (style, CC2XML ("filter: url(#"));
-    xmlBufferCat (style, xmlBufferContent (id));
-    xmlBufferCat (style, CC2XML (");"));
+       "clear",
+       
+       "src",          "src-over",     "src-in",
+       "src-out",      "src-atop",
+       
+       "dst",          "dst-over",     "dst-in",
+       "dst-out",      "dst-atop",     
+       
+       "xor", "plus",  
+       "color-dodge"   /* FIXME: saturate ? */
+    };
 
-    xmlBufferFree (id);
-    
-    document->filter_id++;
+    xmlSetProp (node, CC2XML ("comp-op"), C2XML (op_str[op]));
 }
 
 static void
@@ -803,19 +780,19 @@ emit_pattern (cairo_svg_surface_t *surface, cairo_pattern_t *pattern,
              xmlBufferPtr style, int is_stroke)
 {
     switch (pattern->type) {
-    case CAIRO_PATTERN_SOLID:  
+    case CAIRO_PATTERN_TYPE_SOLID:     
        emit_solid_pattern (surface, (cairo_solid_pattern_t *) pattern, style, is_stroke);
        break;
 
-    case CAIRO_PATTERN_SURFACE:
+    case CAIRO_PATTERN_TYPE_SURFACE:
        emit_surface_pattern (surface, (cairo_surface_pattern_t *) pattern, style, is_stroke);
        break;
 
-    case CAIRO_PATTERN_LINEAR:
+    case CAIRO_PATTERN_TYPE_LINEAR:
        emit_linear_pattern (surface, (cairo_linear_pattern_t *) pattern, style, is_stroke);
        break;
 
-    case CAIRO_PATTERN_RADIAL:
+    case CAIRO_PATTERN_TYPE_RADIAL:
        emit_radial_pattern (surface, (cairo_radial_pattern_t *) pattern, style, is_stroke);
        break;      
     }
@@ -828,7 +805,7 @@ typedef struct
     xmlBufferPtr path;
 } svg_path_info_t;
 
-    static cairo_status_t
+static cairo_status_t
 _cairo_svg_path_move_to (void *closure, cairo_point_t *point)
 {
     svg_path_info_t *info = closure;
@@ -917,42 +894,6 @@ _cairo_svg_path_close_path (void *closure)
     return CAIRO_STATUS_SUCCESS;
 }
 
-static cairo_int_status_t
-_cairo_svg_surface_fill_rectangles (void               *abstract_surface,
-                                   cairo_operator_t     op,
-                                   const cairo_color_t *color,
-                                   cairo_rectangle_t   *rects,
-                                   int                  num_rects)
-{
-    cairo_svg_surface_t *surface = abstract_surface;
-    xmlNodePtr child;
-    xmlBufferPtr style;
-    char buffer[CAIRO_SVG_DTOSTR_BUFFER_LEN];
-    int i;
-
-    style = xmlBufferCreate ();
-    emit_color (color, style, "fill", "opacity");
-    xmlBufferCat (style, " stroke: none;");
-    emit_operator (op, surface, style);
-    
-    for (i = 0; i < num_rects; i++) {
-       child = xmlNewChild (surface->xml_node, NULL, CC2XML ("rect"), NULL);
-       _cairo_dtostr (buffer, sizeof buffer, rects[i].x);
-       xmlSetProp (child, CC2XML ("x"), C2XML (buffer));
-       _cairo_dtostr (buffer, sizeof buffer, rects[i].y);
-       xmlSetProp (child, CC2XML ("y"), C2XML (buffer));
-       _cairo_dtostr (buffer, sizeof buffer, rects[i].width);
-       xmlSetProp (child, CC2XML ("width"), C2XML (buffer));
-       _cairo_dtostr (buffer, sizeof buffer, rects[i].height);
-       xmlSetProp (child, CC2XML ("height"), C2XML (buffer));
-       xmlSetProp (child, CC2XML ("style"), xmlBufferContent (style));
-    }  
-
-    xmlBufferFree (style);
-
-    return CAIRO_STATUS_SUCCESS;
-}
-
 static cairo_int_status_t
 _cairo_svg_surface_fill (void                  *abstract_surface,
                         cairo_operator_t        op,
@@ -975,10 +916,9 @@ _cairo_svg_surface_fill (void                      *abstract_surface,
     
     style = xmlBufferCreate ();
     emit_pattern (surface, source, style, 0);
-    xmlBufferCat (style, " stroke: none;");
-    xmlBufferCat (style, " fill-rule: ");
-    xmlBufferCat (style, fill_rule == CAIRO_FILL_RULE_EVEN_ODD ? "evenodd;" : "nonzero;");
-    emit_operator (op, surface, style);
+    xmlBufferCat (style, CC2XML (" stroke: none;"));
+    xmlBufferCat (style, CC2XML (" fill-rule: "));
+    xmlBufferCat (style, fill_rule == CAIRO_FILL_RULE_EVEN_ODD ? CC2XML("evenodd;") : CC2XML ("nonzero;"));
 
     status = _cairo_path_fixed_interpret (path,
                                          CAIRO_DIRECTION_FORWARD,
@@ -991,98 +931,15 @@ _cairo_svg_surface_fill (void                     *abstract_surface,
     child = xmlNewChild (surface->xml_node, NULL, CC2XML ("path"), NULL);
     xmlSetProp (child, CC2XML ("d"), xmlBufferContent (info.path));
     xmlSetProp (child, CC2XML ("style"), xmlBufferContent (style));
+    emit_operator (child, op);
 
     xmlBufferFree (info.path);
     xmlBufferFree (style);
 
+    surface->modified = TRUE;
     return status;
 }
 
-static double
-intersect (cairo_line_t *line, cairo_fixed_t y)
-{
-    return _cairo_fixed_to_double (line->p1.x) +
-       _cairo_fixed_to_double (line->p2.x - line->p1.x) *
-       _cairo_fixed_to_double (y - line->p1.y) /
-       _cairo_fixed_to_double (line->p2.y - line->p1.y);
-}
-
-static cairo_int_status_t
-_cairo_svg_surface_composite_trapezoids (cairo_operator_t       op,
-                                        cairo_pattern_t        *pattern,
-                                        void                   *abstract_dst,
-                                        cairo_antialias_t       antialias,
-                                        int                     x_src,
-                                        int                     y_src,
-                                        int                     x_dst,
-                                        int                     y_dst,
-                                        unsigned int            width,
-                                        unsigned int            height,
-                                        cairo_trapezoid_t      *traps,
-                                        int                     num_traps)
-{
-    cairo_svg_surface_t *surface = abstract_dst;
-    xmlBufferPtr style, path;
-    xmlNodePtr child;
-    double left_x1, left_x2, right_x1, right_x2;
-    char buffer[CAIRO_SVG_DTOSTR_BUFFER_LEN];
-    int i;
-
-    style = xmlBufferCreate ();
-    emit_pattern (surface, pattern, style, 0);
-    xmlBufferCat (style, "stroke: none;");
-
-    path = xmlBufferCreate ();
-
-    for (i = 0; i < num_traps; i++) {
-
-       left_x1  = intersect (&traps[i].left, traps[i].top);
-       left_x2  = intersect (&traps[i].left, traps[i].bottom);
-       right_x1 = intersect (&traps[i].right, traps[i].top);
-       right_x2 = intersect (&traps[i].right, traps[i].bottom);
-
-       xmlBufferCat (path, CC2XML ("M "));
-       _cairo_dtostr (buffer, sizeof buffer, left_x1);
-       xmlBufferCat (path, CC2XML (buffer));
-       xmlBufferCat (path, CC2XML (" "));
-       _cairo_dtostr (buffer, sizeof buffer,
-                      _cairo_fixed_to_double (traps[i].top));
-       xmlBufferCat (path, CC2XML (buffer));
-       xmlBufferCat (path, CC2XML (" L "));
-       _cairo_dtostr (buffer, sizeof buffer, left_x2);
-       xmlBufferCat (path, CC2XML (buffer));
-       xmlBufferCat (path, CC2XML (" "));
-       _cairo_dtostr (buffer, sizeof buffer, 
-                      _cairo_fixed_to_double (traps[i].bottom));
-       xmlBufferCat (path, CC2XML (buffer));
-       xmlBufferCat (path, CC2XML (" L "));
-       _cairo_dtostr (buffer, sizeof buffer, right_x2);
-       xmlBufferCat (path, CC2XML (buffer));
-       xmlBufferCat (path, CC2XML (" "));
-       _cairo_dtostr (buffer, sizeof buffer, 
-                      _cairo_fixed_to_double (traps[i].bottom));
-       xmlBufferCat (path, CC2XML (buffer));
-       xmlBufferCat (path, CC2XML (" L "));
-       _cairo_dtostr (buffer, sizeof buffer, right_x1);
-       xmlBufferCat (path, CC2XML (buffer));
-       xmlBufferCat (path, CC2XML (" "));
-       _cairo_dtostr (buffer, sizeof buffer,
-                     _cairo_fixed_to_double (traps[i].top));
-       xmlBufferCat (path, CC2XML (buffer));
-       xmlBufferCat (path, CC2XML (" Z"));
-    }
-
-    child = xmlNewChild (surface->xml_node, NULL, CC2XML ("path"), NULL);
-
-    xmlSetProp (child, CC2XML ("d"), xmlBufferContent (path));
-    xmlSetProp (child, CC2XML ("style"), xmlBufferContent (style));
-    
-    xmlBufferFree (path);
-    xmlBufferFree (style);
-
-    return CAIRO_STATUS_SUCCESS;
-}
-
 static cairo_int_status_t
 _cairo_svg_surface_get_extents (void             *abstract_surface,
                                cairo_rectangle_t *rectangle)
@@ -1102,26 +959,26 @@ _cairo_svg_surface_get_extents (void               *abstract_surface,
     return CAIRO_STATUS_SUCCESS;
 }
 
-    /* First attempt of paint implementation, but obviously I didn't
-     * understand how it's supposed to work */
-
-#if 0
-static cairo_int_status_t
-_cairo_svg_surface_paint (void             *abstract_surface,
-                         cairo_operator_t   op,
-                         cairo_pattern_t   *source)
+static xmlNodePtr
+emit_paint (xmlNodePtr node,
+           cairo_svg_surface_t *surface,
+           cairo_operator_t     op,
+           cairo_pattern_t     *source)
 {
-    cairo_svg_surface_t *surface = abstract_surface;
     xmlNodePtr child;
     xmlBufferPtr style;
     char buffer[CAIRO_SVG_DTOSTR_BUFFER_LEN];
 
+    if (source->type == CAIRO_PATTERN_TYPE_SURFACE)
+       return emit_composite_pattern (node, 
+                                      (cairo_surface_pattern_t *) source, 
+                                      NULL, NULL, FALSE);
+
     style = xmlBufferCreate ();
     emit_pattern (surface, source, style, 0);
-    xmlBufferCat (style, " stroke: none;");
-    emit_operator (op, surface, style);
+    xmlBufferCat (style, CC2XML (" stroke: none;"));
 
-    child = xmlNewChild (surface->xml_node, NULL, CC2XML ("rect"), NULL);
+    child = xmlNewChild (node, NULL, CC2XML ("rect"), NULL);
     xmlSetProp (child, CC2XML ("x"), CC2XML ("0"));
     xmlSetProp (child, CC2XML ("y"), CC2XML ("0"));
     _cairo_dtostr (buffer, sizeof buffer, surface->width);
@@ -1129,12 +986,54 @@ _cairo_svg_surface_paint (void               *abstract_surface,
     _cairo_dtostr (buffer, sizeof buffer, surface->height);
     xmlSetProp (child, CC2XML ("height"), C2XML (buffer));
     xmlSetProp (child, CC2XML ("style"), xmlBufferContent (style));
+    emit_operator (child, op);
 
     xmlBufferFree (style);
 
+    return child;
+}
+
+static cairo_int_status_t
+_cairo_svg_surface_paint (void             *abstract_surface,
+                         cairo_operator_t   op,
+                         cairo_pattern_t   *source)
+{
+    cairo_svg_surface_t *surface = abstract_surface;
+
+    emit_paint (surface->xml_node, surface, op, source);
+    
+    surface->modified = TRUE;
+    return CAIRO_STATUS_SUCCESS;
+}
+
+static cairo_int_status_t
+_cairo_svg_surface_mask (void              *abstract_surface,
+                       cairo_operator_t     op,
+                       cairo_pattern_t     *source,
+                       cairo_pattern_t     *mask)
+{
+    cairo_svg_surface_t *surface = abstract_surface;
+    cairo_svg_document_t *document = surface->document;
+    xmlNodePtr child, mask_node;
+    char buffer[CAIRO_SVG_DTOSTR_BUFFER_LEN];
+
+    mask_node = xmlNewChild (document->xml_node_defs, NULL, CC2XML ("mask"), NULL);
+    snprintf (buffer, sizeof buffer, "mask%d", document->mask_id);
+    xmlSetProp (mask_node, CC2XML ("id"), C2XML (buffer));
+    emit_paint (mask_node, surface, op, mask);
+
+    child = emit_paint (surface->xml_node, surface, op, source);
+
+    if (child) {
+       snprintf (buffer, sizeof buffer, "url(#mask%d)", document->mask_id);
+       xmlSetProp (child, CC2XML ("mask"), C2XML (buffer));
+    }
+
+    document->mask_id++;
+
+    surface->modified = TRUE;
     return CAIRO_STATUS_SUCCESS;
 }
-#endif
 
 static cairo_int_status_t
 _cairo_svg_surface_stroke (void                        *abstract_dst,
@@ -1199,21 +1098,21 @@ _cairo_svg_surface_stroke (void                 *abstract_dst,
        xmlBufferCat (style, CC2XML (" stroke-dasharray: "));
        for (i = 0; i < stroke_style->num_dashes; i++) {
            if (i != 0)
-               xmlBufferCat (style, ",");
+               xmlBufferCat (style, CC2XML (","));
            /* FIXME: Is is really what we want ? */
            rx = ry = stroke_style->dash[i];
            cairo_matrix_transform_distance (ctm, &rx, &ry);
            _cairo_dtostr (buffer, sizeof buffer, sqrt ((rx * rx + ry * ry) / 2.0));
            xmlBufferCat (style, C2XML (buffer));
        }
-       xmlBufferCat (style, ";");
+       xmlBufferCat (style, CC2XML (";"));
        if (stroke_style->dash_offset != 0.0) {
            xmlBufferCat (style, CC2XML (" stroke-dashoffset: "));
            rx = ry = stroke_style->dash_offset;
            cairo_matrix_transform_distance (ctm, &rx, &ry);
            _cairo_dtostr (buffer, sizeof buffer, sqrt ((rx * rx + ry * ry) / 2.0));
            xmlBufferCat (style, C2XML (buffer));
-           xmlBufferCat (style, ";");
+           xmlBufferCat (style, CC2XML (";"));
        }
     }
 
@@ -1231,30 +1130,26 @@ _cairo_svg_surface_stroke (void                 *abstract_dst,
                                          &info);
     
     child = xmlNewChild (surface->xml_node, NULL, CC2XML ("path"), NULL);
-
     xmlSetProp (child, CC2XML ("d"), xmlBufferContent (info.path));
     xmlSetProp (child, CC2XML ("style"), xmlBufferContent (style));
+    emit_operator (child, op);
     
     xmlBufferFree (info.path);
     xmlBufferFree (style);
 
+    surface->modified = TRUE;
     return status;
 }
 
 static cairo_int_status_t
-_cairo_svg_surface_old_show_glyphs (cairo_scaled_font_t        *scaled_font,
-                                   cairo_operator_t     op,
-                                   cairo_pattern_t     *pattern,
-                                   void                *abstract_surface,
-                                   int                  source_x,
-                                   int                  source_y,
-                                   int                  dest_x,
-                                   int                  dest_y,
-                                   unsigned int         width,
-                                   unsigned int         height,
-                                   const cairo_glyph_t *glyphs,
-                                   int                  num_glyphs)
+_cairo_svg_surface_show_glyphs (void                   *abstract_surface,
+                               cairo_operator_t         op,
+                               cairo_pattern_t         *pattern,
+                               const cairo_glyph_t     *glyphs,
+                               int                      num_glyphs,
+                               cairo_scaled_font_t     *scaled_font)
 {
+    cairo_svg_surface_t *surface = abstract_surface;
     cairo_path_fixed_t path;
     cairo_status_t status;
 
@@ -1278,6 +1173,7 @@ _cairo_svg_surface_old_show_glyphs (cairo_scaled_font_t   *scaled_font,
 
     _cairo_path_fixed_fini (&path);
 
+    surface->modified = TRUE;
     return status;
 }
 
@@ -1296,10 +1192,8 @@ _cairo_svg_surface_intersect_clip_path (void                     *dst,
     char buffer[CAIRO_SVG_DTOSTR_BUFFER_LEN];
 
     if (path == NULL) {
-       while (surface->clip_level > 0) {
-           surface->xml_node = surface->xml_node->parent;
-           surface->clip_level--;
-       }
+       surface->xml_node = surface->xml_root_node;
+       surface->clip_level = 0;
        return CAIRO_STATUS_SUCCESS;
     }
 
@@ -1350,6 +1244,7 @@ _cairo_svg_surface_get_font_options (void                  *abstract_surface,
 
 
 static const cairo_surface_backend_t cairo_svg_surface_backend = {
+       CAIRO_SURFACE_TYPE_SVG,
        _cairo_svg_surface_create_similar,
        _cairo_svg_surface_finish,
        NULL, /* acquire_source_image */
@@ -1357,25 +1252,25 @@ static const cairo_surface_backend_t cairo_svg_surface_backend = {
        NULL, /* acquire_dest_image */
        NULL, /* release_dest_image */
        NULL, /* clone_similar */
-       _cairo_svg_surface_composite,
-       _cairo_svg_surface_fill_rectangles, 
-       _cairo_svg_surface_composite_trapezoids,
+       NULL, /* _cairo_svg_surface_composite, */
+       NULL, /* _cairo_svg_surface_fill_rectangles, */
+       NULL, /* _cairo_svg_surface_composite_trapezoids,*/
        NULL, /* copy_page */
        NULL, /* show_page */
        NULL, /* set_clip_region */
        _cairo_svg_surface_intersect_clip_path,
        _cairo_svg_surface_get_extents,
-       _cairo_svg_surface_old_show_glyphs,
+       NULL, /* _cairo_svg_surface_old_show_glyphs, */
        _cairo_svg_surface_get_font_options,
        NULL, /* flush */
        NULL, /* mark dirty rectangle */
        NULL, /* scaled font fini */
        NULL, /* scaled glyph fini */
-       NULL, /*_cairo_svg_surface_paint,*/
-       NULL, /* mask */
+       _cairo_svg_surface_paint,
+       _cairo_svg_surface_mask,
        _cairo_svg_surface_stroke,
        _cairo_svg_surface_fill,
-       NULL  /* show_glyphs */
+       _cairo_svg_surface_show_glyphs
 };
 
 static cairo_svg_document_t *
@@ -1407,6 +1302,7 @@ _cairo_svg_document_create (cairo_output_stream_t *output_stream,
     document->pattern_id = 0;
     document->filter_id = 0;
     document->clip_id = 0;
+    document->mask_id = 0;
 
     doc = xmlNewDoc (CC2XML ("1.0")); 
     node = xmlNewNode (NULL, CC2XML ("svg"));
@@ -1423,7 +1319,7 @@ _cairo_svg_document_create (cairo_output_stream_t *output_stream,
     xmlSetProp (node, CC2XML ("height"), CC2XML (buffer));
     xmlSetProp (node, CC2XML ("xmlns"), CC2XML ("http://www.w3.org/2000/svg"));
     xmlSetProp (node, CC2XML ("xmlns:xlink"), CC2XML ("http://www.w3.org/1999/xlink"));
-    xmlSetProp (node, CC2XML ("version"), CC2XML ("1.1"));
+    xmlSetProp (node, CC2XML ("version"), CC2XML ("1.2"));
 
     return document;
 }
@@ -1446,21 +1342,32 @@ _cairo_svg_document_destroy (cairo_svg_document_t *document)
     free (document);
 }
 
+static int
+_cairo_svg_document_write (cairo_output_stream_t *output_stream,
+                          const char * buffer,
+                          int len)
+{
+    if (_cairo_output_stream_write (output_stream, buffer, len) != CAIRO_STATUS_SUCCESS)
+       return -1;
+}
+
+
 static cairo_status_t
 _cairo_svg_document_finish (cairo_svg_document_t *document)
 {
     cairo_status_t status;
     cairo_output_stream_t *output = document->output_stream;
-    xmlChar *xml_buffer;
-    int xml_buffer_size;
+    xmlOutputBufferPtr xml_output_buffer;
 
     if (document->finished)
        return CAIRO_STATUS_SUCCESS;
 
-    /* FIXME: Dumping xml tree in memory is silly. */
-    xmlDocDumpFormatMemoryEnc (document->xml_doc, &xml_buffer, &xml_buffer_size, "UTF-8", 1);
-    _cairo_output_stream_write (document->output_stream, xml_buffer, xml_buffer_size);
-    xmlFree(xml_buffer);
+    xml_output_buffer = xmlOutputBufferCreateIO ((xmlOutputWriteCallback) _cairo_svg_document_write,
+                                                (xmlOutputCloseCallback) NULL,
+                                                (void *) document->output_stream, 
+                                                NULL);
+    xmlSaveFormatFileTo (xml_output_buffer, document->xml_doc, "UTF-8", 1);
+
     xmlFreeDoc (document->xml_doc);
 
     status = _cairo_output_stream_get_status (output);
index 0043ca530a2edadf00950ee2d94c408b2d2b72fd..89df00b3769adbb9880315aaf99e14fecb21e0ab 100644 (file)
@@ -1,5 +1,4 @@
-/*
- * $Id: cairo-wideint.c,v 1.6 2006/02/03 04:49:23 vladimir%pobox.com Exp $
+/* cairo - a vector graphics library with display and print output
  *
  * Copyright © 2004 Keith Packard
  *
index 3050a5ebbb7a4c88b4c03290280c94ea89a05d17..795cde73d3b1e090dd08a8a063bc10ed7eb78845 100644 (file)
@@ -1,5 +1,4 @@
-/*
- * $Id: cairo-wideint.h,v 1.11 2006/02/03 04:49:23 vladimir%pobox.com Exp $
+/* cairo - a vector graphics library with display and print output
  *
  * Copyright © 2004 Keith Packard
  *
index 583cac0166af00f86f203987d5dfabfa37b7a88e..89c95e944ef11ed00e2c544607f1d5076462b9f4 100644 (file)
@@ -52,8 +52,6 @@
 
 const cairo_scaled_font_backend_t cairo_win32_scaled_font_backend;
 
-#define LOGICAL_SCALE 32
-
 typedef struct {
     cairo_scaled_font_t base;
 
@@ -63,8 +61,8 @@ typedef struct {
 
     /* We do drawing and metrics computation in a "logical space" which
      * is similar to font space, except that it is scaled by a factor
-     * of the (desired font size) * (LOGICAL_SCALE). The multiplication
-     * by LOGICAL_SCALE allows for sub-pixel precision.
+     * of the (desired font size) * (WIN32_FONT_LOGICAL_SCALE). The multiplication
+     * by WIN32_FONT_LOGICAL_SCALE allows for sub-pixel precision.
      */
     double logical_scale;
 
@@ -148,8 +146,8 @@ _compute_transform (cairo_win32_scaled_font_t *scaled_font,
        if (scaled_font->swap_y)
            scaled_font->y_scale = - scaled_font->y_scale;
        
-       scaled_font->logical_scale = LOGICAL_SCALE * scaled_font->y_scale;
-       scaled_font->logical_size = LOGICAL_SCALE * floor (scaled_font->y_scale + 0.5);
+       scaled_font->logical_scale = WIN32_FONT_LOGICAL_SCALE * scaled_font->y_scale;
+       scaled_font->logical_size = WIN32_FONT_LOGICAL_SCALE * floor (scaled_font->y_scale + 0.5);
     }
 
     /* The font matrix has x and y "scale" components which we extract and
@@ -163,8 +161,8 @@ _compute_transform (cairo_win32_scaled_font_t *scaled_font,
                                             &scaled_font->x_scale, &scaled_font->y_scale,
                                             TRUE);     /* XXX: Handle vertical text */
 
-       scaled_font->logical_size = floor (LOGICAL_SCALE * scaled_font->y_scale + 0.5);
-       scaled_font->logical_scale = LOGICAL_SCALE * scaled_font->y_scale;
+       scaled_font->logical_size = floor (WIN32_FONT_LOGICAL_SCALE * scaled_font->y_scale + 0.5);
+       scaled_font->logical_scale = WIN32_FONT_LOGICAL_SCALE * scaled_font->y_scale;
     }
 
     cairo_matrix_scale (&scaled_font->logical_to_device,
@@ -1148,8 +1146,7 @@ _cairo_win32_scaled_font_show_glyphs (void                       *abstract_font,
                         ((int)solid_pattern->color.blue_short) >> 8);
 
        status = _draw_glyphs_on_surface (surface, scaled_font, new_color,
-                                         - surface->base.device_x_offset,
-                                         - surface->base.device_y_offset,
+                                         0, 0,
                                          glyphs, num_glyphs);
        
        return status;
@@ -1165,7 +1162,7 @@ _cairo_win32_scaled_font_show_glyphs (void                       *abstract_font,
        cairo_surface_pattern_t mask;
        RECT r;
 
-       tmp_surface = (cairo_win32_surface_t *)cairo_win32_surface_create_dib (CAIRO_FORMAT_ARGB32, width, height);
+       tmp_surface = (cairo_win32_surface_t *)cairo_win32_surface_create_with_dib (CAIRO_FORMAT_ARGB32, width, height);
        if (tmp_surface->base.status)
            return CAIRO_STATUS_NO_MEMORY;
 
@@ -1361,6 +1358,7 @@ CLEANUP_FONT:
 }
 
 const cairo_scaled_font_backend_t cairo_win32_scaled_font_backend = {
+    CAIRO_FONT_TYPE_WIN32,
     _cairo_win32_scaled_font_create_toy,
     _cairo_win32_scaled_font_fini,
     _cairo_win32_scaled_font_glyph_init,
@@ -1406,6 +1404,7 @@ _cairo_win32_font_face_scaled_font_create (void                   *abstract_face,
 }
 
 static const cairo_font_face_backend_t _cairo_win32_font_face_backend = {
+    CAIRO_FONT_TYPE_WIN32,
     _cairo_win32_font_face_destroy,
     _cairo_win32_font_face_scaled_font_create
 };
@@ -1552,5 +1551,40 @@ 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;
 }
+
+void
+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->xx = win_font->logical_to_device.xx;
+    logical_to_device->yx = win_font->logical_to_device.yx;
+    logical_to_device->xy = win_font->logical_to_device.xy;
+    logical_to_device->yy = win_font->logical_to_device.yy;
+    logical_to_device->x0 = win_font->logical_to_device.x0;
+    logical_to_device->y0 = win_font->logical_to_device.y0;
+}
+
+void
+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->xx = win_font->device_to_logical.xx;
+    device_to_logical->yx = win_font->device_to_logical.yx;
+    device_to_logical->xy = win_font->device_to_logical.xy;
+    device_to_logical->yy = win_font->device_to_logical.yy;
+    device_to_logical->x0 = win_font->device_to_logical.x0;
+    device_to_logical->y0 = win_font->device_to_logical.y0;
+}
index fd66424136e1635163d962828b932145d1c132a2..c4c42ae50d5045900c9ac53cad6a4fb8ce47d5cf 100644 (file)
@@ -39,6 +39,8 @@
 #include <cairo-win32.h>
 #include <cairoint.h>
 
+#define WIN32_FONT_LOGICAL_SCALE 32
+
 typedef struct _cairo_win32_surface {
     cairo_surface_t base;
 
index 3d9ddd11cc53afedfdf37c4ce113c0c51f03aa6f..0a72a6fbbd0d229fbbba93fe3e40792ba908a57f 100644 (file)
@@ -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 © 2005 Red Hat, Inc.
  * Contributor(s):
  *     Owen Taylor <otaylor@redhat.com>
  *     Stuart Parmenter <stuart@mozilla.com>
+ *     Vladimir Vukicevic <vladimir@pobox.com>
  */
 
 #include <stdio.h>
 #include "cairoint.h"
+#include "cairo-clip-private.h"
 #include "cairo-win32-private.h"
 
+/* for older SDKs */
 #ifndef SHADEBLENDCAPS
 #define SHADEBLENDCAPS  120
 #endif
@@ -59,7 +63,7 @@ static const cairo_surface_backend_t cairo_win32_surface_backend;
 cairo_status_t
 _cairo_win32_print_gdi_error (const char *context)
 {
-    LPSTR lpMsgBuf;
+    void *lpMsgBuf;
     DWORD last_error = GetLastError ();
 
     if (!FormatMessageA (FORMAT_MESSAGE_ALLOCATE_BUFFER | 
@@ -67,11 +71,11 @@ _cairo_win32_print_gdi_error (const char *context)
                         NULL,
                         last_error,
                         MAKELANGID (LANG_NEUTRAL, SUBLANG_DEFAULT),
-                        (LPSTR) &lpMsgBuf,
+                        (LPTSTR) &lpMsgBuf,
                         0, NULL)) {
        fprintf (stderr, "%s: Unknown GDI error", context);
     } else {
-       fprintf (stderr, "%s: %s", context, lpMsgBuf);
+       fprintf (stderr, "%s: %s", context, (char *)lpMsgBuf);
        
        LocalFree (lpMsgBuf);
     }
@@ -143,7 +147,7 @@ _create_dc_and_bitmap (cairo_win32_surface_t *surface,
     /* We can't create real RGB24 bitmaps because something seems to
      * 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).
+     * (and creating one with masks).  So treat them like 32bpp.
      */
     case CAIRO_FORMAT_RGB24:
     case CAIRO_FORMAT_ARGB32:
@@ -266,7 +270,7 @@ _cairo_win32_surface_create_for_dc (HDC             original_dc,
     surface = malloc (sizeof (cairo_win32_surface_t));
     if (surface == NULL) {
        _cairo_error (CAIRO_STATUS_NO_MEMORY);
-       return (cairo_surface_t *)(&_cairo_surface_nil);
+       return &_cairo_surface_nil;
     }
 
     status = _create_dc_and_bitmap (surface, original_dc, format,
@@ -312,10 +316,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_t *)(&_cairo_surface_nil);
+       return &_cairo_surface_nil;
     } else {
        _cairo_error (status);
-       return (cairo_surface_t *)(&_cairo_surface_nil);
+       return &_cairo_surface_nil;
     }
 }
 
@@ -331,27 +335,6 @@ _cairo_win32_surface_create_similar (void      *abstract_src,
     return _cairo_win32_surface_create_for_dc (src->dc, format, width, height);
 }
 
-/**
- * _cairo_win32_surface_create_dib:
- * @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, or %NULL if it couldn't
- *   be created (probably because of lack of memory)
- **/
-cairo_surface_t *
-cairo_win32_surface_create_dib (cairo_format_t format,
-                               int            width,
-                               int            height)
-{
-    return _cairo_win32_surface_create_for_dc (NULL, format, width, height);
-}
-
 static cairo_status_t
 _cairo_win32_surface_finish (void *abstract_surface)
 {
@@ -411,8 +394,6 @@ _cairo_win32_surface_get_subimage (cairo_win32_surface_t  *surface,
        FillRect(local->dc, &r, (HBRUSH)GetStockObject(WHITE_BRUSH));
     }
 
-    GdiFlush();
-
     *local_out = local;
     
     return CAIRO_STATUS_SUCCESS;
@@ -436,8 +417,6 @@ _cairo_win32_surface_acquire_source_image (void                    *abstract_sur
     cairo_status_t status;
 
     if (surface->image) {
-       GdiFlush();
-
        *image_out = (cairo_image_surface_t *)surface->image;
        *image_extra = NULL;
 
@@ -618,7 +597,7 @@ _composite_alpha_blend (cairo_win32_surface_t *dst,
        if (VER_PLATFORM_WIN32_WINDOWS != os.dwPlatformId ||
            os.dwMajorVersion != 4 || os.dwMinorVersion != 10)
        {
-           HMODULE msimg32_dll = LoadLibraryA("msimg32");
+           HMODULE msimg32_dll = LoadLibrary ("msimg32");
            
            if (msimg32_dll != NULL)
                alpha_blend = (cairo_alpha_blend_func_t)GetProcAddress (msimg32_dll,
@@ -645,7 +624,7 @@ _composite_alpha_blend (cairo_win32_surface_t *dst,
                      src_x, src_y,
                      width, height,
                      blend_function))
-       return _cairo_win32_print_gdi_error ("_cairo_win32_surface_composite(AlphaBlend)");
+       return _cairo_win32_print_gdi_error ("_cairo_win32_surface_composite");
     
     return CAIRO_STATUS_SUCCESS;
 }
@@ -671,7 +650,7 @@ _cairo_win32_surface_composite (cairo_operator_t    op,
     int integer_transform;
     int itx, ity;
 
-    if (pattern->type != CAIRO_PATTERN_SURFACE ||
+    if (pattern->type != CAIRO_PATTERN_TYPE_SURFACE ||
        pattern->extend != CAIRO_EXTEND_NONE)
        return CAIRO_INT_STATUS_UNSUPPORTED;
 
@@ -679,7 +658,7 @@ _cairo_win32_surface_composite (cairo_operator_t    op,
        /* FIXME: When we fully support RENDER style 4-channel
         * masks we need to check r/g/b != 1.0.
         */
-       if (mask_pattern->type != CAIRO_PATTERN_SOLID)
+       if (mask_pattern->type != CAIRO_PATTERN_TYPE_SOLID)
            return CAIRO_INT_STATUS_UNSUPPORTED;
 
        alpha = ((cairo_solid_pattern_t *)mask_pattern)->color.alpha_short >> 8;
@@ -734,7 +713,7 @@ _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(BitBlt)");
+           return _cairo_win32_print_gdi_error ("_cairo_win32_surface_composite");
 
        return CAIRO_STATUS_SUCCESS;
        
@@ -1000,6 +979,141 @@ _cairo_win32_surface_flush (void *abstract_surface)
     return _cairo_surface_reset_clip (abstract_surface);
 }
 
+#define STACK_GLYPH_SIZE 256
+
+static cairo_int_status_t
+_cairo_win32_surface_show_glyphs (void                 *surface,
+                                 cairo_operator_t       op,
+                                 cairo_pattern_t       *source,
+                                 const cairo_glyph_t   *glyphs,
+                                 int                    num_glyphs,
+                                 cairo_scaled_font_t   *scaled_font)
+{
+    cairo_win32_surface_t *dst = surface;
+
+    WORD glyph_buf_stack[STACK_GLYPH_SIZE];
+    WORD *glyph_buf = glyph_buf_stack;
+    int dx_buf_stack[STACK_GLYPH_SIZE];
+    int *dx_buf = dx_buf_stack;
+
+    BOOL win_result = 0;
+    int i;
+    double last_y = glyphs[0].y;
+
+    cairo_solid_pattern_t *solid_pattern;
+    COLORREF color;
+    int output_count = 0;
+
+    cairo_matrix_t device_to_logical;
+
+    /* We can only handle win32 fonts */
+    if (cairo_scaled_font_get_type (scaled_font) != CAIRO_FONT_TYPE_WIN32)
+       return CAIRO_INT_STATUS_UNSUPPORTED;
+
+    /* We can only handle opaque solid color sources */
+    if (!_cairo_pattern_is_opaque_solid(source))
+       return CAIRO_INT_STATUS_UNSUPPORTED;
+
+    /* We can only handle operator SOURCE or OVER with the destination
+     * having no alpha */
+    if ((op != CAIRO_OPERATOR_SOURCE && op != CAIRO_OPERATOR_OVER) || 
+       (dst->format != CAIRO_FORMAT_RGB24))
+       return CAIRO_INT_STATUS_UNSUPPORTED;
+
+    /* If we have a fallback mask clip set on the dst, we have
+     * to go through the fallback path */
+    if (dst->base.clip &&
+       (dst->base.clip->mode != CAIRO_CLIP_MODE_REGION ||
+        dst->base.clip->surface != NULL))
+       return CAIRO_INT_STATUS_UNSUPPORTED;
+
+    solid_pattern = (cairo_solid_pattern_t *)source;
+    color = RGB(((int)solid_pattern->color.red_short) >> 8,
+               ((int)solid_pattern->color.green_short) >> 8,
+               ((int)solid_pattern->color.blue_short) >> 8);
+
+    cairo_win32_scaled_font_get_device_to_logical(scaled_font, &device_to_logical);
+
+    SaveDC(dst->dc);
+
+    cairo_win32_scaled_font_select_font(scaled_font, dst->dc);
+    SetTextColor(dst->dc, color);
+    SetTextAlign(dst->dc, TA_BASELINE | TA_LEFT);
+    SetBkMode(dst->dc, TRANSPARENT);
+
+    if (num_glyphs > STACK_GLYPH_SIZE) {
+       glyph_buf = (WORD *)malloc(num_glyphs * sizeof(WORD));
+       dx_buf = (int *)malloc(num_glyphs * sizeof(int));
+    }
+
+    for (i = 0; i < num_glyphs; ++i) {
+       output_count++;
+
+       glyph_buf[i] = glyphs[i].index;
+       if (i == num_glyphs - 1)
+           dx_buf[i] = 0;
+       else
+           dx_buf[i] = floor(((glyphs[i+1].x - glyphs[i].x) * WIN32_FONT_LOGICAL_SCALE) + 0.5);
+
+
+       if (i == num_glyphs - 1 || glyphs[i].y != glyphs[i+1].y) {
+           const int offset = (i - output_count) + 1;
+           double user_x = glyphs[offset].x;
+           double user_y = last_y;
+           double logical_x, logical_y;
+
+           cairo_matrix_transform_point(&device_to_logical,
+                                        &user_x, &user_y);
+
+           logical_x = floor(user_x + 0.5);
+           logical_y = floor(user_y + 0.5);
+
+           win_result = ExtTextOutW(dst->dc,
+                                    logical_x,
+                                    logical_y,
+                                    ETO_GLYPH_INDEX,
+                                    NULL,
+                                    glyph_buf + offset,
+                                    output_count,
+                                    dx_buf + offset);
+           if (!win_result) {
+               _cairo_win32_print_gdi_error("_cairo_win32_surface_show_glyphs(ExtTextOutW failed)");
+               goto FAIL;
+           }
+
+           output_count = 0;
+
+           if (i < num_glyphs - 1)
+               last_y = glyphs[i+1].y;
+       } else {
+           last_y = glyphs[i].y;
+       }
+    }
+
+FAIL:
+    RestoreDC(dst->dc, -1);
+
+    if (glyph_buf != glyph_buf_stack) {
+       free(glyph_buf);
+       free(dx_buf);
+    }
+    return (win_result) ? CAIRO_STATUS_SUCCESS : CAIRO_INT_STATUS_UNSUPPORTED;
+}  
+
+#undef STACK_GLYPH_SIZE
+
+/**
+ * cairo_win32_surface_create:
+ * @hdc: the DC to create a surface for
+ * 
+ * Creates a cairo surface that targets the given DC.  The DC will be
+ * queried for its initial clip extents, and this will be used as the
+ * size of the cairo surface.  Also, if the DC is a raster DC, it will
+ * be queried for its pixel format and the cairo surface format will
+ * be set appropriately.
+ * 
+ * Return value: the newly created surface
+ **/
 cairo_surface_t *
 cairo_win32_surface_create (HDC hdc)
 {
@@ -1014,7 +1128,7 @@ cairo_win32_surface_create (HDC hdc)
        _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_t *)(&_cairo_surface_nil);
+       return &_cairo_surface_nil;
     }
 
     if (GetDeviceCaps(hdc, TECHNOLOGY) == DT_RASDISPLAY) {
@@ -1032,7 +1146,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_t *)(&_cairo_surface_nil);
+           return &_cairo_surface_nil;
        }
     } else {
        format = CAIRO_FORMAT_RGB24;
@@ -1041,7 +1155,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_t *)(&_cairo_surface_nil);
+       return &_cairo_surface_nil;
     }
 
     surface->image = NULL;
@@ -1075,6 +1189,28 @@ cairo_win32_surface_create (HDC hdc)
     return (cairo_surface_t *)surface;
 }
 
+/**
+ * cairo_win32_surface_create_with_dib:
+ * @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
+ *
+ **/
+cairo_surface_t *
+cairo_win32_surface_create_with_dib (cairo_format_t format,
+                                     int           width,
+                                     int           height)
+{
+    return _cairo_win32_surface_create_for_dc (NULL, format, width, height);
+}
+
+
 /**
  * _cairo_surface_is_win32:
  * @surface: a #cairo_surface_t
@@ -1115,6 +1251,7 @@ cairo_win32_surface_get_dc (cairo_surface_t *surface)
 }
 
 static const cairo_surface_backend_t cairo_win32_surface_backend = {
+    CAIRO_SURFACE_TYPE_WIN32,
     _cairo_win32_surface_create_similar,
     _cairo_win32_surface_finish,
     _cairo_win32_surface_acquire_source_image,
@@ -1141,9 +1278,9 @@ static const cairo_surface_backend_t cairo_win32_surface_backend = {
     NULL, /* mask */
     NULL, /* stroke */
     NULL, /* fill */
-    NULL, /* show_glyphs */
+    _cairo_win32_surface_show_glyphs,
 
-    NULL, /* snapshot */
+    NULL  /* snapshot */
 };
 
 /*
index 145881df2b34776afed3ac840b9a39c802febd18..31a7fdc73742e55c7cb6f85c09b9301f8224e795 100644 (file)
@@ -48,9 +48,9 @@ cairo_public cairo_surface_t *
 cairo_win32_surface_create (HDC hdc);
 
 cairo_public cairo_surface_t *
-cairo_win32_surface_create_dib (cairo_format_t format,
-                               int width,
-                               int height);
+cairo_win32_surface_create_with_dib (cairo_format_t format,
+                                     int width,
+                                     int height);
 
 cairo_public HDC
 cairo_win32_surface_get_dc (cairo_surface_t *surface);
@@ -71,6 +71,14 @@ cairo_win32_scaled_font_done_font (cairo_scaled_font_t *scaled_font);
 cairo_public double
 cairo_win32_scaled_font_get_metrics_factor (cairo_scaled_font_t *scaled_font);
 
+cairo_public void
+cairo_win32_scaled_font_get_logical_to_device (cairo_scaled_font_t *scaled_font,
+                                              cairo_matrix_t *logical_to_device);
+
+cairo_public void
+cairo_win32_scaled_font_get_device_to_logical (cairo_scaled_font_t *scaled_font,
+                                              cairo_matrix_t *device_to_logical);
+
 CAIRO_END_DECLS
 
 #else  /* CAIRO_HAS_WIN32_SURFACE */
index f7e65ff0859af29803068ecd08d7aa37b28f1b5e..78eafc0fae369a45d5d72501fbedeead10b19205 100644 (file)
@@ -321,7 +321,7 @@ _CAIRO_MASK_FORMAT (cairo_format_masks_t *masks, cairo_format_t *format)
            masks->blue_mask == 0x000000ff)
        {
            *format = CAIRO_FORMAT_ARGB32;
-           return 1;
+           return TRUE;
        }
        if (masks->alpha_mask == 0x00000000 &&
            masks->red_mask == 0x00ff0000 &&
@@ -329,25 +329,25 @@ _CAIRO_MASK_FORMAT (cairo_format_masks_t *masks, cairo_format_t *format)
            masks->blue_mask == 0x000000ff)
        {
            *format = CAIRO_FORMAT_RGB24;
-           return 1;
+           return TRUE;
        }
        break;
     case 8:
        if (masks->alpha_mask == 0xff)
        {
            *format = CAIRO_FORMAT_A8;
-           return 1;
+           return TRUE;
        }
        break;
     case 1:
        if (masks->alpha_mask == 0x1)
        {
            *format = CAIRO_FORMAT_A1;
-           return 1;
+           return TRUE;
        }
        break;
     }
-    return 0;
+    return FALSE;
 }
 
 static cairo_status_t
@@ -1025,6 +1025,7 @@ _cairo_xcb_surface_get_extents (void                *abstract_surface,
 }
 
 static const cairo_surface_backend_t cairo_xcb_surface_backend = {
+    CAIRO_SURFACE_TYPE_XCB,
     _cairo_xcb_surface_create_similar,
     _cairo_xcb_surface_finish,
     _cairo_xcb_surface_acquire_source_image,
index ee0b40ac676c1b77a0ed65e1c23f4bacf40c7db8..f75426bed51634043dddaf24c51e6f9f9074e8da 100644 (file)
@@ -40,7 +40,9 @@
 #include "cairo-xlib-xrender.h"
 #include "cairo-xlib-test.h"
 #include "cairo-xlib-private.h"
+#include "cairo-clip-private.h"
 #include <X11/extensions/Xrender.h>
+#include <X11/extensions/renderproto.h>
 
 /* Xlib doesn't define a typedef, so define one ourselves */
 typedef int (*cairo_xlib_error_func_t) (Display     *display,
@@ -63,6 +65,14 @@ _cairo_surface_is_xlib (cairo_surface_t *surface);
 static cairo_bool_t
 _native_byte_order_lsb (void);
 
+static cairo_int_status_t
+_cairo_xlib_surface_show_glyphs (void                *abstract_dst,
+                                cairo_operator_t     op,
+                                cairo_pattern_t     *src_pattern,
+                                const cairo_glyph_t *glyphs,
+                                int                  num_glyphs,
+                                cairo_scaled_font_t *scaled_font);
+
 /*
  * Instead of taking two round trips for each blending request,
  * assume that if a particular drawable fails GetImage that it will
@@ -291,7 +301,7 @@ _cairo_xlib_surface_create_similar (void           *abstract_src,
     }
 
     return _cairo_xlib_surface_create_similar_with_format (abstract_src,
-                                                           format, width, height);
+                                                          format, width, height);
 }
 
 static cairo_status_t
@@ -1095,7 +1105,7 @@ _categorize_composite_operation (cairo_xlib_surface_t *dst,
     if (!dst->buggy_repeat)
        return DO_RENDER;
 
-    if (src_pattern->type == CAIRO_PATTERN_SURFACE)
+    if (src_pattern->type == CAIRO_PATTERN_TYPE_SURFACE)
     {
        cairo_surface_pattern_t *surface_pattern = (cairo_surface_pattern_t *)src_pattern;
        
@@ -1696,25 +1706,8 @@ _cairo_xlib_surface_get_font_options (void                  *abstract_surface,
     cairo_xlib_surface_t *surface = abstract_surface;
   
     *options = surface->screen_info->font_options;
-    
-    if (_surface_has_alpha (surface) && options->antialias == CAIRO_ANTIALIAS_SUBPIXEL)
-       options->antialias = CAIRO_ANTIALIAS_GRAY;
 }
 
-static cairo_int_status_t
-_cairo_xlib_surface_old_show_glyphs (cairo_scaled_font_t       *scaled_font,
-                                    cairo_operator_t            op,
-                                    cairo_pattern_t            *pattern,
-                                    void                       *abstract_surface,
-                                    int                         source_x,
-                                    int                         source_y,
-                                    int                         dest_x,
-                                    int                         dest_y,
-                                    unsigned int                width,
-                                    unsigned int                height,
-                                    const cairo_glyph_t        *glyphs,
-                                    int                         num_glyphs);
-
 static void
 _cairo_xlib_surface_scaled_font_fini (cairo_scaled_font_t *scaled_font);
 
@@ -1723,6 +1716,7 @@ _cairo_xlib_surface_scaled_glyph_fini (cairo_scaled_glyph_t *scaled_glyph,
                                       cairo_scaled_font_t  *scaled_font);
 
 static const cairo_surface_backend_t cairo_xlib_surface_backend = {
+    CAIRO_SURFACE_TYPE_XLIB,
     _cairo_xlib_surface_create_similar,
     _cairo_xlib_surface_finish,
     _cairo_xlib_surface_acquire_source_image,
@@ -1738,12 +1732,19 @@ static const cairo_surface_backend_t cairo_xlib_surface_backend = {
     _cairo_xlib_surface_set_clip_region,
     NULL, /* intersect_clip_path */
     _cairo_xlib_surface_get_extents,
-    _cairo_xlib_surface_old_show_glyphs,
+    NULL, /* old_show_glyphs */
     _cairo_xlib_surface_get_font_options,
     NULL, /* flush */
     NULL, /* mark_dirty_rectangle */
     _cairo_xlib_surface_scaled_font_fini,
     _cairo_xlib_surface_scaled_glyph_fini,
+
+    NULL, /* paint */
+    NULL, /* mask */
+    NULL, /* stroke */
+    NULL, /* fill */
+    _cairo_xlib_surface_show_glyphs,
+    NULL  /* snapshot */
 };
 
 /**
@@ -2232,8 +2233,8 @@ _cairo_xlib_surface_add_glyph (Display *dpy,
      *  sitting around for x and y. 
      */
 
-    glyph_info.x = -(int) glyph_surface->base.device_x_offset;
-    glyph_info.y = -(int) glyph_surface->base.device_y_offset;
+    glyph_info.x = - (int) floor(glyph_surface->base.device_x_offset + 0.5);
+    glyph_info.y = - (int) floor(glyph_surface->base.device_y_offset + 0.5);
     glyph_info.width = glyph_surface->width;
     glyph_info.height = glyph_surface->height;
     glyph_info.xOff = 0;
@@ -2314,14 +2315,13 @@ _cairo_xlib_surface_add_glyph (Display *dpy,
 #define N_STACK_BUF 1024
 
 static cairo_status_t
-_cairo_xlib_surface_old_show_glyphs8  (cairo_scaled_font_t    *scaled_font,
-                                      cairo_operator_t        op,
-                                      cairo_xlib_surface_t   *src,
-                                      cairo_xlib_surface_t   *self,
-                                      int                     source_x,
-                                      int                     source_y,
-                                      const cairo_glyph_t    *glyphs,
-                                      int                     num_glyphs)
+_cairo_xlib_surface_show_glyphs8  (cairo_xlib_surface_t *dst,
+                                   cairo_operator_t op,
+                                   cairo_xlib_surface_t *src,
+                                   int src_x_offset, int src_y_offset,
+                                   const cairo_glyph_t *glyphs,
+                                   int num_glyphs,
+                                   cairo_scaled_font_t *scaled_font)
 {
     cairo_xlib_surface_font_private_t *font_private = scaled_font->surface_private;
     XGlyphElt8 *elts = NULL;
@@ -2360,13 +2360,13 @@ _cairo_xlib_surface_old_show_glyphs8  (cairo_scaled_font_t    *scaled_font,
        lastY = thisY;
     }
 
-    XRenderCompositeText8  (self->dpy,
+    XRenderCompositeText8  (dst->dpy,
                            _render_operator (op),
                            src->src_picture,
-                           self->dst_picture,
+                           dst->dst_picture,
                            font_private->format,
-                           source_x + elts[0].xOff, source_y + elts[0].yOff,
-                           0, 0,
+                            src_x_offset + elts[0].xOff, src_y_offset + elts[0].yOff,
+                            elts[0].xOff, elts[0].yOff,
                            elts, num_glyphs);
 
     if (elts != stack_elts)
@@ -2376,14 +2376,13 @@ _cairo_xlib_surface_old_show_glyphs8  (cairo_scaled_font_t    *scaled_font,
 }
 
 static cairo_status_t
-_cairo_xlib_surface_old_show_glyphs16 (cairo_scaled_font_t    *scaled_font,
-                                      cairo_operator_t        op,
-                                      cairo_xlib_surface_t   *src,
-                                      cairo_xlib_surface_t   *self,
-                                      int                     source_x,
-                                      int                     source_y,
-                                      const cairo_glyph_t    *glyphs,
-                                      int                     num_glyphs)
+_cairo_xlib_surface_show_glyphs16 (cairo_xlib_surface_t *dst,
+                                   cairo_operator_t op,
+                                   cairo_xlib_surface_t *src,
+                                   int src_x_offset, int src_y_offset,
+                                   const cairo_glyph_t *glyphs,
+                                   int num_glyphs,
+                                   cairo_scaled_font_t *scaled_font)
 {
     cairo_xlib_surface_font_private_t *font_private = scaled_font->surface_private;
     XGlyphElt16 *elts = NULL;
@@ -2422,13 +2421,13 @@ _cairo_xlib_surface_old_show_glyphs16 (cairo_scaled_font_t    *scaled_font,
        lastY = thisY;
     }
 
-    XRenderCompositeText16 (self->dpy,
+    XRenderCompositeText16 (dst->dpy,
                            _render_operator (op),
                            src->src_picture,
-                           self->dst_picture,
+                           dst->dst_picture,
                            font_private->format,
-                           source_x + elts[0].xOff, source_y + elts[0].yOff,
-                           0, 0,
+                            src_x_offset + elts[0].xOff, src_y_offset + elts[0].yOff,
+                            elts[0].xOff, elts[0].yOff,
                            elts, num_glyphs);
 
     if (elts != stack_elts)
@@ -2438,14 +2437,13 @@ _cairo_xlib_surface_old_show_glyphs16 (cairo_scaled_font_t    *scaled_font,
 }
 
 static cairo_status_t
-_cairo_xlib_surface_old_show_glyphs32 (cairo_scaled_font_t    *scaled_font,
-                                      cairo_operator_t        op,
-                                      cairo_xlib_surface_t   *src,
-                                      cairo_xlib_surface_t   *self,
-                                      int                     source_x,
-                                      int                     source_y,
-                                      const cairo_glyph_t    *glyphs,
-                                      int                     num_glyphs)
+_cairo_xlib_surface_show_glyphs32 (cairo_xlib_surface_t *dst,
+                                   cairo_operator_t op,
+                                   cairo_xlib_surface_t *src,
+                                   int src_x_offset, int src_y_offset,
+                                   const cairo_glyph_t *glyphs,
+                                   int num_glyphs,
+                                   cairo_scaled_font_t *scaled_font)
 {
     cairo_xlib_surface_font_private_t *font_private = scaled_font->surface_private;
     XGlyphElt32 *elts = NULL;
@@ -2484,13 +2482,13 @@ _cairo_xlib_surface_old_show_glyphs32 (cairo_scaled_font_t    *scaled_font,
        lastY = thisY;
     }
 
-    XRenderCompositeText32 (self->dpy,
+    XRenderCompositeText32 (dst->dpy,
                            _render_operator (op),
                            src->src_picture,
-                           self->dst_picture,
+                           dst->dst_picture,
                            font_private->format,
-                           source_x + elts[0].xOff, source_y + elts[0].yOff,
-                           0, 0,
+                            src_x_offset + elts[0].xOff, src_y_offset + elts[0].yOff,
+                            elts[0].xOff, elts[0].yOff,
                            elts, num_glyphs);
 
     if (elts != stack_elts)
@@ -2499,62 +2497,121 @@ _cairo_xlib_surface_old_show_glyphs32 (cairo_scaled_font_t    *scaled_font,
     return CAIRO_STATUS_SUCCESS;
 }
 
+typedef cairo_status_t (*cairo_xlib_surface_show_glyphs_func_t)
+    (cairo_xlib_surface_t *, cairo_operator_t, cairo_xlib_surface_t *, int, int,
+     const cairo_glyph_t *, int, cairo_scaled_font_t *);
+
 static cairo_int_status_t
-_cairo_xlib_surface_old_show_glyphs (cairo_scaled_font_t       *scaled_font,
-                                    cairo_operator_t            op,
-                                    cairo_pattern_t            *pattern,
-                                    void                       *abstract_surface,
-                                    int                         source_x,
-                                    int                         source_y,
-                                    int                         dest_x,
-                                    int                         dest_y,
-                                    unsigned int                width,
-                                    unsigned int                height,
-                                    const cairo_glyph_t        *glyphs,
-                                    int                         num_glyphs)
+_cairo_xlib_surface_show_glyphs (void                *abstract_dst,
+                                cairo_operator_t     op,
+                                cairo_pattern_t     *src_pattern,
+                                const cairo_glyph_t *glyphs,
+                                int                  num_glyphs,
+                                cairo_scaled_font_t *scaled_font)
 {
-    cairo_surface_attributes_t attributes;
-    cairo_int_status_t         status;
-    cairo_xlib_surface_t *self = abstract_surface;
-    cairo_xlib_surface_t *src;
+    cairo_int_status_t status;
+    cairo_xlib_surface_t *dst = (cairo_xlib_surface_t*) abstract_dst;
+
     composite_operation_t operation;
+    cairo_surface_attributes_t attributes;
+    cairo_xlib_surface_t *src = NULL;
+
+    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;
     unsigned long max_index = 0;
-    
 
-    if (!CAIRO_SURFACE_RENDER_HAS_COMPOSITE_TEXT (self) || !self->format)
+    cairo_xlib_surface_show_glyphs_func_t show_glyphs_func;
+
+    cairo_pattern_union_t solid_pattern;
+
+    if (!CAIRO_SURFACE_RENDER_HAS_COMPOSITE_TEXT (dst) || !dst->format)
        return CAIRO_INT_STATUS_UNSUPPORTED;
 
-    operation = _categorize_composite_operation (self, op, pattern, TRUE);
+    /* Just let unbounded operators go through the fallback code
+     * instead of trying to do the fixups here */
+    if (!_cairo_operator_bounded_by_mask (op))
+        return CAIRO_INT_STATUS_UNSUPPORTED;
+
+    /* Render <= 0.10 seems to have a bug with PictOpSrc and glyphs --
+     * the solid source seems to be multiplied by the glyph mask, and
+     * then the entire thing is copied to the destination surface,
+     * including the fully transparent "background" of the rectangular
+     * glyph surface. */
+    if (op == CAIRO_OPERATOR_SOURCE &&
+        !CAIRO_SURFACE_RENDER_AT_LEAST(dst, 0, 11))
+        return CAIRO_INT_STATUS_UNSUPPORTED;
+
+    /* We can only use our code if we either have no clip or
+     * have a real native clip region set.  If we're using
+     * fallback clip masking, we have to go through the full
+     * fallback path.
+     */
+    if (dst->base.clip &&
+        (dst->base.clip->mode != CAIRO_CLIP_MODE_REGION ||
+         dst->base.clip->surface != NULL))
+        return CAIRO_INT_STATUS_UNSUPPORTED;
+
+    operation = _categorize_composite_operation (dst, op, src_pattern, TRUE);
     if (operation == DO_UNSUPPORTED)
        return CAIRO_INT_STATUS_UNSUPPORTED;
-    
+
     font_private = scaled_font->surface_private;
     if ((scaled_font->surface_backend != NULL &&
         scaled_font->surface_backend != &cairo_xlib_surface_backend) ||
-       (font_private != NULL && font_private->dpy != self->dpy))
+       (font_private != NULL && font_private->dpy != dst->dpy))
        return CAIRO_INT_STATUS_UNSUPPORTED;
 
-    status = _cairo_pattern_acquire_surface (pattern, &self->base,
-                                            source_x, source_y, width, height,
-                                            (cairo_surface_t **) &src,
-                                            &attributes);
+    /* PictOpClear doesn't seem to work with CompositeText; it seems to ignore
+     * the mask (the glyphs).  This code below was executed as a side effect
+     * of going through the _clip_and_composite fallback code for old_show_glyphs,
+     * so PictOpClear was never used with CompositeText before.
+     */
+    if (op == CAIRO_OPERATOR_CLEAR) {
+       _cairo_pattern_init_solid (&solid_pattern.solid, CAIRO_COLOR_WHITE);
+       src_pattern = &solid_pattern.base;
+       op = CAIRO_OPERATOR_DEST_OUT;
+    }
+
+    if (src_pattern->type == CAIRO_PATTERN_TYPE_SOLID) {
+        status = _cairo_pattern_acquire_surface (src_pattern, &dst->base,
+                                                 0, 0, 1, 1,
+                                                 (cairo_surface_t **) &src,
+                                                 &attributes);
+    } else {
+        cairo_rectangle_t glyph_extents;
+
+        status = _cairo_scaled_font_glyph_device_extents (scaled_font,
+                                                          glyphs,
+                                                          num_glyphs,
+                                                          &glyph_extents);
+        if (status)
+            return status;
+
+        status = _cairo_pattern_acquire_surface (src_pattern, &dst->base,
+                                                 glyph_extents.x, glyph_extents.y,
+                                                 glyph_extents.width, glyph_extents.height,
+                                                 (cairo_surface_t **) &src,
+                                                 &attributes);
+    }
+
     if (status)
-       return status;
+        goto FAIL;
 
-    operation = _recategorize_composite_operation (self, op, src, &attributes, TRUE);
+    operation = _recategorize_composite_operation (dst, op, src, &attributes, TRUE);
     if (operation == DO_UNSUPPORTED) {
        status = CAIRO_INT_STATUS_UNSUPPORTED;
        goto FAIL;
     }
-       
+
     status = _cairo_xlib_surface_set_attributes (src, &attributes);
     if (status)
-       goto FAIL;
-    
-    /* Send all unsent glyphs to the server */
+        goto FAIL;
+
+    /* Send all unsent glyphs to the server, and count the max of the glyph indices */
     for (i = 0; i < num_glyphs; i++) {
        if (glyphs[i].index > max_index)
            max_index = glyphs[i].index;
@@ -2565,47 +2622,44 @@ _cairo_xlib_surface_old_show_glyphs (cairo_scaled_font_t        *scaled_font,
        if (status != CAIRO_STATUS_SUCCESS)
            return status;
        if (scaled_glyph->surface_private == NULL) {
-           _cairo_xlib_surface_add_glyph (self->dpy, scaled_font, scaled_glyph);
+           _cairo_xlib_surface_add_glyph (dst->dpy, scaled_font, scaled_glyph);
            scaled_glyph->surface_private = (void *) 1;
        }
     }
-    
-    _cairo_xlib_surface_ensure_dst_picture (self);
-    /* Call the appropriate sub-function. */
-
-    if (max_index < 256)
-       status = _cairo_xlib_surface_old_show_glyphs8 (scaled_font, op, src, self,
-                                                  source_x + attributes.x_offset - dest_x,
-                                                  source_y + attributes.y_offset - dest_y, 
-                                                  glyphs, num_glyphs);
-    else if (max_index < 65536)
-       status = _cairo_xlib_surface_old_show_glyphs16 (scaled_font, op, src, self,
-                                                   source_x + attributes.x_offset - dest_x,
-                                                   source_y + attributes.y_offset - dest_y, 
-                                                   glyphs, num_glyphs);
-    else 
-       status = _cairo_xlib_surface_old_show_glyphs32 (scaled_font, op, src, self,
-                                                   source_x + attributes.x_offset - dest_x,
-                                                   source_y + attributes.y_offset - dest_y, 
-                                                   glyphs, num_glyphs);
-
-    if (status == CAIRO_STATUS_SUCCESS && !_cairo_operator_bounded_by_mask (op)) {
-       cairo_rectangle_t   extents;
-       status = _cairo_scaled_font_glyph_device_extents (scaled_font,
-                                                         glyphs,
-                                                         num_glyphs,
-                                                         &extents);
-       if (status == CAIRO_STATUS_SUCCESS)
-           status = _cairo_surface_composite_shape_fixup_unbounded 
-                       (&self->base, &attributes, src->width, src->height,
-                        extents.width, extents.height,
-                        source_x, source_y,
-                        dest_x - extents.x, dest_y - extents.y,
-                        dest_x, dest_y,
-                        width, height);
+
+    _cairo_xlib_surface_ensure_dst_picture (dst);
+
+    max_chunk_size = XMaxRequestSize (dst->dpy);
+    if (max_index < 256) {
+       max_chunk_size -= sz_xRenderCompositeGlyphs8Req;
+       show_glyphs_func = _cairo_xlib_surface_show_glyphs8;
+    } else if (max_index < 65536) {
+       max_chunk_size -= sz_xRenderCompositeGlyphs16Req;
+       show_glyphs_func = _cairo_xlib_surface_show_glyphs16;
+    } else {
+       max_chunk_size -= sz_xRenderCompositeGlyphs32Req;
+       show_glyphs_func = _cairo_xlib_surface_show_glyphs32;
     }
- FAIL:
-    _cairo_pattern_release_surface (pattern, &src->base, &attributes);
-    
+    max_chunk_size /= sz_xGlyphElt;
+
+    for (glyphs_remaining = num_glyphs, glyphs_chunk = glyphs;
+        glyphs_remaining;
+        glyphs_remaining -= chunk_size, glyphs_chunk += chunk_size)
+    {
+       chunk_size = MIN (glyphs_remaining, max_chunk_size);
+
+       status = show_glyphs_func (dst, op, src,
+                                   attributes.x_offset, attributes.y_offset,
+                                   glyphs_chunk, chunk_size, scaled_font);
+       if (status != CAIRO_STATUS_SUCCESS)
+           break;
+    }
+
+  FAIL:
+    if (src)
+        _cairo_pattern_release_surface (src_pattern, &src->base, &attributes);
+    if (src_pattern == &solid_pattern.base)
+       _cairo_pattern_fini (&solid_pattern.base);
     return status;
 }
+
index 44b986c7f3e92e3daccad6c5c95bad3bc6131f74..37e1dfd3bfac883db5ab51f0e29da49f781f4020 100644 (file)
@@ -45,7 +45,7 @@
 
 CAIRO_BEGIN_DECLS
 
-void
+cairo_public void
 cairo_test_xlib_disable_render (void);
 
 CAIRO_END_DECLS
index 60ab8208ddc59574d3213c5fe01a9b1e9bc957cf..8401ca1c68345ca942126158b4fab8c20bbf5efb 100644 (file)
@@ -324,29 +324,6 @@ cairo_restore (cairo_t *cr)
 }
 slim_hidden_def(cairo_restore);
 
-/**
- * moz_cairo_set_target:
- * @cr: a #cairo_t
- * @target: a #cairo_surface_t
- *
- * Change the destination surface of rendering to @cr to @target.
- * @target must not be %NULL, or an error will be set on @cr.
- */
-void
-moz_cairo_set_target (cairo_t *cr, cairo_surface_t *target)
-{
-    if (cr->status)
-        return;
-
-    if (target == NULL) {
-        _cairo_set_error (cr, CAIRO_STATUS_NULL_POINTER);
-        return;
-    }
-
-    _moz_cairo_gstate_set_target (cr->gstate, target);
-}
-slim_hidden_def(moz_cairo_set_target);
-
 /**
  * cairo_push_group:
  * @cr: a cairo context
@@ -402,8 +379,13 @@ cairo_push_group_with_content (cairo_t *cr, cairo_content_t content)
        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);
+     * the same location on the parent surface -- when we pop_group this,
+     * the source pattern will get fixed up for the appropriate target surface
+     * device offsets, so we want to set our own surface offsets from /that/,
+     * and not from the device origin. */
+    cairo_surface_set_device_offset (group_surface,
+                                     cr->gstate->target->device_x_offset - extents.x,
+                                     cr->gstate->target->device_y_offset - extents.y);
 
     /* create a new gstate for the redirect */
     cairo_save (cr);
@@ -2278,6 +2260,9 @@ cairo_show_glyphs (cairo_t *cr, cairo_glyph_t *glyphs, int num_glyphs)
     if (cr->status)
        return;
 
+    if (num_glyphs == 0)
+       return;
+
     cr->status = _cairo_gstate_show_glyphs (cr->gstate, glyphs, num_glyphs);
     if (cr->status)
        _cairo_set_error (cr, cr->status);
@@ -2527,10 +2512,14 @@ cairo_get_target (cairo_t *cr)
 /**
  * cairo_get_group_target:
  * @cr: a cairo context
- * 
+ * @dx: device offset x value from cr's original target
+ * @dy: device offset y value from cr's original target
+ *
  * Gets the target surface for the current transparency group
  * started by the last cairo_push_group() call on the cairo
- * context.
+ * context.  The offset between this surface and the cairo
+ * context's original target surface is also returned if
+ * dx and/or dy are not NULL.
  *
  * This function may return NULL if there is no transparency
  * group on the target.
@@ -2540,12 +2529,21 @@ cairo_get_target (cairo_t *cr)
  * cairo_surface_reference().
  **/
 cairo_surface_t *
-cairo_get_group_target (cairo_t *cr)
+cairo_get_group_target (cairo_t *cr, double *dx, double *dy)
 {
+    cairo_surface_t *gsurf;
+
     if (cr->status)
        return (cairo_surface_t*) &_cairo_surface_nil;
 
-    return _cairo_gstate_get_target (cr->gstate);
+    gsurf = _cairo_gstate_get_target (cr->gstate);
+    if (!gsurf)
+        return NULL;
+
+    if (dx || dy)
+        _cairo_gstate_get_target_offsets_from_original (cr->gstate, dx, dy);
+
+    return gsurf;
 }
 
 /**
index d848efa322b100e686df56714cb0e892af0c043d..3b4b3ccabca25fa2ecd5085e053fb6ff8e965dd9 100644 (file)
@@ -272,9 +272,6 @@ cairo_save (cairo_t *cr);
 cairo_public void
 cairo_restore (cairo_t *cr);
 
-cairo_public void
-moz_cairo_set_target (cairo_t *cr, cairo_surface_t *target);
-
 cairo_public void
 cairo_push_group (cairo_t *cr);
 
@@ -923,6 +920,47 @@ cairo_font_face_destroy (cairo_font_face_t *font_face);
 cairo_public cairo_status_t
 cairo_font_face_status (cairo_font_face_t *font_face);
 
+/**
+ * cairo_font_type_t
+ * @CAIRO_FONT_TYPE_FT: The font is of type ft
+ * @CAIRO_FONT_TYPE_WIN32: The font is of type win32
+ * @CAIRO_FONT_TYPE_ATSUI: The font is of type atsui
+ *
+ * @cairo_font_type_t is used to describe the type of a given font
+ * face or scaled font. The font types are also known as "font
+ * backends" within cairo.
+ *
+ * The type of a font face is determined by the function used to
+ * create it, which will generally be of the form
+ * cairo_<type>_font_face_create. The font face type can be queried
+ * with cairo_font_face_get_type()
+ *
+ * The various cairo_font_face functions can be used with a font face
+ * of any type.
+ *
+ * The type of a scaled font is determined by the type of the font
+ * face passed to cairo_scaled_font_create. The scaled font type can
+ * be queried with cairo_scaled_font_get_type()
+ *
+ * The various cairo_scaled_font functions can be used with scaled
+ * fonts of any type, but some font backends also provide
+ * type-specific functions that must only be called with a scaled font
+ * of the appropriate type. These functions have names that begin with
+ * cairo_<type>_scaled_font such as cairo_ft_scaled_font_lock_face.
+ *
+ * The behavior of calling a type-specific function with a scaled font
+ * of the wrong type is undefined.
+ */
+typedef enum _cairo_font_type {
+    CAIRO_FONT_TYPE_TOY,
+    CAIRO_FONT_TYPE_FT,
+    CAIRO_FONT_TYPE_WIN32,
+    CAIRO_FONT_TYPE_ATSUI
+} cairo_font_type_t;
+
+cairo_public cairo_font_type_t
+cairo_font_face_get_type (cairo_font_face_t *font_face);
+
 cairo_public void *
 cairo_font_face_get_user_data (cairo_font_face_t          *font_face,
                               const cairo_user_data_key_t *key);
@@ -950,6 +988,9 @@ cairo_scaled_font_destroy (cairo_scaled_font_t *scaled_font);
 cairo_public cairo_status_t
 cairo_scaled_font_status (cairo_scaled_font_t *scaled_font);
 
+cairo_public cairo_font_type_t
+cairo_scaled_font_get_type (cairo_scaled_font_t *scaled_font);
+
 cairo_public void
 cairo_scaled_font_extents (cairo_scaled_font_t  *scaled_font,
                           cairo_font_extents_t *extents);
@@ -1021,7 +1062,7 @@ cairo_public cairo_surface_t *
 cairo_get_target (cairo_t *cr);
 
 cairo_public cairo_surface_t *
-cairo_get_group_target (cairo_t *cr);
+cairo_get_group_target (cairo_t *cr, double *dx, double *dy);
 
 typedef enum _cairo_path_data_type {
     CAIRO_PATH_MOVE_TO,
@@ -1144,7 +1185,7 @@ cairo_path_destroy (cairo_path_t *path);
  * A data structure for holding clip rectangles.
  */
 typedef struct _cairo_clip_rect {
-    double x, y, width, height;
+  double x, y, width, height;
 } cairo_clip_rect_t;
 
 cairo_public cairo_bool_t
@@ -1175,14 +1216,66 @@ cairo_surface_create_similar (cairo_surface_t  *other,
 cairo_public cairo_surface_t *
 cairo_surface_reference (cairo_surface_t *surface);
 
+cairo_public void
+cairo_surface_finish (cairo_surface_t *surface);
+
 cairo_public void
 cairo_surface_destroy (cairo_surface_t *surface);
 
 cairo_public cairo_status_t
 cairo_surface_status (cairo_surface_t *surface);
 
-cairo_public void
-cairo_surface_finish (cairo_surface_t *surface);
+/**
+ * cairo_surface_type_t
+ * @CAIRO_SURFACE_TYPE_IMAGE: The surface is of type image
+ * @CAIRO_SURFACE_TYPE_PDF: The surface is of type pdf
+ * @CAIRO_SURFACE_TYPE_PS: The surface is of type ps
+ * @CAIRO_SURFACE_TYPE_XLIB: The surface is of type xlib
+ * @CAIRO_SURFACE_TYPE_XCB: The surface is of type xcb
+ * @CAIRO_SURFACE_TYPE_GLITZ: The surface is of type glitz
+ * @CAIRO_SURFACE_TYPE_QUARTZ: The surface is of type quartz
+ * @CAIRO_SURFACE_TYPE_WIN32: The surface is of type win32
+ * @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_QUARTZ2: The surface is of type quartz2
+ *
+ * @cairo_surface_type_t is used to describe the type of a given
+ * surface. The surface types are also known as "backends" or "surface
+ * backends" within cairo.
+ *
+ * The type of a surface is determined by the function used to create
+ * it, which will generally be of the form cairo_<type>_surface_create,
+ * (though see cairo_surface_create_similar as well).
+ *
+ * The surface type can be queried with cairo_surface_get_type()
+ *
+ * The various cairo_surface functions can be used with surfaces of
+ * any type, but some backends also provide type-specific functions
+ * that must only be called with a surface of the appropriate
+ * type. These functions have names that begin with
+ * cairo_<type>_surface such as cairo_image_surface_get_width().
+ *
+ * The behavior of calling a type-specific function with a surface of
+ * the wrong type is undefined.
+ */
+typedef enum _cairo_surface_type {
+    CAIRO_SURFACE_TYPE_IMAGE,
+    CAIRO_SURFACE_TYPE_PDF,
+    CAIRO_SURFACE_TYPE_PS,
+    CAIRO_SURFACE_TYPE_XLIB,
+    CAIRO_SURFACE_TYPE_XCB,
+    CAIRO_SURFACE_TYPE_GLITZ,
+    CAIRO_SURFACE_TYPE_QUARTZ,
+    CAIRO_SURFACE_TYPE_WIN32,
+    CAIRO_SURFACE_TYPE_BEOS,
+    CAIRO_SURFACE_TYPE_DIRECTFB,
+    CAIRO_SURFACE_TYPE_SVG,
+    CAIRO_SURFACE_TYPE_QUARTZ2
+} cairo_surface_type_t;
+
+cairo_public cairo_surface_type_t
+cairo_surface_get_type (cairo_surface_t *surface);
 
 #if CAIRO_HAS_PNG_FUNCTIONS
 
@@ -1323,6 +1416,43 @@ cairo_pattern_destroy (cairo_pattern_t *pattern);
 cairo_public cairo_status_t
 cairo_pattern_status (cairo_pattern_t *pattern);
 
+/**
+ * cairo_pattern_type_t
+
+ * @CAIRO_PATTERN_TYPE_SOLID: The pattern is a solid (uniform)
+ * color. It may be opaque or translucent.
+ * @CAIRO_PATTERN_TYPE_SURFACE: The pattern is a based on a surface (an image).
+ * @CAIRO_PATTERN_TYPE_LINEAR: The pattern is a linear gradient.
+ * @CAIRO_PATTERN_TYPE_RADIAL: The pattern is a radial gradient.
+ *
+ * @cairo_pattern_type_t us used to describe the type of a given pattern.
+ *
+ * The type of a pattern is determined by the function used to create
+ * it. The cairo_pattern_create_rgb() and cairo_pattern_create_rgba()
+ * functions create SOLID patterns. The remaining
+ * cairo_pattern_create functions map to pattern types in obvious
+ * ways.
+ *
+ * The pattern type can be queried with cairo_pattern_get_type()
+ *
+ * Most cairo_pattern functions can be called with a pattern of any
+ * type, (though trying to change the extend or filter for a solid
+ * pattern will have no effect). A notable exception is
+ * cairo_pattern_add_color_stop_rgb() and
+ * cairo_pattern_add_color_stop_rgba() which must only be called with
+ * gradient patterns (either LINEAR or RADIAL). Otherwise the pattern
+ * will be shutdown and put into an error state.
+ */
+typedef enum _cairo_pattern_type {
+    CAIRO_PATTERN_TYPE_SOLID,
+    CAIRO_PATTERN_TYPE_SURFACE,
+    CAIRO_PATTERN_TYPE_LINEAR,
+    CAIRO_PATTERN_TYPE_RADIAL
+} cairo_pattern_type_t;
+
+cairo_public cairo_pattern_type_t
+cairo_pattern_get_type (cairo_pattern_t *pattern);
+
 cairo_public void
 cairo_pattern_add_color_stop_rgb (cairo_pattern_t *pattern,
                                  double offset,
index 15eb2890ed1c10e44186831174d7aad849cf17fe..9e9913b1b01182690ba1da6b614000781e0e2165 100644 (file)
 #include "cairo-debug.h"
 #include <pixman.h>
 
-#ifndef M_PI
-#define M_PI 3.14159265358979323846
-#endif
-
 CAIRO_BEGIN_DECLS
 
 #if __GNUC__ >= 3 && defined(__ELF__)
@@ -187,6 +183,10 @@ cairo_private void _cairo_beos_unlock(void*);
 #define TRUE 1
 #endif
 
+#ifndef M_PI
+#define M_PI 3.14159265358979323846
+#endif
+
 #define ASSERT_NOT_REACHED             \
 do {                                   \
     static const int NOT_REACHED = 0;  \
@@ -259,6 +259,14 @@ typedef enum cairo_int_status {
     CAIRO_INT_STATUS_CACHE_EMPTY
 } cairo_int_status_t;
 
+typedef enum cairo_internal_surface_type {
+    CAIRO_INTERNAL_SURFACE_TYPE_META = 0x1000,
+    CAIRO_INTERNAL_SURFACE_TYPE_PAGINATED,
+    CAIRO_INTERNAL_SURFACE_TYPE_TEST_META,
+    CAIRO_INTERNAL_SURFACE_TYPE_TEST_FALLBACK,
+    CAIRO_INTERNAL_SURFACE_TYPE_TEST_PAGINATED
+} cairo_internal_surface_type_t;
+
 typedef enum cairo_direction {
     CAIRO_DIRECTION_FORWARD,
     CAIRO_DIRECTION_REVERSE
@@ -345,7 +353,7 @@ struct _cairo_array {
 cairo_private void
 _cairo_array_init (cairo_array_t *array, int element_size);
 
-void
+cairo_private void
 _cairo_array_init_snapshot (cairo_array_t      *array,
                            const cairo_array_t *other);
 
@@ -366,7 +374,7 @@ _cairo_array_append_multiple (cairo_array_t *array,
                              const void        *elements,
                              int                num_elements);
 
-cairo_status_t
+cairo_private cairo_status_t
 _cairo_array_allocate (cairo_array_t    *array,
                       int                num_elements,
                       void             **elements);
@@ -467,6 +475,7 @@ struct _cairo_scaled_font {
 };
 
 struct _cairo_font_face {
+    /* hash_entry must be first */
     cairo_hash_entry_t hash_entry;
     cairo_status_t status;
     int ref_count;
@@ -511,6 +520,8 @@ typedef enum _cairo_scaled_glyph_info {
 } cairo_scaled_glyph_info_t;
 
 struct _cairo_scaled_font_backend {
+    cairo_font_type_t type;
+
     cairo_status_t
     (*create_toy)  (cairo_toy_font_face_t      *toy_face,
                    const cairo_matrix_t        *font_matrix,
@@ -558,6 +569,8 @@ struct _cairo_scaled_font_backend {
 };
 
 struct _cairo_font_face_backend {
+    cairo_font_type_t  type;
+
     /* The destroy() function is allowed to resurrect the font face
      * by re-referencing. This is needed for the FreeType backend.
      */
@@ -602,6 +615,8 @@ typedef struct _cairo_stroke_style {
 } cairo_stroke_style_t;
 
 struct _cairo_surface_backend {
+    cairo_surface_type_t type;
+
     cairo_surface_t *
     (*create_similar)          (void                   *surface,
                                 cairo_content_t         content,
@@ -777,7 +792,7 @@ struct _cairo_surface_backend {
 
     /* OK, I'm starting over somewhat by defining the 5 top-level
      * drawing operators for the surface backend here with consistent
-     * naming and argument-order convensions. */
+     * naming and argument-order conventions. */
     cairo_int_status_t
     (*paint)                   (void                   *surface,
                                 cairo_operator_t        op,
@@ -832,6 +847,11 @@ typedef struct _cairo_format_masks {
 struct _cairo_surface {
     const cairo_surface_backend_t *backend;
 
+    /* We allow surfaces to override the backend->type by shoving something
+     * else into surface->type. This is for "wrapper" surfaces that want to
+     * hide their internal type from the user-level API. */
+    cairo_surface_type_t type;
+
     unsigned int ref_count;
     cairo_status_t status;
     cairo_bool_t finished;
@@ -839,8 +859,6 @@ struct _cairo_surface {
 
     double device_x_offset;
     double device_y_offset;
-    double device_x_scale;
-    double device_y_scale;
 
     cairo_clip_t *clip;
 
@@ -912,13 +930,6 @@ typedef enum {
 #define CAIRO_EXTEND_GRADIENT_DEFAULT CAIRO_EXTEND_PAD
 #define CAIRO_FILTER_DEFAULT CAIRO_FILTER_BEST
 
-typedef enum {
-    CAIRO_PATTERN_SOLID,
-    CAIRO_PATTERN_SURFACE,
-    CAIRO_PATTERN_LINEAR,
-    CAIRO_PATTERN_RADIAL
-} cairo_pattern_type_t;
-
 struct _cairo_pattern {
     cairo_pattern_type_t type;
     unsigned int        ref_count;
@@ -1043,6 +1054,8 @@ _cairo_restrict_value (double *value, double min, double max);
 cairo_private cairo_fixed_t
 _cairo_fixed_from_int (int i);
 
+#define CAIRO_FIXED_ONE _cairo_fixed_from_int (1)
+
 cairo_private cairo_fixed_t
 _cairo_fixed_from_double (double d);
 
@@ -1074,9 +1087,6 @@ _cairo_gstate_destroy (cairo_gstate_t *gstate);
 cairo_private cairo_gstate_t *
 _cairo_gstate_clone (cairo_gstate_t *gstate);
 
-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);
 
@@ -1092,6 +1102,9 @@ _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 void
+_cairo_gstate_get_target_offsets_from_original (cairo_gstate_t *gstate, double *dx, double *dy);
+
 cairo_private cairo_clip_t *
 _cairo_gstate_get_clip (cairo_gstate_t *gstate);
 
@@ -1238,15 +1251,6 @@ _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,
@@ -1261,6 +1265,15 @@ _cairo_gstate_select_font_face (cairo_gstate_t *gstate,
                                cairo_font_slant_t slant, 
                                cairo_font_weight_t weight);
 
+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_set_font_size (cairo_gstate_t *gstate, 
                             double          size);
@@ -1410,13 +1423,13 @@ cairo_private cairo_status_t
 _cairo_path_fixed_init_copy (cairo_path_fixed_t *path,
                             cairo_path_fixed_t *other);
 
-cairo_path_fixed_t *
+cairo_private cairo_path_fixed_t *
 _cairo_path_fixed_create (void);
 
 cairo_private void
 _cairo_path_fixed_fini (cairo_path_fixed_t *path);
 
-void
+cairo_private void
 _cairo_path_fixed_destroy (cairo_path_fixed_t *path);
 
 cairo_private cairo_status_t
@@ -1491,11 +1504,9 @@ _cairo_path_fixed_bounds (cairo_path_fixed_t *path,
                          double *x2, double *y2);
 
 cairo_private void
-_cairo_path_fixed_offset_and_scale (cairo_path_fixed_t *path,
-                                    cairo_fixed_t offx,
-                                    cairo_fixed_t offy,
-                                    cairo_fixed_t scalex,
-                                    cairo_fixed_t scaley);
+_cairo_path_fixed_offset (cairo_path_fixed_t *path,
+                         cairo_fixed_t offx,
+                         cairo_fixed_t offy);
 
 /* cairo_path_fill.c */
 cairo_private cairo_status_t
@@ -1589,7 +1600,7 @@ _cairo_scaled_glyph_set_path (cairo_scaled_glyph_t *scaled_glyph,
                              cairo_scaled_font_t *scaled_font,
                              cairo_path_fixed_t *path);
 
-cairo_status_t
+cairo_private cairo_status_t
 _cairo_scaled_glyph_lookup (cairo_scaled_font_t *scaled_font,
                            unsigned long index,
                            cairo_scaled_glyph_info_t info,
@@ -1838,6 +1849,9 @@ _cairo_surface_composite_shape_fixup_unbounded (cairo_surface_t            *dst,
                                                unsigned int                width,
                                                unsigned int                height);
 
+cairo_private cairo_bool_t
+_cairo_surface_has_device_offset_or_scale (cairo_surface_t *surface);
+
 /* cairo_image_surface.c */
 
 #define CAIRO_FORMAT_VALID(format) ((format) >= CAIRO_FORMAT_ARGB32 && \
@@ -1855,7 +1869,7 @@ _cairo_format_from_content (cairo_content_t content);
 cairo_private cairo_content_t
 _cairo_content_from_format (cairo_format_t format);
 
-cairo_surface_t *
+cairo_private cairo_surface_t *
 _cairo_image_surface_create_for_pixman_image (pixman_image_t *pixman_image,
                                              cairo_format_t  format);
 
@@ -2113,7 +2127,7 @@ _cairo_pattern_acquire_surfaces (cairo_pattern_t      *src,
                                 cairo_surface_attributes_t *src_attributes,
                                 cairo_surface_attributes_t *mask_attributes);
 
-cairo_status_t
+cairo_private cairo_status_t
 _cairo_pattern_get_extents (cairo_pattern_t    *pattern,
                            cairo_rectangle_t   *extents);
 
@@ -2167,6 +2181,16 @@ _cairo_output_stream_write_hex_string (cairo_output_stream_t *stream,
                                       const char *data,
                                       size_t length);
 
+cairo_private void
+_cairo_output_stream_write_base85_string (cairo_output_stream_t *stream,
+                                         const char *data,
+                                         size_t length);
+
+cairo_private void *
+_cairo_compress_lzw (void *data,
+                    unsigned long data_size,
+                    unsigned long *compressed_size);
+
 cairo_private cairo_status_t
 _cairo_output_stream_vprintf (cairo_output_stream_t *stream,
                              const char *fmt, va_list ap);
@@ -2191,7 +2215,6 @@ 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)
@@ -2217,7 +2240,6 @@ 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 fe0cc6fb5caf1a6096bc871de5db02561618ad14..cb8fd92a0c666a3b96b8e0fa53d7863ce61d2b8e 100644 (file)
@@ -175,6 +175,7 @@ _test_fallback_surface_get_extents (void            *abstract_surface,
 }
 
 const cairo_surface_backend_t test_fallback_surface_backend = {
+    CAIRO_INTERNAL_SURFACE_TYPE_TEST_FALLBACK,
     _test_fallback_surface_create_similar,
     _test_fallback_surface_finish,
     _test_fallback_surface_acquire_source_image,
index bdabf31d3cffc7c54af45a0d7ae597f8b760f4f6..6d36fcab22f3eccdc9c2418d36bb1b179daa9dd5 100644 (file)
@@ -296,6 +296,7 @@ _test_meta_surface_snapshot (void *abstract_other)
 }
 
 const cairo_surface_backend_t test_meta_surface_backend = {
+    CAIRO_INTERNAL_SURFACE_TYPE_TEST_META,
     NULL, /* create_similar */
     _test_meta_surface_finish,
     _test_meta_surface_acquire_source_image,
index a73661128a280230055e210ca6d037ac95d74e21..7d2b1622408e85601533707bc670a5cc7b451132 100644 (file)
@@ -44,7 +44,6 @@
 #define M_PI 3.14159265358979323846
 #endif
 
-
 /* #define PIXMAN_CONVOLUTION */
 /* #define PIXMAN_INDEXED_FORMATS */
 
index 0238c15efa610cdaeacb48738ae836fbb22dc172..f1289b3fa4946e68419f847a2377af6c69119e62 100644 (file)
@@ -1,6 +1,4 @@
 /*
- * $Id: fbedge.c,v 1.8 2006/02/03 04:49:30 vladimir%pobox.com Exp $
- *
  * Copyright © 2004 Keith Packard
  *
  * Permission to use, copy, modify, distribute, and sell this software and its
index d361b234ebd7afd699376ce67b8e4cd043dee403..aa9ca90fa23667744b6c5af2b3c52c1922fdf3b5 100644 (file)
@@ -1,6 +1,4 @@
 /*
- * $Id: fbedgeimp.h,v 1.8 2006/02/03 04:49:30 vladimir%pobox.com Exp $
- *
  * Copyright © 2004 Keith Packard
  *
  * Permission to use, copy, modify, distribute, and sell this software and its
index 9be261e5d6c518078cf2e1f92306b9f33ed81ae1..a0917400923790e1e6b8aa87846de971d5fc874e 100644 (file)
@@ -1,6 +1,4 @@
 /*
- * $Id: fbpict.c,v 1.5 2006/02/03 04:49:30 vladimir%pobox.com Exp $
- *
  * Copyright © 2000 SuSE, Inc.
  *
  * Permission to use, copy, modify, distribute, and sell this software and its
@@ -1151,7 +1149,7 @@ fbCompositeTrans_0888xnx0888(pixman_operator_t      op,
                                setupPackedReader(ws,wt,isrc,wsrc,workingSource);
 
                                /* get to word aligned */
-                               switch(!(long)dst&3)
+                               switch(~(long)dst&3)
                                {
                                        case 1:
                                                readPackedSource(rs);
@@ -1227,7 +1225,7 @@ fbCompositeTrans_0888xnx0888(pixman_operator_t      op,
                                srcLine += srcStride;
                                w = width*3;
                                /* get to word aligned */
-                               switch(!(long)src&3)
+                               switch(~(long)src&3)
                                {
                                        case 1:
                                                rd=alphamaskCombine24(*src++, *dst)>>8;
index 8b9d12f30d050f0879eff77801761793714ef596..fbf00ed772af375ab5eef72adb29df063fb6f40d 100644 (file)
@@ -1,6 +1,4 @@
 /*
- * $Id: fbpict.h,v 1.5 2006/02/03 04:49:30 vladimir%pobox.com Exp $
- *
  * Copyright © 2000 Keith Packard
  *             2005 Lars Knoll & Zack Rusin, Trolltech
  *
index f9996d9487b1066f13df09a8e7ac8d6b06a60090..0dd836fdc054f3f6763d9ec5a2d534ad605f0118 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * $Id: fbtrap.c,v 1.8 2006/02/03 04:49:30 vladimir%pobox.com Exp $
+ * $Id: fbtrap.c,v 1.11 2006/03/17 22:24:10 vladimir%pobox.com Exp $
  *
  * Copyright © 2004 Keith Packard
  *
index 18d0c3d9747c44d9808c659f0bbf36f4d77b3115..e3e2a30b03c2e7becc3364c7f8e430df7c81b315 100644 (file)
@@ -68,7 +68,7 @@ FbFillColor (uint32_t pixel, int bits)
 
 void
 pixman_pixel_to_color (const pixman_format_t   *format,
-               pixman_bits_t   pixel,
+               const pixman_bits_t     pixel,
                pixman_color_t          *color)
 {
     uint32_t       r, g, b, a;
index 4518e62b2777a73f956c8b9cccb0dce7a60dacec..cdec492e3925ba492726e6db70b6d5f20fe5b20e 100644 (file)
@@ -1,6 +1,4 @@
 /*
- * $Id: icpixels.c,v 1.8 2006/02/03 04:49:30 vladimir%pobox.com Exp $
- *
  * Copyright © 1998 Keith Packard
  *
  * Permission to use, copy, modify, distribute, and sell this software and its
index f43fc592c53cb1713532dcad6b412dd08b3c6946..08bd0247b85f7febd555d9fdfe0f01af0ab410dc 100644 (file)
@@ -1,6 +1,4 @@
 /*
- * $Id: ictrap.c,v 1.8 2006/02/03 04:49:30 vladimir%pobox.com Exp $
- *
  * Copyright © 2002 Keith Packard
  *
  * Permission to use, copy, modify, distribute, and sell this software and its
index 103de496ebccbf52ac888129b47ec8421450c2aa..17a00e5fdfe3a841350622860cbb6857efcd1047 100644 (file)
@@ -1,77 +1,79 @@
-#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
+#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
 #if defined(USE_MMX) && !defined(__amd64__) && !defined(__x86_64__)
-#define fbHaveMMX _cairo_pixman_have_mmx
+#define fbHaveMMX _moz_cairo_pixman_have_mmx
 #endif
-#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 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
+#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
index 7798df900a8d6ef45d79c02fb31e02ca7c9c8fe9..00884e7ce9cf793988052ae580de8ebaf8829037 100644 (file)
@@ -54,8 +54,6 @@ ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
 SOFTWARE.
 
 ******************************************************************/
-/* $Id: pixman.h,v 1.11 2006/02/03 04:49:30 vladimir%pobox.com Exp $ */
-
 /* libic.h */
 
 /*
@@ -83,7 +81,7 @@ SOFTWARE.
 
 #if defined (__SVR4) && defined (__sun)
 # include <sys/int_types.h>
-#elif defined (__OpenBSD__) || defined (_AIX)
+#elif defined (__OpenBSD__) || defined (_AIX) || defined (__osf__)
 # include <inttypes.h>
 #elif defined (_MSC_VER)
   typedef __int8 int8_t;
index 5ee4fd07cc2c0e08eea7f735fecee872cc4b8911..e5660969ee7a84a037aa2c79c5fef6670a974ec8 100644 (file)
@@ -1462,7 +1462,7 @@ pixman_region_validate(badreg, pOverlap)
     } RegionInfo;
 
             int        numRects;   /* Original numRects for badreg         */
-            RegionInfo *ri;        /* DeprecatedArray of current regions                   */
+            RegionInfo *ri;        /* Array of current regions             */
             int        numRI;      /* Number of entries used in ri         */
             int        sizeRI;     /* Number of entries available in ri    */
             int        i;          /* Index into rects                     */
index 57be76372cebca073ba9dc079767112c7c29b5ec..e47c455909480346c77001da4758f2f28518c0f4 100644 (file)
@@ -44,8 +44,6 @@ ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
 SOFTWARE.
 
 ******************************************************************/
-/* $Id: pixregionint.h,v 1.8 2006/02/03 04:49:30 vladimir%pobox.com Exp $ */
-
 #ifndef _PIXREGIONINT_H_
 #define _PIXREGIONINT_H_
 
index 1c4784b10f709839d5999631fc259da41246fed6..56fcfb3e00ae452ab58c19944bbf54918de3d13e 100644 (file)
@@ -1,6 +1,4 @@
 /*
- * $Id: renderedge.c,v 1.8 2006/02/03 04:49:30 vladimir%pobox.com Exp $
- *
  * Copyright © 2004 Keith Packard
  *
  * Permission to use, copy, modify, distribute, and sell this software and its
index f6f73f34a296c3d780070a81aa65f9ee9eac6ff2..522e5034e6358268db682887f4c3a6303df19519 100644 (file)
@@ -1,6 +1,4 @@
 /*
- * $Id: renderedge.h,v 1.8 2006/02/03 04:49:30 vladimir%pobox.com Exp $
- *
  * Copyright © 2004 Keith Packard
  *
  * Permission to use, copy, modify, distribute, and sell this software and its