1 /* libsvg-cairo - Render SVG documents using the cairo library
2 *
3 * Copyright � 2002 University of Southern California
4 *
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Library General Public
7 * License as published by the Free Software Foundation; either
8 * version 2 of the License, or (at your option) any later version.
9 *
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Library General Public License for more details.
14 *
15 * You should have received a copy of the GNU Library General Public
16 * License along with this library; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 *
19 * Author: Carl D. Worth <cworth@isi.edu>
20 */
21
22 #include <stdlib.h>
23 #include <string.h>
24
25 #include "svg-cairo-internal.h"
26
27 svg_cairo_status_t
_svg_cairo_state_create(svg_cairo_state_t ** state)28 _svg_cairo_state_create (svg_cairo_state_t **state)
29 {
30 *state = malloc (sizeof (svg_cairo_state_t));
31 if (*state == NULL)
32 return SVG_CAIRO_STATUS_NO_MEMORY;
33
34 _svg_cairo_state_init (*state);
35
36 return SVG_CAIRO_STATUS_SUCCESS;
37 }
38
39 svg_cairo_status_t
_svg_cairo_state_init(svg_cairo_state_t * state)40 _svg_cairo_state_init (svg_cairo_state_t *state)
41 {
42 /* trust libsvg to set all of these to reasonable defaults:
43 state->fill_paint;
44 state->stroke_paint;
45 state->fill_opacity;
46 state->stroke_opacity;
47 */
48 state->child_surface = NULL;
49 state->saved_cr = NULL;
50
51 state->font_family = strdup (SVG_CAIRO_FONT_FAMILY_DEFAULT);
52 if (state->font_family == NULL)
53 return SVG_CAIRO_STATUS_NO_MEMORY;
54
55 state->font_size = 1.0;
56 state->font_style = SVG_FONT_STYLE_NORMAL;
57 state->font_weight = 400;
58 state->font_dirty = 1;
59
60 state->dash = NULL;
61 state->num_dashes = 0;
62 state->dash_offset = 0;
63
64 state->opacity = 1.0;
65
66 state->bbox = 0;
67
68 state->text_anchor = SVG_TEXT_ANCHOR_START;
69
70 state->next = NULL;
71
72 return SVG_CAIRO_STATUS_SUCCESS;
73 }
74
75 svg_cairo_status_t
_svg_cairo_state_init_copy(svg_cairo_state_t * state,const svg_cairo_state_t * other)76 _svg_cairo_state_init_copy (svg_cairo_state_t *state, const svg_cairo_state_t *other)
77 {
78 _svg_cairo_state_deinit (state);
79
80 if (other == NULL)
81 return _svg_cairo_state_init (state);
82
83 *state = *other;
84
85 /* We don't need our own child_surface or saved cr at this point. */
86 state->child_surface = NULL;
87 state->saved_cr = NULL;
88
89 if (other->font_family)
90 state->font_family = strdup ((char *) other->font_family);
91
92 state->viewport_width = other->viewport_width;
93 state->viewport_height = other->viewport_height;
94
95 if (other->dash) {
96 state->dash = malloc (state->num_dashes * sizeof(double));
97 if (state->dash == NULL)
98 return SVG_CAIRO_STATUS_NO_MEMORY;
99 memcpy (state->dash, other->dash, state->num_dashes * sizeof(double));
100 }
101
102 return SVG_CAIRO_STATUS_SUCCESS;
103 }
104
105 svg_cairo_status_t
_svg_cairo_state_deinit(svg_cairo_state_t * state)106 _svg_cairo_state_deinit (svg_cairo_state_t *state)
107 {
108 if (state->child_surface) {
109 cairo_surface_destroy(state->child_surface);
110 state->child_surface = NULL;
111 }
112
113 if (state->saved_cr) {
114 cairo_destroy(state->saved_cr);
115 state->saved_cr = NULL;
116 }
117
118 if (state->font_family) {
119 free (state->font_family);
120 state->font_family = NULL;
121 }
122
123 if (state->dash) {
124 free (state->dash);
125 state->dash = NULL;
126 }
127
128 state->next = NULL;
129
130 return SVG_CAIRO_STATUS_SUCCESS;
131 }
132
133 svg_cairo_status_t
_svg_cairo_state_destroy(svg_cairo_state_t * state)134 _svg_cairo_state_destroy (svg_cairo_state_t *state)
135 {
136 _svg_cairo_state_deinit (state);
137
138 free (state);
139
140 return SVG_CAIRO_STATUS_SUCCESS;
141 }
142
143 svg_cairo_state_t *
_svg_cairo_state_push(svg_cairo_state_t * state)144 _svg_cairo_state_push (svg_cairo_state_t *state)
145 {
146 svg_cairo_state_t *new;
147
148 _svg_cairo_state_create (&new);
149 if (new == NULL)
150 return NULL;
151
152 _svg_cairo_state_init_copy (new, state);
153
154 new->next = state;
155
156 return new;
157 }
158
159 svg_cairo_state_t *
_svg_cairo_state_pop(svg_cairo_state_t * state)160 _svg_cairo_state_pop (svg_cairo_state_t *state)
161 {
162 svg_cairo_state_t *next;
163
164 if (state == NULL)
165 return NULL;
166
167 next = state->next;
168
169 _svg_cairo_state_destroy (state);
170
171 return next;
172 }
173