rsvg.c 4.32 KB
Newer Older
1 2
/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/* vim: set sw=4 sts=4 ts=4 expandtab: */
3
/*
4
   rsvg.c: SAX-based renderer for SVG files into a GdkPixbuf.
5

6
   Copyright (C) 2000 Eazel, Inc.
7
   Copyright (C) 2002-2005 Dom Lachowicz <cinamod@hotmail.com>
8

9
   This program is free software; you can redistribute it and/or
10
   modify it under the terms of the GNU Library General Public License as
11 12
   published by the Free Software Foundation; either version 2 of the
   License, or (at your option) any later version.
13

14 15 16
   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
17
   Library General Public License for more details.
18

19
   You should have received a copy of the GNU Library General Public
20 21 22
   License along with this program; if not, write to the
   Free Software Foundation, Inc., 59 Temple Place - Suite 330,
   Boston, MA 02111-1307, USA.
23

24 25 26
   Author: Raph Levien <raph@artofcode.com>
*/

27
#include "config.h"
28

29
#include "rsvg.h"
30
#include "rsvg-private.h"
31 32 33
#include "rsvg-css.h"
#include "rsvg-styles.h"
#include "rsvg-shapes.h"
34
#include "rsvg-image.h"
35
#include "rsvg-text.h"
36
#include "rsvg-filter.h"
37
#include "rsvg-mask.h"
38
#include "rsvg-marker.h"
39

40
#include <math.h>
41
#include <string.h>
Michael Meeks's avatar
Michael Meeks committed
42
#include <stdarg.h>
43

44
#include "rsvg-cairo.h"
Caleb Michael Moore's avatar
Caleb Michael Moore committed
45
#include "rsvg-cairo-draw.h"
46

47
static void
48
rsvg_pixmap_destroy (gchar * pixels, gpointer data)
49
{
50
    g_free (pixels);
51 52
}

Dom Lachowicz's avatar
Dom Lachowicz committed
53 54 55
/**
 * rsvg_handle_get_pixbuf_sub:
 * @handle: An #RsvgHandle
56 57 58
 * @id: The id of an element inside the SVG, or %NULL to render the whole SVG. For
 * example, if you have a layer called "layer1" that you wish to render, pass 
 * "##layer1" as the id.
Dom Lachowicz's avatar
Dom Lachowicz committed
59 60 61 62 63 64 65 66
 *
 * Returns the pixbuf loaded by #handle.  The pixbuf returned will be reffed, so
 * the caller of this function must assume that ref.  If insufficient data has
 * been read to create the pixbuf, or an error occurred in loading, then %NULL
 * will be returned.  Note that the pixbuf may not be complete until
 * @rsvg_handle_close has been called.
 *
 * Returns: the pixbuf loaded by #handle, or %NULL.
67 68
 *
 * Since: 2.14
Dom Lachowicz's avatar
Dom Lachowicz committed
69
 **/
70
GdkPixbuf *
71
rsvg_handle_get_pixbuf_sub (RsvgHandle * handle, const char *id)
72
{
73 74 75 76 77 78
    RsvgDimensionData dimensions;
    GdkPixbuf *output = NULL;
    guint8 *pixels;
    cairo_surface_t *surface;
    cairo_t *cr;
    int rowstride;
79

80
    g_return_val_if_fail (handle != NULL, NULL);
81

82 83
    if (!handle->priv->finished)
        return NULL;
84

85 86 87
    rsvg_handle_get_dimensions (handle, &dimensions);
    if (!(dimensions.width && dimensions.height))
        return NULL;
88

89
    rowstride = dimensions.width * 4;
90

91
    pixels = g_try_malloc0 (dimensions.width * dimensions.height * 4UL);
92 93
    if (!pixels)
        return NULL;
Caleb Michael Moore's avatar
Caleb Michael Moore committed
94

95 96 97 98
    surface = cairo_image_surface_create_for_data (pixels,
                                                   CAIRO_FORMAT_ARGB32,
                                                   dimensions.width, dimensions.height, rowstride);
    cr = cairo_create (surface);
99
    cairo_surface_destroy (surface);
100

101
    if (rsvg_handle_render_cairo_sub (handle, cr, id)) {
102 103 104 105 106 107 108 109 110 111
        rsvg_cairo_to_pixbuf (pixels, rowstride, dimensions.height);

        output = gdk_pixbuf_new_from_data (pixels,
                                           GDK_COLORSPACE_RGB,
                                           TRUE,
                                           8,
                                           dimensions.width,
                                           dimensions.height,
                                           rowstride,
                                           (GdkPixbufDestroyNotify) rsvg_pixmap_destroy, NULL);
112
	} else {
113 114
        g_free (pixels);
        output = NULL;
115
	}
116

117
    cairo_destroy (cr);
118

119
    return output;
120
}
121 122 123 124 125 126 127 128 129 130 131 132 133 134

/**
 * rsvg_handle_get_pixbuf:
 * @handle: An #RsvgHandle
 *
 * Returns the pixbuf loaded by #handle.  The pixbuf returned will be reffed, so
 * the caller of this function must assume that ref.  If insufficient data has
 * been read to create the pixbuf, or an error occurred in loading, then %NULL
 * will be returned.  Note that the pixbuf may not be complete until
 * @rsvg_handle_close has been called.
 *
 * Returns: the pixbuf loaded by #handle, or %NULL.
 **/
GdkPixbuf *
135
rsvg_handle_get_pixbuf (RsvgHandle * handle)
136
{
137
    return rsvg_handle_get_pixbuf_sub (handle, NULL);
138
}