mirror of
https://gitlab.freedesktop.org/cairo/cairo.git
synced 2026-05-05 14:38:13 +02:00
Add xml surface
A very simple surface that produces a hierarchical DAG in a simple XML format. It is intended to be used whilst debugging, for example with the automatic regression finding tools of cairo-sphinx, and with test suites that just want to verify that their code made a particular Cairo call.
This commit is contained in:
parent
6e0b3be903
commit
425b0e35e2
19 changed files with 1902 additions and 14 deletions
|
|
@ -320,6 +320,16 @@ enabled_cairo_boilerplate_headers += $(cairo_boilerplate_tee_headers)
|
|||
enabled_cairo_boilerplate_private += $(cairo_boilerplate_tee_private)
|
||||
enabled_cairo_boilerplate_sources += $(cairo_boilerplate_tee_sources)
|
||||
|
||||
supported_cairo_boilerplate_headers += $(cairo_boilerplate_xml_headers)
|
||||
all_cairo_boilerplate_headers += $(cairo_boilerplate_xml_headers)
|
||||
all_cairo_boilerplate_private += $(cairo_boilerplate_xml_private)
|
||||
all_cairo_boilerplate_sources += $(cairo_boilerplate_xml_sources)
|
||||
ifeq ($(CAIRO_HAS_XML_SURFACE),1)
|
||||
enabled_cairo_boilerplate_headers += $(cairo_boilerplate_xml_headers)
|
||||
enabled_cairo_boilerplate_private += $(cairo_boilerplate_xml_private)
|
||||
enabled_cairo_boilerplate_sources += $(cairo_boilerplate_xml_sources)
|
||||
endif
|
||||
|
||||
supported_cairo_boilerplate_headers += $(cairo_boilerplate_user_headers)
|
||||
all_cairo_boilerplate_headers += $(cairo_boilerplate_user_headers)
|
||||
all_cairo_boilerplate_private += $(cairo_boilerplate_user_private)
|
||||
|
|
|
|||
|
|
@ -28,3 +28,4 @@ CAIRO_HAS_PS_SURFACE=1
|
|||
CAIRO_HAS_PDF_SURFACE=1
|
||||
CAIRO_HAS_SVG_SURFACE=1
|
||||
CAIRO_HAS_TEST_SURFACES=0
|
||||
CAIRO_HAS_XML_SURFACE=1
|
||||
|
|
|
|||
|
|
@ -92,5 +92,8 @@ endif
|
|||
@echo "#define CAIRO_HAS_IMAGE_SURFACE 1" >> src/cairo-features.h
|
||||
@echo "#define CAIRO_HAS_META_SURFACE 1" >> src/cairo-features.h
|
||||
@echo "#define CAIRO_HAS_TEE_SURFACE 1" >> src/cairo-features.h
|
||||
ifeq ($(CAIRO_HAS_XML_SURFACE),1)
|
||||
@echo "#define CAIRO_HAS_XML_SURFACE 1" >> src/cairo-features.h
|
||||
endif
|
||||
@echo "#define CAIRO_HAS_USER_FONT 1" >> src/cairo-features.h
|
||||
@echo "#endif" >> src/cairo-features.h
|
||||
|
|
|
|||
|
|
@ -359,6 +359,7 @@ AC_DEFUN([CAIRO_REPORT],
|
|||
echo " Image: yes (always builtin)"
|
||||
echo " Meta: yes (always builtin)"
|
||||
echo " Tee: yes (always builtin)"
|
||||
echo " XML: $use_xml"
|
||||
echo " Xlib: $use_xlib"
|
||||
echo " Xlib Xrender: $use_xlib_xrender"
|
||||
echo " Qt: $use_qt"
|
||||
|
|
|
|||
|
|
@ -571,6 +571,10 @@ dnl ===========================================================================
|
|||
|
||||
CAIRO_ENABLE_SURFACE_BACKEND(meta, meta, always)
|
||||
CAIRO_ENABLE_SURFACE_BACKEND(tee, tee, always)
|
||||
CAIRO_ENABLE_SURFACE_BACKEND(xml, xml, yes, [
|
||||
use_xml=$have_libz
|
||||
xml_NONPKGCONFIG_LIBS=-lz
|
||||
])
|
||||
|
||||
dnl ===========================================================================
|
||||
|
||||
|
|
|
|||
|
|
@ -99,6 +99,7 @@ cairo_sources = \
|
|||
cairo-arc.c \
|
||||
cairo-array.c \
|
||||
cairo-atomic.c \
|
||||
cairo-base64-stream.c \
|
||||
cairo-base85-stream.c \
|
||||
cairo-bentley-ottmann.c \
|
||||
cairo-bentley-ottmann-rectangular.c \
|
||||
|
|
@ -190,9 +191,14 @@ cairo_ps_headers = cairo-ps.h
|
|||
cairo_ps_private = cairo-ps-surface-private.h
|
||||
cairo_ps_sources = cairo-ps-surface.c
|
||||
|
||||
cairo_deflate_stream_sources = cairo-deflate-stream.c
|
||||
|
||||
cairo_pdf_headers = cairo-pdf.h
|
||||
cairo_pdf_private = cairo-pdf-surface-private.h
|
||||
cairo_pdf_sources = cairo-pdf-surface.c cairo-deflate-stream.c
|
||||
cairo_pdf_sources = cairo-pdf-surface.c
|
||||
if CAIRO_HAS_PDF_SURFACE
|
||||
req_cairo_deflate_stream_sources = $(cairo_deflate_stream_sources)
|
||||
endif
|
||||
|
||||
cairo_svg_headers = cairo-svg.h
|
||||
cairo_svg_private = cairo-svg-surface-private.h
|
||||
|
|
@ -294,5 +300,15 @@ cairo_gallium_sources = drm/cairo-drm-gallium-surface.c
|
|||
cairo_script_headers = cairo-script.h
|
||||
cairo_script_sources = cairo-script-surface.c
|
||||
|
||||
cairo_xml_headers = cairo-xml.h
|
||||
cairo_xml_sources = cairo-xml-surface.c
|
||||
if CAIRO_HAS_XML_SURFACE
|
||||
req_cairo_deflate_stream_sources = $(cairo_deflate_stream_sources)
|
||||
endif
|
||||
|
||||
cairo_vg_headers = cairo-vg.h
|
||||
cairo_vg_sources = cairo-vg-surface.c
|
||||
|
||||
cairo_sources += \
|
||||
$(req_cairo_deflate_stream_sources) \
|
||||
$(NULL)
|
||||
|
|
|
|||
|
|
@ -430,6 +430,20 @@ enabled_cairo_headers += $(cairo_tee_headers)
|
|||
enabled_cairo_private += $(cairo_tee_private)
|
||||
enabled_cairo_sources += $(cairo_tee_sources)
|
||||
|
||||
supported_cairo_headers += $(cairo_xml_headers)
|
||||
all_cairo_headers += $(cairo_xml_headers)
|
||||
all_cairo_private += $(cairo_xml_private)
|
||||
all_cairo_sources += $(cairo_xml_sources)
|
||||
ifeq ($(CAIRO_HAS_XML_SURFACE),1)
|
||||
enabled_cairo_headers += $(cairo_xml_headers)
|
||||
enabled_cairo_private += $(cairo_xml_private)
|
||||
enabled_cairo_sources += $(cairo_xml_sources)
|
||||
endif
|
||||
all_cairo_pkgconf += cairo-xml.pc
|
||||
ifeq ($(CAIRO_HAS_XML_SURFACE),1)
|
||||
enabled_cairo_pkgconf += cairo-xml.pc
|
||||
endif
|
||||
|
||||
supported_cairo_headers += $(cairo_user_headers)
|
||||
all_cairo_headers += $(cairo_user_headers)
|
||||
all_cairo_private += $(cairo_user_private)
|
||||
|
|
|
|||
143
src/cairo-base64-stream.c
Normal file
143
src/cairo-base64-stream.c
Normal file
|
|
@ -0,0 +1,143 @@
|
|||
/* -*- Mode: c; c-basic-offset: 4; indent-tabs-mode: t; tab-width: 8; -*- */
|
||||
/* cairo - a vector graphics library with display and print output
|
||||
*
|
||||
* Copyright © 2005-2007 Emmanuel Pacaud <emmanuel.pacaud@free.fr>
|
||||
* Copyright © 2009 Chris Wilson
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it either under the terms of the GNU Lesser General Public
|
||||
* License version 2.1 as published by the Free Software Foundation
|
||||
* (the "LGPL") or, at your option, under the terms of the Mozilla
|
||||
* Public License Version 1.1 (the "MPL"). If you do not alter this
|
||||
* notice, a recipient may use your version of this file under either
|
||||
* the MPL or the LGPL.
|
||||
*
|
||||
* You should have received a copy of the LGPL along with this library
|
||||
* in the file COPYING-LGPL-2.1; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
* You should have received a copy of the MPL along with this library
|
||||
* in the file COPYING-MPL-1.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License
|
||||
* Version 1.1 (the "License"); you may not use this file except in
|
||||
* compliance with the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY
|
||||
* OF ANY KIND, either express or implied. See the LGPL or the MPL for
|
||||
* the specific language governing rights and limitations.
|
||||
*
|
||||
* The Original Code is the cairo graphics library.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Red Hat, Inc.
|
||||
*
|
||||
* Author(s):
|
||||
* Kristian Høgsberg <krh@redhat.com>
|
||||
* Chris Wilson <chris@chris-wilson.co.uk>
|
||||
*/
|
||||
|
||||
#include "cairoint.h"
|
||||
#include "cairo-output-stream-private.h"
|
||||
|
||||
typedef struct _cairo_base64_stream {
|
||||
cairo_output_stream_t base;
|
||||
cairo_output_stream_t *output;
|
||||
unsigned int in_mem;
|
||||
unsigned int trailing;
|
||||
unsigned char src[3];
|
||||
} cairo_base64_stream_t;
|
||||
|
||||
static char const base64_table[64] =
|
||||
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
|
||||
|
||||
static cairo_status_t
|
||||
_cairo_base64_stream_write (cairo_output_stream_t *base,
|
||||
const unsigned char *data,
|
||||
unsigned int length)
|
||||
{
|
||||
cairo_base64_stream_t * stream = (cairo_base64_stream_t *) base;
|
||||
unsigned char *src = stream->src;
|
||||
unsigned int i;
|
||||
|
||||
if (stream->in_mem + length < 3) {
|
||||
for (i = 0; i < length; i++) {
|
||||
src[i + stream->in_mem] = *data++;
|
||||
}
|
||||
stream->in_mem += length;
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
do {
|
||||
unsigned char dst[4];
|
||||
|
||||
for (i = stream->in_mem; i < 3; i++) {
|
||||
src[i] = *data++;
|
||||
length--;
|
||||
}
|
||||
stream->in_mem = 0;
|
||||
|
||||
dst[0] = base64_table[src[0] >> 2];
|
||||
dst[1] = base64_table[(src[0] & 0x03) << 4 | src[1] >> 4];
|
||||
dst[2] = base64_table[(src[1] & 0x0f) << 2 | src[2] >> 6];
|
||||
dst[3] = base64_table[src[2] & 0xfc >> 2];
|
||||
/* Special case for the last missing bits */
|
||||
switch (stream->trailing) {
|
||||
case 2:
|
||||
dst[2] = '=';
|
||||
case 1:
|
||||
dst[3] = '=';
|
||||
default:
|
||||
break;
|
||||
}
|
||||
_cairo_output_stream_write (stream->output, dst, 4);
|
||||
} while (length >= 3);
|
||||
|
||||
for (i = 0; i < length; i++) {
|
||||
src[i] = *data++;
|
||||
}
|
||||
stream->in_mem = length;
|
||||
|
||||
return _cairo_output_stream_get_status (stream->output);
|
||||
}
|
||||
|
||||
static cairo_status_t
|
||||
_cairo_base64_stream_close (cairo_output_stream_t *base)
|
||||
{
|
||||
cairo_base64_stream_t *stream = (cairo_base64_stream_t *) base;
|
||||
cairo_status_t status = CAIRO_STATUS_SUCCESS;
|
||||
|
||||
if (stream->in_mem > 0) {
|
||||
memset (stream->src + stream->in_mem, 0, 3 - stream->in_mem);
|
||||
stream->trailing = 3 - stream->in_mem;
|
||||
stream->in_mem = 3;
|
||||
status = _cairo_base64_stream_write (base, NULL, 0);
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
cairo_output_stream_t *
|
||||
_cairo_base64_stream_create (cairo_output_stream_t *output)
|
||||
{
|
||||
cairo_base64_stream_t *stream;
|
||||
|
||||
if (output->status)
|
||||
return _cairo_output_stream_create_in_error (output->status);
|
||||
|
||||
stream = malloc (sizeof (cairo_base64_stream_t));
|
||||
if (unlikely (stream == NULL)) {
|
||||
_cairo_error_throw (CAIRO_STATUS_NO_MEMORY);
|
||||
return (cairo_output_stream_t *) &_cairo_output_stream_nil;
|
||||
}
|
||||
|
||||
_cairo_output_stream_init (&stream->base,
|
||||
_cairo_base64_stream_write,
|
||||
NULL,
|
||||
_cairo_base64_stream_close);
|
||||
|
||||
stream->output = output;
|
||||
stream->in_mem = 0;
|
||||
stream->trailing = 0;
|
||||
|
||||
return &stream->base;
|
||||
}
|
||||
|
|
@ -102,9 +102,6 @@ _cairo_base85_stream_close (cairo_output_stream_t *base)
|
|||
_cairo_output_stream_write (stream->output, five_tuple, stream->pending + 1);
|
||||
}
|
||||
|
||||
/* Mark end of base85 data */
|
||||
_cairo_output_stream_printf (stream->output, "~>");
|
||||
|
||||
return _cairo_output_stream_get_status (stream->output);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -184,6 +184,10 @@ _cairo_null_stream_create (void);
|
|||
cairo_private cairo_output_stream_t *
|
||||
_cairo_base85_stream_create (cairo_output_stream_t *output);
|
||||
|
||||
/* cairo-base64-stream.c */
|
||||
cairo_private cairo_output_stream_t *
|
||||
_cairo_base64_stream_create (cairo_output_stream_t *output);
|
||||
|
||||
/* cairo-deflate-stream.c */
|
||||
cairo_private cairo_output_stream_t *
|
||||
_cairo_deflate_stream_create (cairo_output_stream_t *output);
|
||||
|
|
|
|||
|
|
@ -1919,10 +1919,14 @@ _cairo_ps_surface_emit_base85_string (cairo_ps_surface_t *surface,
|
|||
_cairo_output_stream_write (base85_stream, data, length);
|
||||
|
||||
status = _cairo_output_stream_destroy (base85_stream);
|
||||
|
||||
/* Mark end of base85 data */
|
||||
_cairo_output_stream_printf (string_array_stream, "~>");
|
||||
status2 = _cairo_output_stream_destroy (string_array_stream);
|
||||
if (status == CAIRO_STATUS_SUCCESS)
|
||||
status = status2;
|
||||
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1142,7 +1142,7 @@ _emit_png_surface (cairo_script_surface_t *surface,
|
|||
if (unlikely (status))
|
||||
return status;
|
||||
|
||||
_cairo_output_stream_puts (surface->ctx->stream, " >> image ");
|
||||
_cairo_output_stream_puts (surface->ctx->stream, "~> >> image ");
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
|
|
@ -1253,7 +1253,7 @@ _emit_image_surface (cairo_script_surface_t *surface,
|
|||
if (unlikely (status))
|
||||
return status;
|
||||
}
|
||||
_cairo_output_stream_puts (surface->ctx->stream, " >> image ");
|
||||
_cairo_output_stream_puts (surface->ctx->stream, "~> >> image ");
|
||||
|
||||
cairo_surface_destroy (&clone->base);
|
||||
}
|
||||
|
|
@ -1291,7 +1291,7 @@ _emit_image_surface (cairo_script_surface_t *surface,
|
|||
if (unlikely (status))
|
||||
return status;
|
||||
|
||||
_cairo_output_stream_puts (surface->ctx->stream, " set-mime-data\n");
|
||||
_cairo_output_stream_puts (surface->ctx->stream, "~> set-mime-data\n");
|
||||
}
|
||||
|
||||
cairo_surface_get_mime_data (&image->base, CAIRO_MIME_TYPE_JP2,
|
||||
|
|
@ -1307,7 +1307,7 @@ _emit_image_surface (cairo_script_surface_t *surface,
|
|||
if (unlikely (status))
|
||||
return status;
|
||||
|
||||
_cairo_output_stream_puts (surface->ctx->stream, " set-mime-data\n");
|
||||
_cairo_output_stream_puts (surface->ctx->stream, "~> set-mime-data\n");
|
||||
}
|
||||
|
||||
_cairo_output_stream_puts (surface->ctx->stream, "pattern");
|
||||
|
|
@ -2499,7 +2499,7 @@ _emit_type42_font (cairo_script_surface_t *surface,
|
|||
|
||||
font_private = scaled_font->surface_private;
|
||||
_cairo_output_stream_printf (surface->ctx->stream,
|
||||
" >> font dup /f%lu exch def set-font-face",
|
||||
"~> >> font dup /f%lu exch def set-font-face",
|
||||
font_private->id);
|
||||
|
||||
return status;
|
||||
|
|
@ -3003,7 +3003,7 @@ _cairo_script_surface_show_text_glyphs (void *abstract_surface,
|
|||
}
|
||||
|
||||
_cairo_output_stream_printf (surface->ctx->stream,
|
||||
" %f <~", glyphs[n].x - x);
|
||||
"~> %f <~", glyphs[n].x - x);
|
||||
base85_stream = _cairo_base85_stream_create (surface->ctx->stream);
|
||||
} else {
|
||||
_cairo_output_stream_printf (surface->ctx->stream,
|
||||
|
|
@ -3025,7 +3025,7 @@ _cairo_script_surface_show_text_glyphs (void *abstract_surface,
|
|||
}
|
||||
|
||||
_cairo_output_stream_printf (surface->ctx->stream,
|
||||
" %f %f <~",
|
||||
"~> %f %f <~",
|
||||
ix, iy);
|
||||
base85_stream = _cairo_base85_stream_create (surface->ctx->stream);
|
||||
} else {
|
||||
|
|
@ -3067,6 +3067,8 @@ _cairo_script_surface_show_text_glyphs (void *abstract_surface,
|
|||
status2 = _cairo_output_stream_destroy (base85_stream);
|
||||
if (status == CAIRO_STATUS_SUCCESS)
|
||||
status = status2;
|
||||
|
||||
_cairo_output_stream_printf (surface->ctx->stream, "~>");
|
||||
} else {
|
||||
_cairo_output_stream_puts (surface->ctx->stream, " ]");
|
||||
}
|
||||
|
|
@ -3105,6 +3107,8 @@ _cairo_script_surface_show_text_glyphs (void *abstract_surface,
|
|||
status = _cairo_output_stream_destroy (base85_stream);
|
||||
if (unlikely (status))
|
||||
return status;
|
||||
|
||||
_cairo_output_stream_puts (surface->ctx->stream, "~>");
|
||||
}
|
||||
|
||||
_cairo_output_stream_printf (surface->ctx->stream,
|
||||
|
|
|
|||
1153
src/cairo-xml-surface.c
Normal file
1153
src/cairo-xml-surface.c
Normal file
File diff suppressed because it is too large
Load diff
72
src/cairo-xml.h
Normal file
72
src/cairo-xml.h
Normal file
|
|
@ -0,0 +1,72 @@
|
|||
/* cairo - a vector graphics library with display and print output
|
||||
*
|
||||
* Copyright © 2009 Chris Wilson
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it either under the terms of the GNU Lesser General Public
|
||||
* License version 2.1 as published by the Free Software Foundation
|
||||
* (the "LGPL") or, at your option, under the terms of the Mozilla
|
||||
* Public License Version 1.1 (the "MPL"). If you do not alter this
|
||||
* notice, a recipient may use your version of this file under either
|
||||
* the MPL or the LGPL.
|
||||
*
|
||||
* You should have received a copy of the LGPL along with this library
|
||||
* in the file COPYING-LGPL-2.1; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
* You should have received a copy of the MPL along with this library
|
||||
* in the file COPYING-MPL-1.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License
|
||||
* Version 1.1 (the "License"); you may not use this file except in
|
||||
* compliance with the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY
|
||||
* OF ANY KIND, either express or implied. See the LGPL or the MPL for
|
||||
* the specific language governing rights and limitations.
|
||||
*
|
||||
* The Original Code is the cairo graphics library.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Chris Wilson
|
||||
*
|
||||
* Contributor(s):
|
||||
* Chris Wilson <chris@chris-wilson.co.uk>
|
||||
*/
|
||||
|
||||
#ifndef CAIRO_XML_H
|
||||
#define CAIRO_XML_H
|
||||
|
||||
#include "cairo.h"
|
||||
|
||||
#if CAIRO_HAS_XML_SURFACE
|
||||
|
||||
CAIRO_BEGIN_DECLS
|
||||
|
||||
typedef struct _cairo_xml cairo_xml_t;
|
||||
|
||||
cairo_public cairo_xml_t *
|
||||
cairo_xml_create (const char *filename);
|
||||
|
||||
cairo_public cairo_xml_t *
|
||||
cairo_xml_create_for_stream (cairo_write_func_t write_func,
|
||||
void *closure);
|
||||
|
||||
cairo_public void
|
||||
cairo_xml_destroy (cairo_xml_t *context);
|
||||
|
||||
cairo_public cairo_surface_t *
|
||||
cairo_xml_surface_create (cairo_xml_t *xml,
|
||||
cairo_content_t content,
|
||||
double width, double height);
|
||||
|
||||
cairo_public cairo_status_t
|
||||
cairo_xml_for_meta_surface (cairo_xml_t *context,
|
||||
cairo_surface_t *meta);
|
||||
|
||||
CAIRO_END_DECLS
|
||||
|
||||
#else /*CAIRO_HAS_XML_SURFACE*/
|
||||
# error Cairo was not compiled with support for the XML backend
|
||||
#endif /*CAIRO_HAS_XML_SURFACE*/
|
||||
|
||||
#endif /*CAIRO_XML_H*/
|
||||
|
|
@ -1949,6 +1949,7 @@ cairo_surface_status (cairo_surface_t *surface);
|
|||
* @CAIRO_SURFACE_TYPE_GL: The surface is of type OpenGL, since 1.10
|
||||
* @CAIRO_SURFACE_TYPE_DRM: The surface is of type Direct Render Manager, since 1.10
|
||||
* @CAIRO_SURFACE_TYPE_TEE: The surface is of type 'tee' (a multiplexing surface), since 1.10
|
||||
* @CAIRO_SURFACE_TYPE_XML: The surface is of type XML (for debugging), since 1.10
|
||||
*
|
||||
* #cairo_surface_type_t is used to describe the type of a given
|
||||
* surface. The surface types are also known as "backends" or "surface
|
||||
|
|
@ -1994,7 +1995,8 @@ typedef enum _cairo_surface_type {
|
|||
CAIRO_SURFACE_TYPE_VG,
|
||||
CAIRO_SURFACE_TYPE_GL,
|
||||
CAIRO_SURFACE_TYPE_DRM,
|
||||
CAIRO_SURFACE_TYPE_TEE
|
||||
CAIRO_SURFACE_TYPE_TEE,
|
||||
CAIRO_SURFACE_TYPE_XML
|
||||
} cairo_surface_type_t;
|
||||
|
||||
cairo_public cairo_surface_type_t
|
||||
|
|
|
|||
|
|
@ -15,9 +15,16 @@ SUBDIRS += cairo-sphinx
|
|||
endif
|
||||
endif
|
||||
|
||||
AM_CPPFLAGS = -I$(top_srcdir)/src
|
||||
AM_CPPFLAGS = -I$(top_srcdir)/src \
|
||||
-I$(top_builddir)/src \
|
||||
-I$(top_srcdir)/util/cairo-script \
|
||||
$(CAIRO_CFLAGS)
|
||||
|
||||
EXTRA_PROGRAMS += show-traps show-edges show-events
|
||||
EXTRA_PROGRAMS += show-traps show-edges show-events trace-to-xml xml-to-trace
|
||||
|
||||
trace_to_xml_LDADD = cairo-script/libcairo-script-interpreter.la $(top_builddir)/src/libcairo.la $(CAIRO_LDADD)
|
||||
|
||||
xml_to_trace_LDADD = -lexpat
|
||||
|
||||
show_traps_SOURCES = show-traps.c
|
||||
show_traps_CFLAGS = $(gtk_CFLAGS)
|
||||
|
|
|
|||
|
|
@ -667,6 +667,92 @@ base85_end (csi_t *ctx, csi_scanner_t *scan, cairo_bool_t deflate)
|
|||
longjmp (scan->jmpbuf, status);
|
||||
}
|
||||
|
||||
static void
|
||||
base64_add (csi_t *ctx, csi_scanner_t *scan, int c)
|
||||
{
|
||||
int val;
|
||||
|
||||
/* Convert Base64 character to its 6 bit nibble */
|
||||
val = scan->accumulator;
|
||||
if (c =='/') {
|
||||
val = (val << 6) | 63;
|
||||
} else if (c =='+') {
|
||||
val = (val << 6) | 62;
|
||||
} else if (c >='A' && c <='Z') {
|
||||
val = (val << 6) | (c -'A');
|
||||
} else if (c >='a' && c <='z') {
|
||||
val = (val << 6) | (c -'a' + 26);
|
||||
} else if (c >='0' && c <='9') {
|
||||
val = (val << 6) | (c -'0' + 52);
|
||||
}
|
||||
|
||||
buffer_check (ctx, scan, 1);
|
||||
switch (scan->accumulator_count++) {
|
||||
case 0:
|
||||
break;
|
||||
|
||||
case 1:
|
||||
buffer_add (&scan->buffer, (val >> 4) & 0xFF);
|
||||
val &= 0xF;
|
||||
break;
|
||||
|
||||
case 2:
|
||||
buffer_add (&scan->buffer, (val >> 2) & 0xFF);
|
||||
val &= 0x3;
|
||||
break;
|
||||
|
||||
case 3:
|
||||
buffer_add (&scan->buffer, (val >> 0) & 0xFF);
|
||||
scan->accumulator_count = 0;
|
||||
val = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
if (c == '=') {
|
||||
scan->accumulator_count = 0;
|
||||
scan->accumulator = 0;
|
||||
} else {
|
||||
scan->accumulator = val;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
base64_end (csi_t *ctx, csi_scanner_t *scan)
|
||||
{
|
||||
csi_object_t obj;
|
||||
cairo_status_t status;
|
||||
|
||||
switch (scan->accumulator_count) {
|
||||
case 0:
|
||||
break;
|
||||
case 2:
|
||||
base64_add (ctx, scan, (scan->accumulator << 2) & 0x3f);
|
||||
base64_add (ctx, scan, '=');
|
||||
break;
|
||||
case 1:
|
||||
base64_add (ctx, scan, (scan->accumulator << 4) & 0x3f);
|
||||
base64_add (ctx, scan, '=');
|
||||
base64_add (ctx, scan, '=');
|
||||
break;
|
||||
}
|
||||
|
||||
status = csi_string_new (ctx,
|
||||
&obj,
|
||||
scan->buffer.base,
|
||||
scan->buffer.ptr - scan->buffer.base);
|
||||
if (_csi_unlikely (status))
|
||||
longjmp (scan->jmpbuf, status);
|
||||
|
||||
if (scan->build_procedure.type != CSI_OBJECT_TYPE_NULL)
|
||||
status = csi_array_append (ctx,
|
||||
scan->build_procedure.datum.array,
|
||||
&obj);
|
||||
else
|
||||
status = scan_push (ctx, &obj);
|
||||
if (_csi_unlikely (status))
|
||||
longjmp (scan->jmpbuf, status);
|
||||
}
|
||||
|
||||
static inline void
|
||||
scan_read (csi_scanner_t *scan, csi_file_t *src, void *ptr, int len)
|
||||
{
|
||||
|
|
@ -782,6 +868,8 @@ scan_none:
|
|||
deflate = 1;
|
||||
case '~':
|
||||
goto scan_base85;
|
||||
case '{':
|
||||
goto scan_base64;
|
||||
default:
|
||||
csi_file_putc (src, next);
|
||||
goto scan_hex;
|
||||
|
|
@ -1204,6 +1292,31 @@ scan_base85:
|
|||
}
|
||||
}
|
||||
longjmp (scan->jmpbuf, _csi_error (CSI_STATUS_INVALID_SCRIPT));
|
||||
|
||||
scan_base64:
|
||||
buffer_reset (&scan->buffer);
|
||||
scan->accumulator = 0;
|
||||
scan->accumulator_count = 0;
|
||||
while ((c = csi_file_getc (src)) != EOF) {
|
||||
switch (c) {
|
||||
case '}':
|
||||
next = csi_file_getc (src);
|
||||
switch (next) {
|
||||
case EOF:
|
||||
return;
|
||||
|
||||
case '>':
|
||||
base64_end (ctx, scan);
|
||||
goto scan_none;
|
||||
}
|
||||
longjmp (scan->jmpbuf, _csi_error (CSI_STATUS_INVALID_SCRIPT));
|
||||
|
||||
default:
|
||||
base64_add (ctx, scan, c);
|
||||
break;
|
||||
}
|
||||
}
|
||||
longjmp (scan->jmpbuf, _csi_error (CSI_STATUS_INVALID_SCRIPT));
|
||||
}
|
||||
|
||||
static csi_status_t
|
||||
|
|
|
|||
77
util/trace-to-xml.c
Normal file
77
util/trace-to-xml.c
Normal file
|
|
@ -0,0 +1,77 @@
|
|||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include <cairo-xml.h>
|
||||
#include <cairo-script-interpreter.h>
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
static cairo_surface_t *
|
||||
_surface_create (void *_closure,
|
||||
cairo_content_t content,
|
||||
double width, double height)
|
||||
{
|
||||
cairo_surface_t **closure = _closure;
|
||||
cairo_surface_t *surface;
|
||||
cairo_rectangle_t extents;
|
||||
|
||||
extents.x = extents.y = 0;
|
||||
extents.width = width;
|
||||
extents.height = height;
|
||||
surface = cairo_meta_surface_create (content, &extents);
|
||||
if (*closure == NULL)
|
||||
*closure = cairo_surface_reference (surface);
|
||||
|
||||
return surface;
|
||||
}
|
||||
|
||||
static cairo_status_t
|
||||
stdio_write (void *closure, const unsigned char *data, unsigned len)
|
||||
{
|
||||
if (fwrite (data, len, 1, closure) == 1)
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
else
|
||||
return CAIRO_STATUS_WRITE_ERROR;
|
||||
}
|
||||
|
||||
int
|
||||
main (int argc, char **argv)
|
||||
{
|
||||
cairo_surface_t *surface = NULL;
|
||||
const cairo_script_interpreter_hooks_t hooks = {
|
||||
.closure = &surface,
|
||||
.surface_create = _surface_create,
|
||||
};
|
||||
cairo_script_interpreter_t *csi;
|
||||
FILE *in = stdin, *out = stdout;
|
||||
|
||||
if (argc >= 2 && strcmp (argv[1], "-"))
|
||||
in = fopen (argv[1], "r");
|
||||
if (argc >= 3 && strcmp (argv[2], "-"))
|
||||
out = fopen (argv[2], "w");
|
||||
|
||||
csi = cairo_script_interpreter_create ();
|
||||
cairo_script_interpreter_install_hooks (csi, &hooks);
|
||||
cairo_script_interpreter_feed_stream (csi, in);
|
||||
cairo_script_interpreter_finish (csi);
|
||||
cairo_script_interpreter_destroy (csi);
|
||||
|
||||
if (surface != NULL) {
|
||||
cairo_xml_t *xml;
|
||||
|
||||
xml = cairo_xml_create_for_stream (stdio_write, out);
|
||||
cairo_xml_for_meta_surface (xml, surface);
|
||||
cairo_xml_destroy (xml);
|
||||
|
||||
cairo_surface_destroy (surface);
|
||||
}
|
||||
|
||||
if (in != stdin)
|
||||
fclose (in);
|
||||
if (out != stdout)
|
||||
fclose (out);
|
||||
|
||||
return 0;
|
||||
}
|
||||
263
util/xml-to-trace.c
Normal file
263
util/xml-to-trace.c
Normal file
|
|
@ -0,0 +1,263 @@
|
|||
#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;
|
||||
}
|
||||
Loading…
Add table
Reference in a new issue