~ubuntu-branches/ubuntu/raring/cairo/raring

« back to all changes in this revision

Viewing changes to util/cairo-script/cairo-script-operators.c

  • Committer: Package Import Robot
  • Author(s): Chris Coulson
  • Date: 2013-01-23 21:19:34 UTC
  • mfrom: (1.3.11) (28.1.7 experimental)
  • Revision ID: package-import@ubuntu.com-20130123211934-q9qb538ujcmkliic
Tags: 1.12.10-1ubuntu1
* Merge from Debian, remaining changes:
* debian/patches/server_side_gradients.patch:
  - Don't use server side gradients, most drivers don't handle those and
    are really slow
* debian/control: Add missing libxext-dev dependency to libcairo2-dev.
  Spotted by autopkgtest.
* debian/patches/git_evince_rendering_fix.patch:
  Backport GIT commit to fix a rendering bug in evince
* debian/control, debian/libcairo2.symbols, debian/rules:
  - Disable GL backend due to LP: #725434

Show diffs side-by-side

added added

removed removed

Lines of Context:
52
52
#include <math.h>
53
53
#include <limits.h> /* INT_MAX */
54
54
#include <assert.h>
 
55
 
 
56
#if HAVE_ZLIB
55
57
#include <zlib.h>
 
58
#endif
 
59
 
 
60
#if HAVE_LZO
 
61
#include <lzo/lzo2a.h>
 
62
#endif
56
63
 
57
64
#ifdef HAVE_MMAP
58
65
# ifdef HAVE_UNISTD_H
1756
1763
    if (bytes == NULL)
1757
1764
        return NULL;
1758
1765
 
1759
 
    if (uncompress ((Bytef *) bytes, &len,
1760
 
                    (Bytef *) src->string, src->len) != Z_OK)
1761
 
    {
1762
 
        _csi_free (ctx, bytes);
1763
 
        bytes = NULL;
1764
 
    }
1765
 
    else
1766
 
    {
1767
 
        bytes[len] = '\0';
1768
 
    }
1769
 
 
 
1766
    switch (src->method) {
 
1767
    default:
 
1768
    case NONE:
 
1769
        free (bytes);
 
1770
        return NULL;
 
1771
 
 
1772
#if HAVE_ZLIB
 
1773
    case ZLIB:
 
1774
        if (uncompress ((Bytef *) bytes, &len,
 
1775
                        (Bytef *) src->string, src->len) != Z_OK)
 
1776
        {
 
1777
            _csi_free (ctx, bytes);
 
1778
            return NULL;
 
1779
        }
 
1780
        break;
 
1781
#endif
 
1782
 
 
1783
#if HAVE_LZO
 
1784
    case LZO:
 
1785
        if (lzo2a_decompress ((Bytef *) src->string, src->len,
 
1786
                              (Bytef *) bytes, &len,
 
1787
                              NULL))
 
1788
        {
 
1789
            _csi_free (ctx, bytes);
 
1790
            return NULL;
 
1791
        }
 
1792
        break;
 
1793
#endif
 
1794
    }
 
1795
 
 
1796
    bytes[len] = '\0';
1770
1797
    return bytes;
1771
1798
}
1772
1799
 
2865
2892
}
2866
2893
 
2867
2894
static csi_status_t
2868
 
