From: Andrea Zagli Date: Sun, 11 Mar 2007 07:46:51 +0000 (+0000) Subject: Initial import. X-Git-Tag: 0.2.0~42 X-Git-Url: https://saetta.ns0.it/gitweb?a=commitdiff_plain;h=901d9fee1fc97adf3985117c7a5a97fc88329b87;p=reptool%2Flibreptool Initial import. git-svn-id: svn+ssh://saetta.homelinux.org/svn/libreptool/trunk@1 3191ed1d-3fce-41bb-ab4a-0cebc0943b59 --- 901d9fee1fc97adf3985117c7a5a97fc88329b87 diff --git a/AUTHORS b/AUTHORS new file mode 100644 index 0000000..948556f --- /dev/null +++ b/AUTHORS @@ -0,0 +1 @@ +Andrea Zagli diff --git a/ChangeLog b/ChangeLog new file mode 100644 index 0000000..e69de29 diff --git a/Makefile.am b/Makefile.am new file mode 100644 index 0000000..d5c57dd --- /dev/null +++ b/Makefile.am @@ -0,0 +1,7 @@ +SUBDIRS = src tests + +EXTRA_DIST = libreptool.pc.in + +pkgconfigdir = $(libdir)/pkgconfig +pkgconfig_DATA = libreptool.pc + diff --git a/NEWS b/NEWS new file mode 100644 index 0000000..e69de29 diff --git a/README b/README new file mode 100644 index 0000000..e69de29 diff --git a/autogen.sh b/autogen.sh new file mode 100755 index 0000000..c286803 --- /dev/null +++ b/autogen.sh @@ -0,0 +1,98 @@ +#!/bin/sh +# Run this to generate all the initial makefiles, etc. + +srcdir=`dirname $0` +test -z "$srcdir" && srcdir=. + +ORIGDIR=`pwd` +cd $srcdir +PROJECT=libreptool +TEST_TYPE=-f +FILE=configure.ac + +DIE=0 + +have_libtool=false +if libtoolize --version < /dev/null > /dev/null 2>&1 ; then + libtool_version=`libtoolize --version | sed 's/^[^0-9]*\([0-9.][0-9.]*\).*/\1/'` + case $libtool_version in + 1.4*|1.5*) + have_libtool=true + ;; + esac +fi +if $have_libtool ; then : ; else + echo + echo "You must have libtool 1.4 installed to compile $PROJECT." + echo "Install the appropriate package for your distribution," + echo "or get the source tarball at http://ftp.gnu.org/gnu/libtool/" + DIE=1 +fi + +(gtkdocize --version) < /dev/null > /dev/null 2>&1 || { + echo + echo "You must have gtk-doc installed to compile $PROJECT." + echo "Install the appropriate package for your distribution," + echo "or get the source tarball at http://ftp.gnome.org/pub/GNOME/sources/gtk-doc/" + DIE=1 +} + +(autoconf --version) < /dev/null > /dev/null 2>&1 || { + echo + echo "You must have autoconf installed to compile $PROJECT." + echo "Install the appropriate package for your distribution," + echo "or get the source tarball at http://ftp.gnu.org/gnu/autoconf/" + DIE=1 +} + +if automake --version < /dev/null > /dev/null 2>&1 ; then + AUTOMAKE=automake + ACLOCAL=aclocal +else + echo + echo "You must have automake 1.7.x installed to compile $PROJECT." + echo "Install the appropriate package for your distribution," + echo "or get the source tarball at http://ftp.gnu.org/gnu/automake/" + DIE=1 +fi + +if test "$DIE" -eq 1; then + exit 1 +fi + +test $TEST_TYPE $FILE || { + echo "You must run this script in the top-level $PROJECT directory" + exit 1 +} + +if test -z "$AUTOGEN_SUBDIR_MODE"; then + if test -z "$*"; then + echo "I am going to run ./configure with no arguments - if you wish " + echo "to pass any to it, please specify them on the $0 command line." + fi +fi + +rm -rf autom4te.cache + +# README and INSTALL are required by automake, but may be deleted by clean +# up rules. to get automake to work, simply touch these here, they will be +# regenerated from their corresponding *.in files by ./configure anyway. +touch README INSTALL + +$ACLOCAL || exit $? + +libtoolize --force || exit $? +gtkdocize || exit $? + +autoheader || exit $? + +$AUTOMAKE --add-missing || exit $? +autoconf || exit $? +cd $ORIGDIR || exit $? + +if test -z "$AUTOGEN_SUBDIR_MODE"; then + $srcdir/configure --enable-maintainer-mode $AUTOGEN_CONFIGURE_ARGS "$@" || exit $? + + echo + echo "Now type 'make' to compile $PROJECT." +fi diff --git a/config.h.in b/config.h.in new file mode 100644 index 0000000..0e1824b --- /dev/null +++ b/config.h.in @@ -0,0 +1,58 @@ +/* config.h.in. Generated from configure.ac by autoheader. */ + +/* Define to 1 if you have the header file. */ +#undef HAVE_DLFCN_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_INTTYPES_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_MEMORY_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_STDINT_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_STDLIB_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_STRINGS_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_STRING_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_STAT_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_TYPES_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_UNISTD_H + +/* Name of package */ +#undef PACKAGE + +/* Define to the address where bug reports for this package should be sent. */ +#undef PACKAGE_BUGREPORT + +/* Define to the full name of this package. */ +#undef PACKAGE_NAME + +/* Define to the full name and version of this package. */ +#undef PACKAGE_STRING + +/* Define to the one symbol short name of this package. */ +#undef PACKAGE_TARNAME + +/* Define to the version of this package. */ +#undef PACKAGE_VERSION + +/* Define to 1 if you have the ANSI C header files. */ +#undef STDC_HEADERS + +/* Version number of package */ +#undef VERSION + +/* Define to empty if `const' does not conform to ANSI C. */ +#undef const diff --git a/configure.ac b/configure.ac new file mode 100644 index 0000000..71f1041 --- /dev/null +++ b/configure.ac @@ -0,0 +1,42 @@ +# -*- Autoconf -*- +# Process this file with autoconf to produce a configure script. + +AC_PREREQ(2.59) +AC_INIT([libreptool], [0.0.1], [azagli@inwind.it]) +AC_CONFIG_SRCDIR([src/rptprint.c]) +AC_CONFIG_HEADER([config.h]) + +AM_INIT_AUTOMAKE +AM_MAINTAINER_MODE +AC_LIBTOOL_WIN32_DLL + +AC_CANONICAL_SYSTEM + +# Checks for programs. +AC_PROG_CC +AC_PROG_LIBTOOL + +# Checks for libraries. +PKG_CHECK_MODULES([REPTOOL], [glib-2.0 >= 2.6.0 + gobject-2.0 >= 2.6.0 + libxml-2.0 >= 2.6.0 + cairo >= 1.0.0 + pangocairo >= 1.12]) + +AC_SUBST(REPTOOL_CFLAGS) +AC_SUBST(REPTOOL_LIBS) + +# Checks for header files. + +# Checks for typedefs, structures, and compiler characteristics. +AC_C_CONST + +# Checks for library functions. + +AC_CONFIG_FILES([ + libreptool.pc + Makefile + src/Makefile + tests/Makefile +]) +AC_OUTPUT diff --git a/data/reptool.dtd b/data/reptool.dtd new file mode 100644 index 0000000..2efcf24 --- /dev/null +++ b/data/reptool.dtd @@ -0,0 +1,145 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/data/reptool_report.dtd b/data/reptool_report.dtd new file mode 100644 index 0000000..5fe1e16 --- /dev/null +++ b/data/reptool_report.dtd @@ -0,0 +1,99 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/libreptool.pc.in b/libreptool.pc.in new file mode 100644 index 0000000..9c36abc --- /dev/null +++ b/libreptool.pc.in @@ -0,0 +1,12 @@ +prefix=@prefix@ +exec_prefix=@exec_prefix@ +libdir=@libdir@ +includedir=@includedir@ + +Name: @PACKAGE_NAME@ +Description: Library to manage Reptool files +Version: @PACKAGE_VERSION@ +Requires: glib-2.0 gobject-2.0 libxml-2.0 +Libs: -L${libdir} -lreptool +Cflags: -I${includedir} + diff --git a/src/Makefile.am b/src/Makefile.am new file mode 100644 index 0000000..27617e4 --- /dev/null +++ b/src/Makefile.am @@ -0,0 +1,9 @@ +LIBS = $(REPTOOL_LIBS) + +AM_CPPFLAGS = $(REPTOOL_CFLAGS) + +lib_LTLIBRARIES = libreptool.la + +libreptool_la_SOURCES = rptprint.c + +include_HEADERS = rptprint.h diff --git a/src/rptprint.c b/src/rptprint.c new file mode 100644 index 0000000..0c3a16a --- /dev/null +++ b/src/rptprint.c @@ -0,0 +1,1041 @@ +/* + * Copyright (C) 2006 Andrea Zagli + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#include +#include + +#include +#include + +#include "rptprint.h" + +typedef struct +{ + gdouble x, + y; +} RptPoint; + +typedef struct +{ + gdouble width, + height; +} RptSize; + +typedef enum +{ + RPT_HALIGN_LEFT, + RPT_HALIGN_CENTER, + RPT_HALIGN_RIGHT, + RPT_HALIGN_JUSTIFIED +} eRptHAlign; + +typedef enum +{ + RPT_VALIGN_TOP, + RPT_VALIGN_CENTER, + RPT_VALIGN_BOTTOM +} eRptVAlign; + +typedef struct +{ + eRptHAlign h_align; + eRptVAlign v_align; +} RptAlign; + +typedef struct +{ + gdouble r, + g, + b, + a; +} RptColor; + +typedef struct +{ + gdouble top_width, + right_width, + bottom_width, + left_width; + RptColor top_color, + right_color, + bottom_color, + left_color; +} RptBorder; + +typedef struct +{ + gchar *name; + gdouble size; + gboolean bold, + italic, + underline, + strike; + RptColor color; +} RptFont; + +typedef struct +{ + gdouble width; + RptColor color; +} RptStroke; + +enum +{ + PROP_0 +}; + +static void rpt_print_class_init (RptPrintClass *klass); +static void rpt_print_init (RptPrint *rpt_print); + +static void rpt_print_set_property (GObject *object, + guint property_id, + const GValue *value, + GParamSpec *pspec); +static void rpt_print_get_property (GObject *object, + guint property_id, + GValue *value, + GParamSpec *pspec); + +static void rpt_print_page (RptPrint *rpt_print, + xmlNode *xnode); +static void rpt_print_text_xml (RptPrint *rpt_print, + xmlNode *xnode); +static void rpt_print_line_xml (RptPrint *rpt_print, + xmlNode *xnode); +static void rpt_print_rect_xml (RptPrint *rpt_print, + xmlNode *xnode); +static void rpt_print_image_xml (RptPrint *rpt_print, + xmlNode *xnode); +static void rpt_print_line (RptPrint *rpt_print, + RptPoint from_p, + RptPoint to_p, + RptStroke stroke); +static void rpt_print_border (RptPrint *rpt_print, + RptPoint position, + RptSize size, + RptBorder border); +static void rpt_print_get_position (xmlNode *xnode, + RptPoint *position); +static void rpt_print_get_size (xmlNode *xnode, + RptSize *size); +static void rpt_print_get_align (xmlNode *xnode, + RptAlign *align); +static void rpt_print_get_border (xmlNode *xnode, + RptBorder *border); +static void rpt_print_get_stroke (xmlNode *xnode, + RptStroke *stroke); +static void rpt_print_get_font (xmlNode *xnode, + RptFont *font); +static void rpt_print_parse_color (const gchar *str_color, + RptColor *color); + + +#define RPT_PRINT_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), TYPE_RPT_PRINT, RptPrintPrivate)) + +typedef struct _RptPrintPrivate RptPrintPrivate; +struct _RptPrintPrivate + { + gint width, + height; + cairo_surface_t *surface; + cairo_t *cr; + }; + +GType +rpt_print_get_type (void) +{ + static GType rpt_print_type = 0; + + if (!rpt_print_type) + { + static const GTypeInfo rpt_print_info = + { + sizeof (RptPrintClass), + NULL, /* base_init */ + NULL, /* base_finalize */ + (GClassInitFunc) rpt_print_class_init, + NULL, /* class_finalize */ + NULL, /* class_data */ + sizeof (RptPrint), + 0, /* n_preallocs */ + (GInstanceInitFunc) rpt_print_init, + NULL + }; + + rpt_print_type = g_type_register_static (G_TYPE_OBJECT, "RptPrint", + &rpt_print_info, 0); + } + + return rpt_print_type; +} + +static void +rpt_print_class_init (RptPrintClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + + g_type_class_add_private (object_class, sizeof (RptPrintPrivate)); + + object_class->set_property = rpt_print_set_property; + object_class->get_property = rpt_print_get_property; +} + +static void +rpt_print_init (RptPrint *rpt_print) +{ +} + +/** + * rpt_print_new_from_xml: + * @xdoc: an #xmlDoc. + * @output_type: + * @out_filename: + * + * Returns: the newly created #RptPrint object. + */ +RptPrint +*rpt_print_new_from_xml (xmlDoc *xdoc, RptPrintOutputType output_type, const gchar *out_filename) +{ + RptPrint *rpt_print = NULL; + + xmlNode *cur = xmlDocGetRootElement (xdoc); + if (cur != NULL) + { + if (strcmp (cur->name, "reptool_report") == 0) + { +#if 0 + FILE *fout; +#endif + RptPrintPrivate *priv; + + gint npage = 0; + + rpt_print = RPT_PRINT (g_object_new (rpt_print_get_type (), NULL)); + + priv = RPT_PRINT_GET_PRIVATE (rpt_print); +#if 0 + if (output_type != RPTP_OUTPUT_PNG) + { + fout = fopen ("test.pdf", "w"); + if (fout == NULL) + { + /* TO DO */ + return NULL; + } + } +#endif + cur = cur->children; + while (cur != NULL) + { + if (strcmp (cur->name, "page") == 0) + { + npage++; + + priv->width = atol (xmlGetProp (cur, (const xmlChar *)"width")); + priv->height = atol (xmlGetProp (cur, (const xmlChar *)"height")); + + if (priv->width != 0 && priv->height != 0) + { + if (npage == 1) + { + switch (output_type) + { + case RPTP_OUTPUT_PNG: + priv->surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, priv->width, priv->height); + break; + + case RPTP_OUTPUT_PDF: + priv->surface = cairo_pdf_surface_create ("test.pdf", (double)priv->width, (double)priv->height); + break; + + case RPTP_OUTPUT_PS: + priv->surface = cairo_ps_surface_create ("test.ps", (double)priv->width, (double)priv->height); + break; + + case RPTP_OUTPUT_SVG: + priv->surface = cairo_svg_surface_create ("test.svg", (double)priv->width, (double)priv->height); + break; + } + } + + if (cairo_surface_status (priv->surface) == CAIRO_STATUS_SUCCESS) + { + if (npage == 1) + { + priv->cr = cairo_create (priv->surface); + } + else + { + /* TO DO */ + } + + if (npage == 1 && output_type != RPTP_OUTPUT_PNG) + { + cairo_surface_destroy (priv->surface); + } + + if (cairo_status (priv->cr) == CAIRO_STATUS_SUCCESS) + { + rpt_print_page (rpt_print, cur); + if (output_type == RPTP_OUTPUT_PNG) + { + cairo_surface_write_to_png (priv->surface, "test.png"); + cairo_surface_destroy (priv->surface); + } + + cairo_show_page (priv->cr); + } + else + { + /* TO DO */ + } + } + else + { + /* TO DO */ + } + } + else + { + /* TO DO */ + } + } + else + { + /* TO DO */ + } + + cur = cur->next; + } + + if (priv->cr != NULL) + { + cairo_destroy (priv->cr); + } +#if 0 + if (output_type != RPTP_OUTPUT_PNG) + { + fclose (fout); + } +#endif + } + else + { + /* TO DO */ + } + } + + return rpt_print; +} + +/** + * rpt_print_new_from_file: + * @filename: the path of the xml file to load. + * @output_type: + * @out_filename: + * + * Returns: the newly created #RptPrint object. + */ +RptPrint +*rpt_print_new_from_file (const gchar *filename, RptPrintOutputType output_type, const gchar *out_filename) +{ + RptPrint *rpt_print = NULL; + + xmlDoc *xdoc = xmlParseFile (filename); + if (xdoc != NULL) + { + rpt_print = rpt_print_new_from_xml (xdoc, output_type, out_filename); + } + + return rpt_print; +} + +static void +rpt_print_set_property (GObject *object, guint property_id, const GValue *value, GParamSpec *pspec) +{ + RptPrint *rpt_print = RPT_PRINT (object); + + RptPrintPrivate *priv = RPT_PRINT_GET_PRIVATE (rpt_print); + + switch (property_id) + { + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); + break; + } +} + +static void +rpt_print_get_property (GObject *object, guint property_id, GValue *value, GParamSpec *pspec) +{ + RptPrint *rpt_print = RPT_PRINT (object); + + RptPrintPrivate *priv = RPT_PRINT_GET_PRIVATE (rpt_print); + + switch (property_id) + { + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); + break; + } +} + +static void +rpt_print_page (RptPrint *rpt_print, xmlNode *xnode) +{ + xmlNode *cur = xnode->children; + + while (cur != NULL) + { + if (strcmp (cur->name, "text") == 0) + { + rpt_print_text_xml (rpt_print, cur); + } + else if (strcmp (cur->name, "line") == 0) + { + rpt_print_line_xml (rpt_print, cur); + } + else if (strcmp (cur->name, "rect") == 0) + { + rpt_print_rect_xml (rpt_print, cur); + } + else if (strcmp (cur->name, "image") == 0) + { + rpt_print_image_xml (rpt_print, cur); + } + + cur = cur->next; + } +} + +static void +rpt_print_text_xml (RptPrint *rpt_print, xmlNode *xnode) +{ + RptPrintPrivate *priv = RPT_PRINT_GET_PRIVATE (rpt_print); + + RptPoint position; + RptSize size; + RptAlign align; + RptBorder border; + RptFont font; + RptColor color; + + PangoLayout *playout; + PangoFontDescription *pfdesc; + + gchar *text = (gchar *)xmlNodeGetContent (xnode), + *prop, + *str_font; + + gdouble pad_top, + pad_right, + pad_bottom, + pad_left; + + rpt_print_get_position (xnode, &position); + rpt_print_get_size (xnode, &size); + rpt_print_get_align (xnode, &align); + rpt_print_get_border (xnode, &border); + rpt_print_get_font (xnode, &font); + + /* padding */ + prop = xmlGetProp (xnode, (const xmlChar *)"padding-top"); + if (prop != NULL) + { + pad_top = atof (prop); + } + prop = xmlGetProp (xnode, (const xmlChar *)"padding-right"); + if (prop != NULL) + { + pad_right= atof (prop); + } + prop = xmlGetProp (xnode, (const xmlChar *)"padding-bottom"); + if (prop != NULL) + { + pad_bottom= atof (prop); + } + prop = xmlGetProp (xnode, (const xmlChar *)"padding-left"); + if (prop != NULL) + { + pad_left= atof (prop); + } + + /* creating pango layout */ + playout = pango_cairo_create_layout (priv->cr); + pango_layout_set_width (playout, size.width * PANGO_SCALE); + + str_font = g_strdup (font.name); + if (font.bold) + { + str_font = g_strjoin (NULL, str_font, " bold", NULL); + } + if (font.italic) + { + str_font = g_strjoin (NULL, str_font, " italic", NULL); + } + /*if (font.underline) + { + }*/ + /*if (font.strike) + { + }*/ + if (font.size > 0) + { + str_font = g_strjoin (NULL, str_font, g_strdup_printf (" %f", font.size), NULL); + } + else + { + str_font = g_strjoin (NULL, str_font, " 12", NULL); + } + + /* creating pango font description */ + pfdesc = pango_font_description_from_string (str_font); + pango_layout_set_font_description (playout, pfdesc); + pango_font_description_free (pfdesc); + + /* background */ + prop = xmlGetProp (xnode, (const xmlChar *)"background-color"); + if (prop != NULL) + { + rpt_print_parse_color (prop, &color); + } + + /* drawing border */ + rpt_print_border (rpt_print, position, size, border); + + /* setting alignment */ + switch (align.h_align) + { + case RPT_HALIGN_LEFT: + break; + + case RPT_HALIGN_CENTER: + pango_layout_set_alignment (playout, PANGO_ALIGN_CENTER); + break; + + case RPT_HALIGN_RIGHT: + pango_layout_set_alignment (playout, PANGO_ALIGN_RIGHT); + break; + + case RPT_HALIGN_JUSTIFIED: + pango_layout_set_justify (playout, TRUE); + break; + } + + switch (align.v_align) + { + case RPT_VALIGN_TOP: + break; + + case RPT_VALIGN_CENTER: + break; + + case RPT_VALIGN_BOTTOM: + break; + } + + /* setting clipping region */ + cairo_rectangle (priv->cr, position.x, position.y, size.width, size.height); + cairo_clip (priv->cr); + + /* drawing text */ + cairo_set_source_rgba (priv->cr, font.color.r, font.color.g, font.color.b, font.color.a); + cairo_move_to (priv->cr, position.x, position.y); + pango_layout_set_text (playout, text, -1); + pango_cairo_show_layout (priv->cr, playout); + + cairo_reset_clip (priv->cr); +} + +static void +rpt_print_line_xml (RptPrint *rpt_print, xmlNode *xnode) +{ + RptPoint position, + from_p, + to_p; + RptSize size; + RptStroke stroke; + + rpt_print_get_position (xnode, &position); + rpt_print_get_size (xnode, &size); + rpt_print_get_stroke (xnode, &stroke); + + from_p.x = position.x; + from_p.y = position.y; + to_p.x = position.x + size.width; + to_p.y = position.y + size.height; + + rpt_print_line (rpt_print, from_p, to_p, stroke); +} + +static void +rpt_print_rect_xml (RptPrint *rpt_print, xmlNode *xnode) +{ + RptPoint position, + from_p, + to_p; + RptSize size; + RptStroke stroke; + RptColor fill_color; + + RptPrintPrivate *priv = RPT_PRINT_GET_PRIVATE (rpt_print); + + rpt_print_get_position (xnode, &position); + rpt_print_get_size (xnode, &size); + rpt_print_get_stroke (xnode, &stroke); + + gchar *prop = xmlGetProp (xnode, (const xmlChar *)"fill-color"); + if (prop != NULL) + { + fill_color.r = 0.0; + fill_color.g = 0.0; + fill_color.b = 0.0; + fill_color.a = 1.0; + rpt_print_parse_color (prop, &fill_color); + } + + /*cairo_set_line_width (priv->cr, stroke.width);*/ + cairo_rectangle (priv->cr, position.x, position.y, size.width, size.height); + + if (prop != NULL) + { + cairo_set_source_rgba (priv->cr, fill_color.r, fill_color.g, fill_color.b, fill_color.a); + cairo_fill_preserve (priv->cr); + } + + cairo_set_source_rgba (priv->cr, stroke.color.r, stroke.color.g, stroke.color.b, stroke.color.a); + cairo_stroke (priv->cr); +} + +static void +rpt_print_image_xml (RptPrint *rpt_print, xmlNode *xnode) +{ + RptPoint position; + RptSize size; + RptBorder border; + + cairo_surface_t *image; + cairo_pattern_t *pattern; + cairo_matrix_t matrix; + + gint w, h; + + RptPrintPrivate *priv = RPT_PRINT_GET_PRIVATE (rpt_print); + + gchar *adapt, + *filename= xmlGetProp (xnode, (const xmlChar *)"source"); + if (filename == NULL) + { + return; + } + + adapt = xmlGetProp (xnode, (const xmlChar *)"adapt"); + if (adapt == NULL) + { + adapt = "none"; + } + else + { + g_strstrip (adapt); + } + + rpt_print_get_position (xnode, &position); + rpt_print_get_size (xnode, &size); + rpt_print_get_border (xnode, &border); + + image = cairo_image_surface_create_from_png (filename); + + pattern = cairo_pattern_create_for_surface (image); + + cairo_matrix_init_identity (&matrix); + if (strcmp (adapt, "none") != 0) + { + w = cairo_image_surface_get_width (image); + h = cairo_image_surface_get_height (image); + + if (strcmp (adapt, "to-box") == 0) + { + cairo_matrix_scale (&matrix, w / size.width, h / size.height); + } + else if (strcmp (adapt, "to-image") == 0) + { + size.width = (gdouble)w; + size.height = (gdouble)h; + } + } + cairo_matrix_translate (&matrix, -position.x, -position.y); + + cairo_pattern_set_matrix (pattern, &matrix); + cairo_set_source (priv->cr, pattern); + + cairo_rectangle (priv->cr, position.x, position.y, size.width, size.height); + cairo_fill (priv->cr); + + rpt_print_border (rpt_print, position, size, border); + + cairo_pattern_destroy (pattern); + cairo_surface_destroy (image); +} + +static void +rpt_print_line (RptPrint *rpt_print, RptPoint from_p, RptPoint to_p, RptStroke stroke) +{ + RptPrintPrivate *priv = RPT_PRINT_GET_PRIVATE (rpt_print); + + /*cairo_set_line_width (priv->cr, stroke.width);*/ + cairo_set_source_rgba (priv->cr, stroke.color.r, stroke.color.g, stroke.color.b, stroke.color.a); + cairo_move_to (priv->cr, from_p.x, from_p.y); + cairo_line_to (priv->cr, to_p.x, to_p.y); + cairo_stroke (priv->cr); +} + +static void +rpt_print_border (RptPrint *rpt_print, RptPoint position, RptSize size, RptBorder border) +{ + RptPrintPrivate *priv = RPT_PRINT_GET_PRIVATE (rpt_print); + + RptPoint from_p, + to_p; + RptStroke stroke; + + if (border.top_width != 0.0) + { + from_p.x = position.x; + from_p.y = position.y; + to_p.x = position.x + size.width; + to_p.y = position.y; + stroke.width = border.top_width; + stroke.color = border.top_color; + rpt_print_line (rpt_print, from_p, to_p, stroke); + } + if (border.right_width != 0.0) + { + from_p.x = position.x + size.width; + from_p.y = position.y; + to_p.x = position.x + size.width; + to_p.y = position.y + size.height; + stroke.width = border.right_width; + stroke.color = border.right_color; + rpt_print_line (rpt_print, from_p, to_p, stroke); + } + if (border.bottom_width != 0.0) + { + from_p.x = position.x; + from_p.y = position.y + size.height; + to_p.x = position.x + size.width; + to_p.y = position.y + size.height; + stroke.width = border.bottom_width; + stroke.color = border.bottom_color; + rpt_print_line (rpt_print, from_p, to_p, stroke); + } + if (border.left_width != 0.0) + { + from_p.x = position.x; + from_p.y = position.y; + to_p.x = position.x; + to_p.y = position.y + size.height; + stroke.width = border.left_width; + stroke.color = border.left_color; + rpt_print_line (rpt_print, from_p, to_p, stroke); + } +} + +static void +rpt_print_get_position (xmlNode *xnode, RptPoint *position) +{ + gchar *prop; + + position->x = 0.0; + position->y = 0.0; + + prop = xmlGetProp (xnode, (const xmlChar *)"x"); + if (prop != NULL) + { + position->x = strtod (prop, NULL); + } + prop = xmlGetProp (xnode, (const xmlChar *)"y"); + if (prop != NULL) + { + position->y = strtod (prop, NULL); + } +} + +static void +rpt_print_get_size (xmlNode *xnode, RptSize *size) +{ + gchar *prop; + + size->width = 0.0; + size->height = 0.0; + + prop = xmlGetProp (xnode, (const xmlChar *)"width"); + if (prop != NULL) + { + size->width = strtod (prop, NULL); + } + prop = xmlGetProp (xnode, (const xmlChar *)"height"); + if (prop != NULL) + { + size->height = strtod (prop, NULL); + } +} + +static void +rpt_print_get_align (xmlNode *xnode, RptAlign *align) +{ + gchar *prop; + + align->h_align = RPT_HALIGN_LEFT; + align->v_align = RPT_VALIGN_TOP; + + prop = xmlGetProp (xnode, "horizontal-align"); + if (prop != NULL) + { + if (strcmp (prop, "center") == 0) + { + align->h_align = RPT_HALIGN_CENTER; + } + else if (strcmp (prop, "right") == 0) + { + align->h_align = RPT_HALIGN_RIGHT; + } + else if (strcmp (prop, "justified") == 0) + { + align->h_align = RPT_HALIGN_JUSTIFIED; + } + } + + prop = xmlGetProp (xnode, "vertical-align"); + if (prop != NULL) + { + if (strcmp (prop, "center") == 0) + { + align->v_align = RPT_VALIGN_CENTER; + } + else if (strcmp (prop, "bottom") == 0) + { + align->v_align = RPT_VALIGN_BOTTOM; + } + } +} + +static void +rpt_print_get_border (xmlNode *xnode, RptBorder *border) +{ + gchar *prop; + + border->top_width = 0.0; + border->right_width = 0.0; + border->bottom_width = 0.0; + border->left_width = 0.0; + border->top_color.r = 0.0; + border->top_color.g = 0.0; + border->top_color.b = 0.0; + border->top_color.a = 1.0; + border->right_color.r = 0.0; + border->right_color.g = 0.0; + border->right_color.b = 0.0; + border->right_color.a = 1.0; + border->bottom_color.r = 0.0; + border->bottom_color.g = 0.0; + border->bottom_color.b = 0.0; + border->bottom_color.a = 1.0; + border->left_color.r = 0.0; + border->left_color.g = 0.0; + border->left_color.b = 0.0; + border->left_color.a = 1.0; + + prop = xmlGetProp (xnode, "border-top-width"); + if (prop != NULL) + { + border->top_width = strtod (prop, NULL); + } + + prop = xmlGetProp (xnode, "border-right-width"); + if (prop != NULL) + { + border->right_width = strtod (prop, NULL); + } + + prop = xmlGetProp (xnode, "border-bottom-width"); + if (prop != NULL) + { + border->bottom_width = strtod (prop, NULL); + } + + prop = xmlGetProp (xnode, "border-left-width"); + if (prop != NULL) + { + border->left_width = strtod (prop, NULL); + } + + prop = xmlGetProp (xnode, "border-top-color"); + if (prop != NULL) + { + rpt_print_parse_color (prop, &border->top_color); + } + + prop = xmlGetProp (xnode, "border-right-color"); + if (prop != NULL) + { + rpt_print_parse_color (prop, &border->right_color); + } + + prop = xmlGetProp (xnode, "border-bottom-color"); + if (prop != NULL) + { + rpt_print_parse_color (prop, &border->bottom_color); + } + + prop = xmlGetProp (xnode, "border-left-color"); + if (prop != NULL) + { + rpt_print_parse_color (prop, &border->left_color); + } +} + +static void +rpt_print_get_stroke (xmlNode *xnode, RptStroke *stroke) +{ + gchar *prop; + + stroke->width = 1.0; + stroke->color.r = 0.0; + stroke->color.g = 0.0; + stroke->color.b = 0.0; + stroke->color.a = 1.0; + + prop = xmlGetProp (xnode, "stroke-width"); + if (prop != NULL) + { + stroke->width = strtod (prop, NULL); + } + + prop = xmlGetProp (xnode, "stroke-color"); + if (prop != NULL) + { + rpt_print_parse_color (prop, &stroke->color); + } +} + +static void +rpt_print_get_font (xmlNode *xnode, RptFont *font) +{ + gchar *prop; + + font->name = g_strdup ("sans"); + font->size = 12.0; + font->bold = FALSE; + font->italic = FALSE; + font->underline = FALSE; + font->strike = FALSE; + font->color.r = 0.0; + font->color.g = 0.0; + font->color.b = 0.0; + font->color.a = 1.0; + + prop = xmlGetProp (xnode, "font-name"); + if (prop != NULL) + { + font->name = g_strdup (prop); + } + + prop = xmlGetProp (xnode, "font-size"); + if (prop != NULL) + { + font->size = strtod (prop, NULL); + } + + prop = xmlGetProp (xnode, "font-bold"); + if (prop != NULL) + { + font->bold = (strcmp (g_strstrip (prop), "y") == 0); + } + + prop = xmlGetProp (xnode, "font-italic"); + if (prop != NULL) + { + font->italic = (strcmp (g_strstrip (prop), "y") == 0); + } + + prop = xmlGetProp (xnode, "font-underline"); + if (prop != NULL) + { + font->underline = (strcmp (g_strstrip (prop), "y") == 0); + } + + prop = xmlGetProp (xnode, "font-strike"); + if (prop != NULL) + { + font->strike = (strcmp (g_strstrip (prop), "y") == 0); + } + + prop = xmlGetProp (xnode, "font-color"); + if (prop != NULL) + { + rpt_print_parse_color (prop, &font->color); + } +} + +static void +rpt_print_parse_color (const gchar *str_color, RptColor *color) +{ + gchar *c = g_strstrip (g_strdup (str_color)); + + if (c[0] == '#') + { + if (strlen (c) == 4 || strlen (c) == 5) + { + if (isxdigit (c[1])) + { + color->r = strtol (g_strdup_printf ("%c%c", c[1], c[1]), NULL, 16) / 255.0; + } + if (isxdigit (c[2])) + { + color->g = strtol (g_strdup_printf ("%c%c", c[2], c[2]), NULL, 16) / 255.0; + } + if (isxdigit (c[3])) + { + color->b = strtol (g_strdup_printf ("%c%c", c[3], c[3]), NULL, 16) / 255.0; + } + if (strlen (c) == 5 && isxdigit (c[4])) + { + color->a = strtol (g_strdup_printf ("%c%c", c[4], c[4]), NULL, 16) / 255.0; + } + } + else if (strlen (c) == 7 || strlen (c) == 9) + { + if (isxdigit (c[1]) && isxdigit (c[2])) + { + color->r = strtol (g_strndup (&c[1], 2), NULL, 16) / 255.0; + } + if (isxdigit (c[3]) && isxdigit (c[4])) + { + color->g = strtol (g_strndup (&c[3], 2), NULL, 16) / 255.0; + } + if (isxdigit (c[5]) && isxdigit (c[6])) + { + color->b = strtol (g_strndup (&c[5], 2), NULL, 16) / 255.0; + } + if (strlen (c) == 9) + { + color->a = strtol (g_strndup (&c[7], 2), NULL, 16) / 255.0; + } + } + } +} diff --git a/src/rptprint.h b/src/rptprint.h new file mode 100644 index 0000000..e70a03a --- /dev/null +++ b/src/rptprint.h @@ -0,0 +1,67 @@ +/* + * Copyright (C) 2006 Andrea Zagli + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#ifndef __RPT_PRINT_H__ +#define __RPT_PRINT_H__ + +#include +#include +#include + +G_BEGIN_DECLS + + +#define TYPE_RPT_PRINT (rpt_print_get_type ()) +#define RPT_PRINT(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), TYPE_RPT_PRINT, RptPrint)) +#define RPT_PRINT_COMMON_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), TYPE_RPT_PRINT, RptPrintClass)) +#define IS_RPT_PRINT(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), TYPE_RPT_PRINT)) +#define IS_RPT_PRINT_COMMON_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), TYPE_RPT_PRINT)) +#define RPT_PRINT_COMMON_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), TYPE_RPT_PRINT, RptPrintClass)) + + +typedef struct _RptPrint RptPrint; +typedef struct _RptPrintClass RptPrintClass; + +struct _RptPrint + { + GObject parent; + }; + +struct _RptPrintClass + { + GObjectClass parent_class; + }; + +GType rpt_print_get_type (void) G_GNUC_CONST; + + +typedef enum +{ + RPTP_OUTPUT_PNG, + RPTP_OUTPUT_PDF, + RPTP_OUTPUT_PS, + RPTP_OUTPUT_SVG +} RptPrintOutputType; + +RptPrint *rpt_print_new_from_xml (xmlDoc *xdoc, RptPrintOutputType output_type, const gchar *out_filename); +RptPrint *rpt_print_new_from_file (const gchar *filename, RptPrintOutputType output_type, const gchar *out_filename); + + +G_END_DECLS + +#endif /* __RPT_PRINT_H__ */ diff --git a/tests/Makefile.am b/tests/Makefile.am new file mode 100644 index 0000000..3f5d414 --- /dev/null +++ b/tests/Makefile.am @@ -0,0 +1,10 @@ +LIBS = $(REPTOOL_LIBS) + +AM_CPPFLAGS = $(REPTOOL_CFLAGS) \ + -I$(top_builddir)/src + +libreptool = $(top_builddir)/src/libreptool.la + +noinst_PROGRAMS = rptprint + +rptprint_LDADD = $(libreptool) diff --git a/tests/city.png b/tests/city.png new file mode 100644 index 0000000..4a75a05 Binary files /dev/null and b/tests/city.png differ diff --git a/tests/rptprint.c b/tests/rptprint.c new file mode 100644 index 0000000..62bbcd7 --- /dev/null +++ b/tests/rptprint.c @@ -0,0 +1,35 @@ +/* + * Copyright (C) 2006 Andrea Zagli + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * 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 Library General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor Boston, MA 02110-1301, USA + */ + +#include + +int +main (int argc, char **argv) +{ + RptPrint *rptp; + + g_type_init (); + + rptp = rpt_print_new_from_file (argv[1], RPTP_OUTPUT_PDF, ""); + + if (rptp != NULL) + { + } + + return 0; +} diff --git a/tests/test.rptr b/tests/test.rptr new file mode 100644 index 0000000..fc5781f --- /dev/null +++ b/tests/test.rptr @@ -0,0 +1,14 @@ + + + + Text sample + + + + + + + Text sample on second page + + +