mirror of
https://gitlab.freedesktop.org/cairo/cairo.git
synced 2025-12-20 12:50:10 +01:00
264 lines
6.8 KiB
C
264 lines
6.8 KiB
C
|
|
#include <stdio.h>
|
||
|
|
#include <string.h>
|
||
|
|
#include <expat.h>
|
||
|
|
#include <assert.h>
|
||
|
|
|
||
|
|
struct trace {
|
||
|
|
FILE *stream;
|
||
|
|
char tail_buf[80];
|
||
|
|
const char *tail;
|
||
|
|
int surface_depth;
|
||
|
|
};
|
||
|
|
|
||
|
|
static void
|
||
|
|
start_element (void *closure,
|
||
|
|
const char *element,
|
||
|
|
const char **attr)
|
||
|
|
{
|
||
|
|
struct trace *trace = closure;
|
||
|
|
|
||
|
|
if (strcmp (element, "surface") == 0) {
|
||
|
|
const char *content = "COLOR_ALPHA";
|
||
|
|
const char *width = NULL;
|
||
|
|
const char *height = NULL;
|
||
|
|
|
||
|
|
while (*attr) {
|
||
|
|
if (strcmp (*attr, "content") == 0) {
|
||
|
|
content = *++attr;
|
||
|
|
} else if (strcmp (*attr, "width") == 0) {
|
||
|
|
width = *++attr;
|
||
|
|
} else if (strcmp (*attr, "height") == 0) {
|
||
|
|
height = *++attr;
|
||
|
|
} else {
|
||
|
|
fprintf (stderr, "unknown surface attribute '%s'\n", *attr);
|
||
|
|
attr++;
|
||
|
|
}
|
||
|
|
attr++;
|
||
|
|
}
|
||
|
|
|
||
|
|
fprintf (trace->stream, "<< /content //%s", content);
|
||
|
|
if (width != NULL && height != NULL) {
|
||
|
|
fprintf (trace->stream,
|
||
|
|
" /width %s /height %s",
|
||
|
|
width, height);
|
||
|
|
}
|
||
|
|
if (trace->surface_depth++ == 0)
|
||
|
|
fprintf (trace->stream, " >> surface context\n");
|
||
|
|
else
|
||
|
|
fprintf (trace->stream, " >> surface dup context\n");
|
||
|
|
} else if (strcmp (element, "image") == 0) {
|
||
|
|
const char *format = "ARGB24";
|
||
|
|
const char *width = NULL;
|
||
|
|
const char *height = NULL;
|
||
|
|
|
||
|
|
while (*attr) {
|
||
|
|
if (strcmp (*attr, "format") == 0) {
|
||
|
|
format = *++attr;
|
||
|
|
} else if (strcmp (*attr, "width") == 0) {
|
||
|
|
width = *++attr;
|
||
|
|
} else if (strcmp (*attr, "height") == 0) {
|
||
|
|
height = *++attr;
|
||
|
|
} else {
|
||
|
|
fprintf (stderr, "unknown image attribute '%s'\n", *attr);
|
||
|
|
attr++;
|
||
|
|
}
|
||
|
|
attr++;
|
||
|
|
}
|
||
|
|
|
||
|
|
fprintf (trace->stream,
|
||
|
|
"<< /format //%s /width %s /height %s /mime-type (image/png) /source <{",
|
||
|
|
format, width, height);
|
||
|
|
assert (trace->tail == NULL);
|
||
|
|
trace->tail = "}> >> image pattern\n";
|
||
|
|
} else if (strcmp (element, "solid") == 0) {
|
||
|
|
trace->tail = " rgba\n";
|
||
|
|
} else if (strcmp (element, "linear") == 0) {
|
||
|
|
const char *x1 = NULL;
|
||
|
|
const char *x2 = NULL;
|
||
|
|
const char *y1 = NULL;
|
||
|
|
const char *y2 = NULL;
|
||
|
|
|
||
|
|
while (*attr) {
|
||
|
|
if (strcmp (*attr, "x1") == 0) {
|
||
|
|
x1 = *++attr;
|
||
|
|
} else if (strcmp (*attr, "x2") == 0) {
|
||
|
|
x2 = *++attr;
|
||
|
|
} else if (strcmp (*attr, "y1") == 0) {
|
||
|
|
y1 = *++attr;
|
||
|
|
} else if (strcmp (*attr, "y2") == 0) {
|
||
|
|
y2 = *++attr;
|
||
|
|
} else {
|
||
|
|
fprintf (stderr, "unknown linear attribute '%s'\n", *attr);
|
||
|
|
attr++;
|
||
|
|
}
|
||
|
|
attr++;
|
||
|
|
}
|
||
|
|
|
||
|
|
fprintf (trace->stream, "%s %s %s %s linear\n", x1, y1, x2, y2);
|
||
|
|
} else if (strcmp (element, "radial") == 0) {
|
||
|
|
const char *x1 = NULL;
|
||
|
|
const char *y1 = NULL;
|
||
|
|
const char *r1 = NULL;
|
||
|
|
const char *y2 = NULL;
|
||
|
|
const char *x2 = NULL;
|
||
|
|
const char *r2 = NULL;
|
||
|
|
|
||
|
|
while (*attr) {
|
||
|
|
if (strcmp (*attr, "x1") == 0) {
|
||
|
|
x1 = *++attr;
|
||
|
|
} else if (strcmp (*attr, "y1") == 0) {
|
||
|
|
y1 = *++attr;
|
||
|
|
} else if (strcmp (*attr, "r1") == 0) {
|
||
|
|
r1 = *++attr;
|
||
|
|
} else if (strcmp (*attr, "x2") == 0) {
|
||
|
|
x2 = *++attr;
|
||
|
|
} else if (strcmp (*attr, "y2") == 0) {
|
||
|
|
y2 = *++attr;
|
||
|
|
} else if (strcmp (*attr, "r2") == 0) {
|
||
|
|
r2 = *++attr;
|
||
|
|
} else {
|
||
|
|
fprintf (stderr, "unknown radial attribute '%s'\n", *attr);
|
||
|
|
attr++;
|
||
|
|
}
|
||
|
|
attr++;
|
||
|
|
}
|
||
|
|
|
||
|
|
fprintf (trace->stream,
|
||
|
|
"%s %s %s %s %s %s radial\n",
|
||
|
|
x1, y1, r1, x2, y2, r2);
|
||
|
|
} else if (strcmp (element, "matrix") == 0) {
|
||
|
|
fprintf (trace->stream, "[ ");
|
||
|
|
trace->tail = " ] set-matrix\n";
|
||
|
|
} else if (strcmp (element, "extend") == 0) {
|
||
|
|
trace->tail = " set-extend\n";
|
||
|
|
} else if (strcmp (element, "filter") == 0) {
|
||
|
|
trace->tail = " set-filter\n";
|
||
|
|
} else if (strcmp (element, "operator") == 0) {
|
||
|
|
trace->tail = " set-operator\n";
|
||
|
|
} else if (strcmp (element, "tolerance") == 0) {
|
||
|
|
trace->tail = " set-tolerance\n";
|
||
|
|
} else if (strcmp (element, "fill-rule") == 0) {
|
||
|
|
trace->tail = " set-fill-rule\n";
|
||
|
|
} else if (strcmp (element, "line-cap") == 0) {
|
||
|
|
trace->tail = " set-line-cap\n";
|
||
|
|
} else if (strcmp (element, "line-join") == 0) {
|
||
|
|
trace->tail = " set-line-join\n";
|
||
|
|
} else if (strcmp (element, "line-width") == 0) {
|
||
|
|
trace->tail = " set-line-width\n";
|
||
|
|
} else if (strcmp (element, "miter-limit") == 0) {
|
||
|
|
trace->tail = " set-miter-limit\n";
|
||
|
|
} else if (strcmp (element, "antialias") == 0) {
|
||
|
|
trace->tail = " set-antialias\n";
|
||
|
|
} else if (strcmp (element, "color-stop") == 0) {
|
||
|
|
trace->tail = " add-color-stop\n";
|
||
|
|
} else if (strcmp (element, "path") == 0) {
|
||
|
|
/* need to reset the matrix to identity before the path */
|
||
|
|
fprintf (trace->stream, "identity set-matrix ");
|
||
|
|
trace->tail = "\n";
|
||
|
|
} else if (strcmp (element, "dash") == 0) {
|
||
|
|
const char *offset = "0";
|
||
|
|
|
||
|
|
while (*attr) {
|
||
|
|
if (strcmp (*attr, "offset") == 0) {
|
||
|
|
offset = *++attr;
|
||
|
|
}
|
||
|
|
attr++;
|
||
|
|
}
|
||
|
|
|
||
|
|
fprintf (trace->stream, "[");
|
||
|
|
sprintf (trace->tail_buf, "] %s set-dash\n", offset);
|
||
|
|
trace->tail = trace->tail_buf;
|
||
|
|
} else {
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
static void
|
||
|
|
cdata (void *closure,
|
||
|
|
const XML_Char *s,
|
||
|
|
int len)
|
||
|
|
{
|
||
|
|
struct trace *trace = closure;
|
||
|
|
|
||
|
|
if (trace->tail)
|
||
|
|
fwrite (s, len, 1, trace->stream);
|
||
|
|
}
|
||
|
|
|
||
|
|
static void
|
||
|
|
end_element (void *closure,
|
||
|
|
const char *element)
|
||
|
|
{
|
||
|
|
struct trace *trace = closure;
|
||
|
|
|
||
|
|
if (trace->tail) {
|
||
|
|
fprintf (trace->stream, "%s", trace->tail);
|
||
|
|
trace->tail = NULL;
|
||
|
|
}
|
||
|
|
|
||
|
|
if (strcmp (element, "paint") == 0) {
|
||
|
|
fprintf (trace->stream, "paint\n");
|
||
|
|
} else if (strcmp (element, "mask") == 0) {
|
||
|
|
fprintf (trace->stream, "mask\n");
|
||
|
|
} else if (strcmp (element, "stroke") == 0) {
|
||
|
|
fprintf (trace->stream, "stroke\n");
|
||
|
|
} else if (strcmp (element, "fill") == 0) {
|
||
|
|
fprintf (trace->stream, "fill\n");
|
||
|
|
} else if (strcmp (element, "glyphs") == 0) {
|
||
|
|
fprintf (trace->stream, "show-glyphs\n");
|
||
|
|
} else if (strcmp (element, "clip") == 0) {
|
||
|
|
fprintf (trace->stream, "clip\n");
|
||
|
|
} else if (strcmp (element, "source-pattern") == 0) {
|
||
|
|
fprintf (trace->stream, "set-source\n");
|
||
|
|
} else if (strcmp (element, "mask-pattern") == 0) {
|
||
|
|
} else if (strcmp (element, "surface") == 0) {
|
||
|
|
if (--trace->surface_depth == 0)
|
||
|
|
fprintf (trace->stream, "pop\n");
|
||
|
|
else
|
||
|
|
fprintf (trace->stream, "pop pattern\n");
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
int
|
||
|
|
main (int argc, char **argv)
|
||
|
|
{
|
||
|
|
struct trace trace;
|
||
|
|
XML_Parser p;
|
||
|
|
char buf[8192];
|
||
|
|
int done = 0;
|
||
|
|
FILE *in = stdin;
|
||
|
|
|
||
|
|
trace.stream = stdout;
|
||
|
|
trace.tail = NULL;
|
||
|
|
trace.surface_depth = 0;
|
||
|
|
|
||
|
|
if (argc >= 2 && strcmp (argv[1], "-"))
|
||
|
|
in = fopen (argv[1], "r");
|
||
|
|
if (argc >= 3 && strcmp (argv[2], "-"))
|
||
|
|
trace.stream = fopen (argv[2], "w");
|
||
|
|
|
||
|
|
p = XML_ParserCreate (NULL);
|
||
|
|
XML_SetUserData (p, &trace);
|
||
|
|
XML_SetElementHandler (p, start_element, end_element);
|
||
|
|
XML_SetCharacterDataHandler (p, cdata);
|
||
|
|
do {
|
||
|
|
int len;
|
||
|
|
|
||
|
|
len = fread (buf, 1, sizeof (buf), in);
|
||
|
|
done = feof (stdin);
|
||
|
|
|
||
|
|
if (XML_Parse (p, buf, len, done) == XML_STATUS_ERROR) {
|
||
|
|
fprintf (stderr, "Parse error at line %ld:\n%s\n",
|
||
|
|
XML_GetCurrentLineNumber (p),
|
||
|
|
XML_ErrorString (XML_GetErrorCode (p)));
|
||
|
|
exit (-1);
|
||
|
|
}
|
||
|
|
} while (! done);
|
||
|
|
XML_ParserFree (p);
|
||
|
|
|
||
|
|
if (in != stdin)
|
||
|
|
fclose (in);
|
||
|
|
if (trace.stream != stdout)
|
||
|
|
fclose (trace.stream);
|
||
|
|
|
||
|
|
return 0;
|
||
|
|
}
|