]>
gitweb.michael.orlitzky.com - libsvgtiny-pixbuf.git/blob - example.c
f6deceda741f2708fd7518af64ef05431de7958b
1 #include <fcntl.h> /* open */
2 #include <stdio.h> /* printf, fprintf */
3 #include <stdlib.h> /* malloc */
4 #include <sys/stat.h> /* fstat */
5 #include <unistd.h> /* read */
12 * Render an svgtiny path using cairo.
14 void render_path(cairo_t
*cr
, float scale
, struct svgtiny_shape
*path
) {
18 for (j
= 0; j
!= path
->path_length
; ) {
19 switch ((int) path
->path
[j
]) {
20 case svgtiny_PATH_MOVE
:
22 scale
* path
->path
[j
+ 1],
23 scale
* path
->path
[j
+ 2]);
26 case svgtiny_PATH_CLOSE
:
30 case svgtiny_PATH_LINE
:
32 scale
* path
->path
[j
+ 1],
33 scale
* path
->path
[j
+ 2]);
36 case svgtiny_PATH_BEZIER
:
38 scale
* path
->path
[j
+ 1],
39 scale
* path
->path
[j
+ 2],
40 scale
* path
->path
[j
+ 3],
41 scale
* path
->path
[j
+ 4],
42 scale
* path
->path
[j
+ 5],
43 scale
* path
->path
[j
+ 6]);
51 if (path
->fill
!= svgtiny_TRANSPARENT
) {
52 cairo_set_source_rgb(cr
,
53 svgtiny_RED(path
->fill
) / 255.0,
54 svgtiny_GREEN(path
->fill
) / 255.0,
55 svgtiny_BLUE(path
->fill
) / 255.0);
56 cairo_fill_preserve(cr
);
58 if (path
->stroke
!= svgtiny_TRANSPARENT
) {
59 cairo_set_source_rgb(cr
,
60 svgtiny_RED(path
->stroke
) / 255.0,
61 svgtiny_GREEN(path
->stroke
) / 255.0,
62 svgtiny_BLUE(path
->stroke
) / 255.0);
63 cairo_set_line_width(cr
, scale
* path
->stroke_width
);
64 cairo_stroke_preserve(cr
);
69 * @brief Parse an SVG file into an svgtiny_diagram structure.
72 * The path to the SVG file.
74 * @return If successful, a pointer to an @c svgtiny_diagram structure
75 * is returned; if not, @c NULL is returned. You are expected to @c
76 * svgtiny_free the result if it is valid.
78 struct svgtiny_diagram
* svgtiny_diagram_from_path(char* path
,
81 struct svgtiny_diagram
*diagram
;
90 /* load file into memory buffer */
91 fd
= open(path
, O_RDONLY
);
101 bytecount
= sb
.st_size
;
103 buffer
= malloc(bytecount
);
105 fprintf(stderr
, "Unable to allocate %zd bytes\n", bytecount
);
109 bytesread
= read(fd
, buffer
, bytecount
);
110 if (bytesread
!= bytecount
) {
117 /* create svgtiny object */
118 diagram
= svgtiny_create();
120 fprintf(stderr
, "svgtiny_create() failed\n");
124 code
= svgtiny_parse(diagram
, buffer
, bytecount
, path
, width
, height
);
127 if (code
!= svgtiny_OK
) {
128 fprintf(stderr
, "svgtiny_parse failed: ");
130 case svgtiny_OUT_OF_MEMORY
:
131 fprintf(stderr
, "svgtiny_OUT_OF_MEMORY");
133 case svgtiny_LIBDOM_ERROR
:
134 fprintf(stderr
, "svgtiny_LIBDOM_ERROR");
136 case svgtiny_NOT_SVG
:
137 fprintf(stderr
, "svgtiny_NOT_SVG");
139 case svgtiny_SVG_ERROR
:
140 fprintf(stderr
, "svgtiny_SVG_ERROR: line %i: %s",
142 diagram
->error_message
);
145 fprintf(stderr
, "unknown svgtiny_code %i", code
);
148 fprintf(stderr
, "\n");
155 int main(int argc
, char** argv
) {
160 int pngwidth
= 1024, pngheight
= 1024;
163 struct svgtiny_diagram
*diagram
;
164 cairo_surface_t
*surface
;
166 cairo_status_t cr_status
;
170 /* Parse arguments, and maybe print usage */
172 printf("Usage: %s INPUT OUTPUT\n", argv
[0]);
173 printf("Convert an SVG file (INPUT) to a PNG file (OUTPUT)\n");
180 diagram
= svgtiny_diagram_from_path(svgpath
, pngwidth
, pngheight
);
182 surface
= cairo_image_surface_create(CAIRO_FORMAT_RGB24
,
186 fprintf(stderr
, "cairo_image_surface_create failed\n");
191 cr
= cairo_create(surface
);
192 cr_status
= cairo_status(cr
);
193 if (cr_status
!= CAIRO_STATUS_SUCCESS
) {
195 "cairo_create failed: %s\n",
196 cairo_status_to_string(cr_status
));
201 cairo_set_source_rgb(cr
, 1, 1, 1);
204 /* Loop through the shapes in the diagram... */
205 for (i
= 0; i
!= diagram
->shape_count
; i
++) {
207 /* If this shape is a path, just render it. */
208 if (diagram
->shape
[i
].path
) {
209 render_path(cr
, scale
, &diagram
->shape
[i
]);
212 /* If this shape is text... */
213 if (diagram
->shape
[i
].text
) {
214 /* Figure out what color to use from the R/G/B components of the
216 cairo_set_source_rgb(cr
,
217 svgtiny_RED(diagram
->shape
[i
].stroke
) / 255.0,
218 svgtiny_GREEN(diagram
->shape
[i
].stroke
) / 255.0,
219 svgtiny_BLUE(diagram
->shape
[i
].stroke
) / 255.0);
220 /* Then move to the actual position of the text within the
223 scale
* diagram
->shape
[i
].text_x
,
224 scale
* diagram
->shape
[i
].text_y
);
227 cairo_show_text(cr
, diagram
->shape
[i
].text
);
231 /* Check the status again. */
232 cr_status
= cairo_status(cr
);
233 if (cr_status
!= CAIRO_STATUS_SUCCESS
) {
234 fprintf(stderr
, "cairo error: %s\n",
235 cairo_status_to_string(cr_status
));
240 cr_status
= cairo_surface_write_to_png(surface
, pngpath
);
241 if (cr_status
!= CAIRO_STATUS_SUCCESS
) {
242 fprintf(stderr
, "cairo error: %s\n",
243 cairo_status_to_string(cr_status
));
252 cairo_surface_destroy(surface
);
253 svgtiny_free(diagram
);