_image_read_raw (csi_file_t *src,
 
2895
_image_read_raw (csi_t *ctx,
 
2896
                 csi_object_t *src,
2869
2897
                 cairo_format_t format,
2870
2898
                 int width, int height,
2871
2899
                 cairo_surface_t **image_out)
2875
2903
    int rem, len, ret, x, rowlen, instride, stride;
2876
2904
    cairo_status_t status;
2877
2905
 
2878
 
    stride = cairo_format_stride_for_width (format, width);
2879
 
    data = malloc (stride * height);
2880
 
    if (data == NULL)
2881
 
        return CAIRO_STATUS_NO_MEMORY;
2882
 
 
2883
 
    image = cairo_image_surface_create_for_data (data, format,
2884
 
                                                 width, height, stride);
2885
 
    status = cairo_surface_set_user_data (image,
2886
 
                                          (const cairo_user_data_key_t *) image,
2887
 
                                          data, free);
2888
 
    if (status) {
2889
 
        cairo_surface_destroy (image);
2890
 
        free (image);
2891
 
        return status;
 
2906
    if (width == 0 || height == 0) {
 
2907
        *image_out = cairo_image_surface_create (format, 0, 0);
 
2908
        return CSI_STATUS_SUCCESS;
 
2909
    }
 
2910
 
 
2911
    if (ctx->hooks.create_source_image != NULL) {
 
2912
        image = ctx->hooks.create_source_image (ctx->hooks.closure,
 
2913
                                                format, width, height,
 
2914
                                                0);
 
2915
 
 
2916
        stride = cairo_image_surface_get_stride (image);
 
2917
        data = cairo_image_surface_get_data (image);
 
2918
    } else {
 
2919
        stride = cairo_format_stride_for_width (format, width);
 
2920
        data = malloc (stride * height);
 
2921
        if (data == NULL)
 
2922
            return CAIRO_STATUS_NO_MEMORY;
 
2923
 
 
2924
        image = cairo_image_surface_create_for_data (data, format,
 
2925
                                                     width, height, stride);
 
2926
        status = cairo_surface_set_user_data (image,
 
2927
                                              (const cairo_user_data_key_t *) image,
 
2928
                                              data, free);
 
2929
        if (status) {
 
2930
            cairo_surface_destroy (image);
 
2931
            free (image);
 
2932
            return status;
 
2933
        }
2892
2934
    }
2893
2935
 
2894
2936
    switch (format) {
2914
2956
    }
2915
2957
    len = rowlen * height;
2916
2958
 
2917
 
    bp = data;
2918
 
    rem = len;
2919
 
    while (rem) {
2920
 
        ret = csi_file_read (src, bp, rem);
2921
 
        if (_csi_unlikely (ret == 0)) {
 
2959
    if (rowlen == instride &&
 
2960
        src->type == CSI_OBJECT_TYPE_STRING &&
 
2961
        len == src->datum.string->deflate)
 
2962
    {
 
2963
        csi_string_t *s = src->datum.string;
 
2964
        unsigned long out = s->deflate;
 
2965
 
 
2966
        switch (s->method) {
 
2967
        default:
 
2968
        case NONE:
 
2969
err_decompress:
2922
2970
            cairo_surface_destroy (image);
2923
2971
            return _csi_error (CSI_STATUS_READ_ERROR);
 
2972
 
 
2973
#if HAVE_ZLIB
 
2974
        case ZLIB:
 
2975
            if (uncompress ((Bytef *) data, &out,
 
2976
                            (Bytef *) s->string, s->len) != Z_OK)
 
2977
                goto err_decompress;
 
2978
            break;
 
2979
#endif
 
2980
 
 
2981
#if HAVE_LZO
 
2982
        case LZO:
 
2983
            if (lzo2a_decompress ((Bytef *) s->string, s->len,
 
2984
                                  (Bytef *) data, &out,
 
2985
                                  NULL))
 
2986
                goto err_decompress;
 
2987
            break;
 
2988
#endif
2924
2989
        }
2925
 
        rem -= ret;
2926
 
        bp += ret;
2927
2990
    }
2928
 
 
2929
 
    if (len != height * stride) {
2930
 
        while (--height) {
2931
 
            uint8_t *row = data + height * stride;
2932
 
 
2933
 
            /* XXX pixel conversion */
 
2991
    else
 
2992
    {
 
2993
        csi_object_t file;
 
2994
 
 
2995
        status = csi_object_as_file (ctx, src, &file);
 
2996
        if (_csi_unlikely (status)) {
 
2997
            cairo_surface_destroy (image);
 
2998
            return status;
 
2999
        }
 
3000
 
 
3001
        bp = data;
 
3002
        rem = len;
 
3003
        while (rem) {
 
3004
            ret = csi_file_read (file.datum.file, bp, rem);
 
3005
            if (_csi_unlikely (ret == 0)) {
 
3006
                cairo_surface_destroy (image);
 
3007
                return _csi_error (CSI_STATUS_READ_ERROR);
 
3008
            }
 
3009
            rem -= ret;
 
3010
            bp += ret;
 
3011
        }
 
3012
 
 
3013
        if (len != height * stride) {
 
3014
            while (--height) {
 
3015
                uint8_t *row = data + height * stride;
 
3016
 
 
3017
                /* XXX pixel conversion */
 
3018
                switch (format) {
 
3019
                case CAIRO_FORMAT_A1:
 
3020
                    for (x = rowlen; x--; ) {
 
3021
                        uint8_t byte = *--bp;
 
3022
                        row[x] = CSI_BITSWAP8_IF_LITTLE_ENDIAN (byte);
 
3023
                    }
 
3024
                    break;
 
3025
                case CAIRO_FORMAT_A8:
 
3026
                    for (x = width; x--; )
 
3027
                        row[x] = *--bp;
 
3028
                    break;
 
3029
                case CAIRO_FORMAT_RGB16_565:
 
3030
                    for (x = width; x--; ) {
 
3031
#ifdef WORDS_BIGENDIAN
 
3032
                        row[2*x + 1] = *--bp;
 
3033
                        row[2*x + 0] = *--bp;
 
3034
#else
 
3035
                        row[2*x + 0] = *--bp;
 
3036
                        row[2*x + 1] = *--bp;
 
3037
#endif
 
3038
                    }
 
3039
                    break;
 
3040
                case CAIRO_FORMAT_RGB24:
 
3041
                    for (x = width; x--; ) {
 
3042
#ifdef WORDS_BIGENDIAN
 
3043
                        row[4*x + 3] = *--bp;
 
3044
                        row[4*x + 2] = *--bp;
 
3045
                        row[4*x + 1] = *--bp;
 
3046
                        row[4*x + 0] = 0xff;
 
3047
#else
 
3048
                        row[4*x + 0] = *--bp;
 
3049
                        row[4*x + 1] = *--bp;
 
3050
                        row[4*x + 2] = *--bp;
 
3051
                        row[4*x + 3] = 0xff;
 
3052
#endif
 
3053
                    }
 
3054
                    break;
 
3055
                case CAIRO_FORMAT_RGB30:
 
3056
                case CAIRO_FORMAT_INVALID:
 
3057
                case CAIRO_FORMAT_ARGB32:
 
3058
                    /* stride == width */
 
3059
                    break;
 
3060
                }
 
3061
 
 
3062
                memset (row + instride, 0, stride - instride);
 
3063
            }
 
3064
 
 
3065
            /* need to treat last row carefully */
2934
3066
            switch (format) {
2935
3067
            case CAIRO_FORMAT_A1:
2936
3068
                for (x = rowlen; x--; ) {
2937
3069
                    uint8_t byte = *--bp;
2938
 
                    row[x] = CSI_BITSWAP8_IF_LITTLE_ENDIAN (byte);
 
3070
                    data[x] = CSI_BITSWAP8_IF_LITTLE_ENDIAN (byte);
2939
3071
                }
2940
3072
                break;
2941
3073
            case CAIRO_FORMAT_A8:
2942
3074
                for (x = width; x--; )
2943
 
                    row[x] = *--bp;
 
3075
                    data[x] = *--bp;
2944
3076
                break;
2945
3077
            case CAIRO_FORMAT_RGB16_565:
2946
3078
                for (x = width; x--; ) {
2947
3079
#ifdef WORDS_BIGENDIAN
2948
 
                    row[2*x + 1] = *--bp;
2949
 
                    row[2*x + 0] = *--bp;
 
3080
                    data[2*x + 1] = *--bp;
 
3081
                    data[2*x + 0] = *--bp;
2950
3082
#else
2951
 
                    row[2*x + 0] = *--bp;
2952
 
                    row[2*x + 1] = *--bp;
 
3083
                    data[2*x + 0] = *--bp;
 
3084
                    data[2*x + 1] = *--bp;
2953
3085
#endif
2954
3086
                }
2955
3087
                break;
2956
3088
            case CAIRO_FORMAT_RGB24:
2957
 
                for (x = width; x--; ) {
2958
 
#ifdef WORDS_BIGENDIAN
2959
 
                    row[4*x + 3] = *--bp;
2960
 
                    row[4*x + 2] = *--bp;
2961
 
                    row[4*x + 1] = *--bp;
2962
 
                    row[4*x + 0] = 0xff;
2963
 
#else
2964
 
                    row[4*x + 0] = *--bp;
2965
 
                    row[4*x + 1] = *--bp;
2966
 
                    row[4*x + 2] = *--bp;
2967
 
                    row[4*x + 3] = 0xff;
 
3089
                for (x = width; --x>1; ) {
 
3090
#ifdef WORDS_BIGENDIAN
 
3091
                    data[4*x + 3] = *--bp;
 
3092
                    data[4*x + 2] = *--bp;
 
3093
                    data[4*x + 1] = *--bp;
 
3094
                    data[4*x + 0] = 0xff;
 
3095
#else
 
3096
                    data[4*x + 0] = *--bp;
 
3097
                    data[4*x + 1] = *--bp;
 
3098
                    data[4*x + 2] = *--bp;
 
3099
                    data[4*x + 3] = 0xff;
 
3100
#endif
 
3101
                }
 
3102
                if (width > 1) {
 
3103
                    uint8_t rgb[2][3];
 
3104
                    /* shuffle the last couple of overlapping pixels */
 
3105
                    rgb[1][0] = data[5];
 
3106
                    rgb[1][1] = data[4];
 
3107
                    rgb[1][2] = data[3];
 
3108
                    rgb[0][0] = data[2];
 
3109
                    rgb[0][1] = data[1];
 
3110
                    rgb[0][2] = data[0];
 
3111
#ifdef WORDS_BIGENDIAN
 
3112
                    data[4] = 0xff;
 
3113
                    data[5] = rgb[1][2];
 
3114
                    data[6] = rgb[1][1];
 
3115
                    data[7] = rgb[1][0];
 
3116
                    data[0] = 0xff;
 
3117
                    data[1] = rgb[0][2];
 
3118
                    data[2] = rgb[0][1];
 
3119
                    data[3] = rgb[0][0];
 
3120
#else
 
3121
                    data[7] = 0xff;
 
3122
                    data[6] = rgb[1][2];
 
3123
                    data[5] = rgb[1][1];
 
3124
                    data[4] = rgb[1][0];
 
3125
                    data[3] = 0xff;
 
3126
                    data[2] = rgb[0][2];
 
3127
                    data[1] = rgb[0][1];
 
3128
                    data[0] = rgb[0][0];
 
3129
#endif
 
3130
                } else {
 
3131
#ifdef WORDS_BIGENDIAN
 
3132
                    data[0] = 0xff;
 
3133
                    data[1] = data[0];
 
3134
                    data[2] = data[1];
 
3135
                    data[3] = data[2];
 
3136
#else
 
3137
                    data[3] = data[0];
 
3138
                    data[0] = data[2];
 
3139
                    data[2] = data[3];
 
3140
                    data[3] = 0xff;
2968
3141
#endif
2969
3142
                }
2970
3143
                break;
2974
3147
                /* stride == width */
2975
3148
                break;
2976
3149
            }
2977
 
 
2978
 
            memset (row + instride, 0, stride - instride);
2979
 
        }
2980
 
 
2981
 
        /* need to treat last row carefully */
2982
 
        switch (format) {
2983
 
        case CAIRO_FORMAT_A1:
2984
 
            for (x = rowlen; x--; ) {
2985
 
                uint8_t byte = *--bp;
2986
 
                data[x] = CSI_BITSWAP8_IF_LITTLE_ENDIAN (byte);
2987
 
            }
2988
 
            break;
2989
 
        case CAIRO_FORMAT_A8:
2990
 
            for (x = width; x--; )
2991
 
                data[x] = *--bp;
2992
 
            break;
2993
 
        case CAIRO_FORMAT_RGB16_565:
2994
 
            for (x = width; x--; ) {
2995
 
#ifdef WORDS_BIGENDIAN
2996
 
                data[2*x + 1] = *--bp;
2997
 
                data[2*x + 0] = *--bp;
2998
 
#else
2999
 
                data[2*x + 0] = *--bp;
3000
 
                data[2*x + 1] = *--bp;
3001
 
#endif
3002
 
            }
3003
 
            break;
3004
 
        case CAIRO_FORMAT_RGB24:
3005
 
            for (x = width; --x>1; ) {
3006
 
#ifdef WORDS_BIGENDIAN
3007
 
                data[4*x + 3] = *--bp;
3008
 
                data[4*x + 2] = *--bp;
3009
 
                data[4*x + 1] = *--bp;
3010
 
                data[4*x + 0] = 0xff;
3011
 
#else
3012
 
                data[4*x + 0] = *--bp;
3013
 
                data[4*x + 1] = *--bp;
3014
 
                data[4*x + 2] = *--bp;
3015
 
                data[4*x + 3] = 0xff;
3016
 
#endif
3017
 
            }
3018
 
            if (width > 1) {
3019
 
                uint8_t rgb[2][3];
3020
 
                /* shuffle the last couple of overlapping pixels */
3021
 
                rgb[1][0] = data[5];
3022
 
                rgb[1][1] = data[4];
3023
 
                rgb[1][2] = data[3];
3024
 
                rgb[0][0] = data[2];
3025
 
                rgb[0][1] = data[1];
3026
 
                rgb[0][2] = data[0];
3027
 
#ifdef WORDS_BIGENDIAN
3028
 
                data[4] = 0xff;
3029
 
                data[5] = rgb[1][2];
3030
 
                data[6] = rgb[1][1];
3031
 
                data[7] = rgb[1][0];
3032
 
                data[0] = 0xff;
3033
 
                data[1] = rgb[0][2];
3034
 
                data[2] = rgb[0][1];
3035
 
                data[3] = rgb[0][0];
3036
 
#else
3037
 
                data[7] = 0xff;
3038
 
                data[6] = rgb[1][2];
3039
 
                data[5] = rgb[1][1];
3040
 
                data[4] = rgb[1][0];
3041
 
                data[3] = 0xff;
3042
 
                data[2] = rgb[0][2];
3043
 
                data[1] = rgb[0][1];
3044
 
                data[0] = rgb[0][0];
3045
 
#endif
3046
 
            } else {
3047
 
#ifdef WORDS_BIGENDIAN
3048
 
                data[0] = 0xff;
3049
 
                data[1] = data[0];
3050
 
                data[2] = data[1];
3051
 
                data[3] = data[2];
3052
 
#else
3053
 
                data[3] = data[0];
3054
 
                data[0] = data[2];
3055
 
                data[2] = data[3];
3056
 
                data[3] = 0xff;
3057
 
#endif
3058
 
            }
3059
 
            break;
3060
 
        case CAIRO_FORMAT_RGB30:
3061
 
        case CAIRO_FORMAT_INVALID:
3062
 
        case CAIRO_FORMAT_ARGB32:
3063
 
            /* stride == width */
3064
 
            break;
3065
 
        }
3066
 
        memset (data + instride, 0, stride - instride);
3067
 
    } else {
 
3150
            memset (data + instride, 0, stride - instride);
 
3151
        } else {
3068
3152
#ifndef WORDS_BIGENDIAN
3069
 
        switch (format) {
3070
 
        case CAIRO_FORMAT_A1:
3071
 
            for (x = 0; x < len; x++) {
3072
 
                uint8_t byte = data[x];
3073
 
                data[x] = CSI_BITSWAP8_IF_LITTLE_ENDIAN (byte);
3074
 
            }
3075
 
            break;
3076
 
        case CAIRO_FORMAT_RGB16_565:
3077
 
            {
3078
 
                uint32_t *rgba = (uint32_t *) data;
3079
 
                for (x = len/2; x--; rgba++) {
3080
 
                    *rgba = bswap_16 (*rgba);
3081
 
                }
3082
 
            }
3083
 
            break;
3084
 
        case CAIRO_FORMAT_ARGB32:
3085
 
            {
3086
 
                uint32_t *rgba = (uint32_t *) data;
3087
 
                for (x = len/4; x--; rgba++) {
3088
 
                    *rgba = bswap_32 (*rgba);
3089
 
                }
3090
 
            }
3091
 
            break;
3092
 
 
3093
 
        case CAIRO_FORMAT_A8:
3094
 
            break;
3095
 
 
3096
 
        case CAIRO_FORMAT_RGB30:
3097
 
        case CAIRO_FORMAT_RGB24:
3098
 
        case CAIRO_FORMAT_INVALID:
3099
 
        default:
3100
 
            break;
 
3153
            switch (format) {
 
3154
            case CAIRO_FORMAT_A1:
 
3155
                for (x = 0; x < len; x++) {
 
3156
                    uint8_t byte = data[x];
 
3157
                    data[x] = CSI_BITSWAP8_IF_LITTLE_ENDIAN (byte);
 
3158
                }
 
3159
                break;
 
3160
            case CAIRO_FORMAT_RGB16_565:
 
3161
                {
 
3162
                    uint32_t *rgba = (uint32_t *) data;
 
3163
                    for (x = len/2; x--; rgba++) {
 
3164
                        *rgba = bswap_16 (*rgba);
 
3165
                    }
 
3166
                }
 
3167
                break;
 
3168
            case CAIRO_FORMAT_ARGB32:
 
3169
                {
 
3170
                    uint32_t *rgba = (uint32_t *) data;
 
3171
                    for (x = len/4; x--; rgba++) {
 
3172
                        *rgba = bswap_32 (*rgba);
 
3173
                    }
 
3174
                }
 
3175
                break;
 
3176
 
 
3177
            case CAIRO_FORMAT_A8:
 
3178
                break;
 
3179
 
 
3180
            case CAIRO_FORMAT_RGB30:
 
3181
            case CAIRO_FORMAT_RGB24:
 
3182
            case CAIRO_FORMAT_INVALID:
 
3183
            default:
 
3184
                break;
 
3185
            }
 
3186
#endif
3101
3187
        }
3102
 
#endif
 
3188
        csi_object_free (ctx, &file);
3103
3189
    }
3104
3190
 
3105
3191
    cairo_surface_mark_dirty (image);
3276
3362
                mime_type = MIME_TYPE_PNG;
3277
3363
        }
3278
3364
 
3279
 
        status = csi_object_as_file (ctx, &obj, &file);
3280
 
        if (_csi_unlikely (status))
3281
 
            return status;
3282
3365
 
3283
3366
        /* XXX hook for general mime-type decoder */
3284
3367
 
3285
3368
        switch (mime_type) {
3286
3369
        case MIME_TYPE_NONE:
3287
 
            status = _image_read_raw (file.datum.file,
3288
 
                                      format, width, height, &image);
 
3370
            status = _image_read_raw (ctx, &obj, format, width, height, &image);
3289
3371
            break;
3290
3372
        case MIME_TYPE_PNG:
 
3373
            status = csi_object_as_file (ctx, &obj, &file);
 
3374
            if (_csi_unlikely (status))
 
3375
                return status;
 
3376
 
3291
3377
            status = _image_read_png (file.datum.file, &image);
 
3378
            csi_object_free (ctx, &file);
3292
3379
            break;
3293
3380
        }
3294
 
        csi_object_free (ctx, &file);
3295
3381
        if (_csi_unlikely (status))
3296
3382
            return status;
3297
3383
 
3690
3776
    }
3691
3777
 
3692
3778
    obj.type = CSI_OBJECT_TYPE_SURFACE;
3693
 
    obj.datum.surface = cairo_surface_map_to_image (surface, r);
3694
 
    pop (2);
 
3779
    obj.datum.surface = cairo_surface_reference (cairo_surface_map_to_image (surface, r));
 
3780
    pop (1);
3695
3781
    return push (&obj);
3696
3782
}
3697
3783
 
3712
3798
 
3713
3799
    cairo_surface_unmap_image (surface, image);
3714
3800
 
3715
 
    pop (2);
 
3801
    pop (1);
3716
3802
    return CSI_STATUS_SUCCESS;
3717
3803
}
3718
3804
 
5270
5356
     * principally to remove the pixman ops from the profiles.
5271
5357
     */
5272
5358
    if (_csi_likely (_matching_images (surface, source))) {
5273
 
        cairo_surface_flush (surface);
5274
 
        memcpy (cairo_image_surface_get_data (surface),
5275
 
                cairo_image_surface_get_data (source),
5276
 
                cairo_image_surface_get_height (source) * cairo_image_surface_get_stride (source));
5277
 
        cairo_surface_mark_dirty (surface);
 
5359
        if (cairo_surface_get_reference_count (surface) == 1 &&
 
5360
            cairo_surface_get_reference_count (source) == 1)
 
5361
        {
 
5362
            _csi_peek_ostack (ctx, 0)->datum.surface = surface;
 
5363
            _csi_peek_ostack (ctx, 1)->datum.surface = source;
 
5364
        }
 
5365
        else
 
5366
        {
 
5367
            cairo_surface_flush (surface);
 
5368
            memcpy (cairo_image_surface_get_data (surface),
 
5369
                    cairo_image_surface_get_data (source),
 
5370
                    cairo_image_surface_get_height (source) * cairo_image_surface_get_stride (source));
 
5371
            cairo_surface_mark_dirty (surface);
 
5372
        }
5278
5373
    } else {
5279
5374
        cairo_t *cr;
5280
5375