Commit 15b0f5ff authored by Dom Lachowicz's avatar Dom Lachowicz

restructure source code tree in order to be more managable, handle "wider" and...

restructure source code tree in order to be more managable, handle "wider" and "narrower" text specifications
parent a7eccead
2003-01-08 Dom Lachowicz <cinamod@hotmail.com>
* rsvg-file-util.c, rsvg-private.h, rsvg-shapes.c, rsvg-shapes.h, rsvg-styles.c, rsvg-styles.h, rsvg-text.c, rsvg-text.h : Separate functionality out into separate, managable files
2003-01-07 Dom Lachowicz <cinamod@hotmail.com>
* test-rsvg.c : Unref pixbuf, free memory leak. Thanks valgrind.
......
......@@ -23,6 +23,13 @@ librsvg_2_la_SOURCES = \
rsvg-paint-server.h \
rsvg-path.c \
rsvg-path.h \
rsvg-file-util.c \
rsvg-shapes.c \
rsvg-shapes.h \
rsvg-styles.c \
rsvg-styles.h \
rsvg-text.c \
rsvg-text.h \
rsvg.c
librsvg_2_la_LDFLAGS = -version-info @VERSION_INFO@
......
/* vim: set sw=4: -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
/*
rsvg-bpath-util.c: Data structure and convenience functions for creating bezier paths.
......@@ -35,165 +36,151 @@
RsvgBpathDef *
rsvg_bpath_def_new (void)
{
RsvgBpathDef *bpd;
bpd = g_new (RsvgBpathDef, 1);
bpd->n_bpath = 0;
bpd->n_bpath_max = 16;
bpd->moveto_idx = -1;
bpd->bpath = g_new (ArtBpath, bpd->n_bpath_max);
bpd->ref_count = 1;
return bpd;
RsvgBpathDef *bpd;
bpd = g_new (RsvgBpathDef, 1);
bpd->n_bpath = 0;
bpd->n_bpath_max = 16;
bpd->moveto_idx = -1;
bpd->bpath = g_new (ArtBpath, bpd->n_bpath_max);
return bpd;
}
RsvgBpathDef *
rsvg_bpath_def_new_from (ArtBpath *path)
{
RsvgBpathDef *bpd;
int i;
g_return_val_if_fail (path != NULL, NULL);
for (i = 0; path[i].code != ART_END; i++)
;
if (i <= 0)
return rsvg_bpath_def_new ();
bpd = g_new (RsvgBpathDef, 1);
bpd->n_bpath = i;
bpd->n_bpath_max = i;
bpd->moveto_idx = -1;
bpd->ref_count = 1;
bpd->bpath = g_new (ArtBpath, i);
memcpy (bpd->bpath, path, i * sizeof (ArtBpath));
return bpd;
RsvgBpathDef *bpd;
int i;
g_return_val_if_fail (path != NULL, NULL);
for (i = 0; path[i].code != ART_END; i++)
;
if (i <= 0)
return rsvg_bpath_def_new ();
bpd = g_new (RsvgBpathDef, 1);
bpd->n_bpath = i;
bpd->n_bpath_max = i;
bpd->moveto_idx = -1;
bpd->bpath = g_new (ArtBpath, i);
memcpy (bpd->bpath, path, i * sizeof (ArtBpath));
return bpd;
}
RsvgBpathDef *
rsvg_bpath_def_ref (RsvgBpathDef *bpd)
{
g_return_val_if_fail (bpd != NULL, NULL);
bpd->ref_count += 1;
return bpd;
}
void
rsvg_bpath_def_free (RsvgBpathDef *bpd)
{
g_return_if_fail (bpd != NULL);
bpd->ref_count -= 1;
if (bpd->ref_count == 0)
{
g_free (bpd->bpath);
g_free (bpd);
}
g_return_if_fail (bpd != NULL);
g_free (bpd->bpath);
g_free (bpd);
}
void
rsvg_bpath_def_moveto (RsvgBpathDef *bpd, double x, double y)
{
ArtBpath *bpath;
int n_bpath;
g_return_if_fail (bpd != NULL);
n_bpath = bpd->n_bpath++;
if (n_bpath == bpd->n_bpath_max)
bpd->bpath = g_realloc (bpd->bpath,
(bpd->n_bpath_max <<= 1) * sizeof (ArtBpath));
bpath = bpd->bpath;
bpath[n_bpath].code = ART_MOVETO_OPEN;
bpath[n_bpath].x3 = x;
bpath[n_bpath].y3 = y;
bpd->moveto_idx = n_bpath;
ArtBpath *bpath;
int n_bpath;
g_return_if_fail (bpd != NULL);
n_bpath = bpd->n_bpath++;
if (n_bpath == bpd->n_bpath_max)
bpd->bpath = g_realloc (bpd->bpath,
(bpd->n_bpath_max <<= 1) * sizeof (ArtBpath));
bpath = bpd->bpath;
bpath[n_bpath].code = ART_MOVETO_OPEN;
bpath[n_bpath].x3 = x;
bpath[n_bpath].y3 = y;
bpd->moveto_idx = n_bpath;
}
void
rsvg_bpath_def_lineto (RsvgBpathDef *bpd, double x, double y)
{
ArtBpath *bpath;
int n_bpath;
g_return_if_fail (bpd != NULL);
g_return_if_fail (bpd->moveto_idx >= 0);
n_bpath = bpd->n_bpath++;
if (n_bpath == bpd->n_bpath_max)
bpd->bpath = g_realloc (bpd->bpath,
(bpd->n_bpath_max <<= 1) * sizeof (ArtBpath));
bpath = bpd->bpath;
bpath[n_bpath].code = ART_LINETO;
bpath[n_bpath].x3 = x;
bpath[n_bpath].y3 = y;
ArtBpath *bpath;
int n_bpath;
g_return_if_fail (bpd != NULL);
g_return_if_fail (bpd->moveto_idx >= 0);
n_bpath = bpd->n_bpath++;
if (n_bpath == bpd->n_bpath_max)
bpd->bpath = g_realloc (bpd->bpath,
(bpd->n_bpath_max <<= 1) * sizeof (ArtBpath));
bpath = bpd->bpath;
bpath[n_bpath].code = ART_LINETO;
bpath[n_bpath].x3 = x;
bpath[n_bpath].y3 = y;
}
void
rsvg_bpath_def_curveto (RsvgBpathDef *bpd, double x1, double y1, double x2, double y2, double x3, double y3)
{
ArtBpath *bpath;
int n_bpath;
g_return_if_fail (bpd != NULL);
g_return_if_fail (bpd->moveto_idx >= 0);
n_bpath = bpd->n_bpath++;
if (n_bpath == bpd->n_bpath_max)
bpd->bpath = g_realloc (bpd->bpath,
(bpd->n_bpath_max <<= 1) * sizeof (ArtBpath));
bpath = bpd->bpath;
bpath[n_bpath].code = ART_CURVETO;
bpath[n_bpath].x1 = x1;
bpath[n_bpath].y1 = y1;
bpath[n_bpath].x2 = x2;
bpath[n_bpath].y2 = y2;
bpath[n_bpath].x3 = x3;
bpath[n_bpath].y3 = y3;
ArtBpath *bpath;
int n_bpath;
g_return_if_fail (bpd != NULL);
g_return_if_fail (bpd->moveto_idx >= 0);
n_bpath = bpd->n_bpath++;
if (n_bpath == bpd->n_bpath_max)
bpd->bpath = g_realloc (bpd->bpath,
(bpd->n_bpath_max <<= 1) * sizeof (ArtBpath));
bpath = bpd->bpath;
bpath[n_bpath].code = ART_CURVETO;
bpath[n_bpath].x1 = x1;
bpath[n_bpath].y1 = y1;
bpath[n_bpath].x2 = x2;
bpath[n_bpath].y2 = y2;
bpath[n_bpath].x3 = x3;
bpath[n_bpath].y3 = y3;
}
void
rsvg_bpath_def_closepath (RsvgBpathDef *bpd)
{
ArtBpath *bpath;
int n_bpath;
g_return_if_fail (bpd != NULL);
g_return_if_fail (bpd->moveto_idx >= 0);
g_return_if_fail (bpd->n_bpath > 0);
bpath = bpd->bpath;
n_bpath = bpd->n_bpath;
/* Add closing vector if we need it. */
if (bpath[n_bpath - 1].x3 != bpath[bpd->moveto_idx].x3 ||
bpath[n_bpath - 1].y3 != bpath[bpd->moveto_idx].y3)
{
rsvg_bpath_def_lineto (bpd, bpath[bpd->moveto_idx].x3,
bpath[bpd->moveto_idx].y3);
bpath = bpd->bpath;
}
bpath[bpd->moveto_idx].code = ART_MOVETO;
bpd->moveto_idx = -1;
ArtBpath *bpath;
int n_bpath;
g_return_if_fail (bpd != NULL);
g_return_if_fail (bpd->moveto_idx >= 0);
g_return_if_fail (bpd->n_bpath > 0);
bpath = bpd->bpath;
n_bpath = bpd->n_bpath;
/* Add closing vector if we need it. */
if (bpath[n_bpath - 1].x3 != bpath[bpd->moveto_idx].x3 ||
bpath[n_bpath - 1].y3 != bpath[bpd->moveto_idx].y3)
{
rsvg_bpath_def_lineto (bpd, bpath[bpd->moveto_idx].x3,
bpath[bpd->moveto_idx].y3);
bpath = bpd->bpath;
}
bpath[bpd->moveto_idx].code = ART_MOVETO;
bpd->moveto_idx = -1;
}
void
rsvg_bpath_def_art_finish (RsvgBpathDef *bpd)
{
int n_bpath;
g_return_if_fail (bpd != NULL);
n_bpath = bpd->n_bpath++;
if (n_bpath == bpd->n_bpath_max)
bpd->bpath = g_realloc (bpd->bpath,
(bpd->n_bpath_max <<= 1) * sizeof (ArtBpath));
bpd->bpath[n_bpath].code = ART_END;
int n_bpath;
g_return_if_fail (bpd != NULL);
n_bpath = bpd->n_bpath++;
if (n_bpath == bpd->n_bpath_max)
bpd->bpath = g_realloc (bpd->bpath,
(bpd->n_bpath_max <<= 1) * sizeof (ArtBpath));
bpd->bpath[n_bpath].code = ART_END;
}
/*
rsvg-bpath-util.h: Data structure and convenience functions for creating bezier paths.
Copyright (C) 2000 Eazel, Inc.
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU Library 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 Library 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.
Author: Raph Levien <raph@artofcode.com>
*/
/* vim: set sw=4: -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
#ifndef RSVG_BPATH_UTIL_H
#define RSVG_BPATH_UTIL_H
#include <glib/gtypes.h>
#include <libart_lgpl/art_bpath.h>
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
G_BEGIN_DECLS
typedef struct _RsvgBpathDef RsvgBpathDef;
struct _RsvgBpathDef {
int ref_count;
ArtBpath *bpath;
int n_bpath;
int n_bpath_max;
int moveto_idx;
};
RsvgBpathDef *rsvg_bpath_def_new (void);
RsvgBpathDef *rsvg_bpath_def_new_from (ArtBpath *bpath);
RsvgBpathDef *rsvg_bpath_def_ref (RsvgBpathDef *bpd);
#define rsvg_bpath_def_unref rsvg_bpath_def_free
void rsvg_bpath_def_free (RsvgBpathDef *bpd);
void rsvg_bpath_def_moveto (RsvgBpathDef *bpd,
double x, double y);
double x, double y);
void rsvg_bpath_def_lineto (RsvgBpathDef *bpd,
double x, double y);
double x, double y);
void rsvg_bpath_def_curveto (RsvgBpathDef *bpd,
double x1, double y1,
double x2, double y2,
double x3, double y3);
double x1, double y1,
double x2, double y2,
double x3, double y3);
void rsvg_bpath_def_closepath (RsvgBpathDef *bpd);
void rsvg_bpath_def_art_finish (RsvgBpathDef *bpd);
#ifdef __cplusplus
}
#endif /* __cplusplus */
G_END_DECLS
#endif
This diff is collapsed.
/* vim: set sw=4: -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
#ifndef RSVG_CSS_H
#define RSVG_CSS_H
#include <glib/gtypes.h>
#include <pango/pangoft2.h>
G_BEGIN_DECLS
double
rsvg_css_parse_length (const char *str, gdouble pixels_per_inch,
gint *percent, gint *em, gint *ex);
......@@ -45,3 +52,7 @@ rsvg_css_parse_font_stretch (const char * str, PangoStretch inherit);
const char *
rsvg_css_parse_font_family (const char * str, const char * inherit);
G_END_DECLS
#endif /* RSVG_CSS_H */
/* vim: set sw=4: -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
/*
rsvg-defs.c: Manage SVG defs and references.
......@@ -29,43 +30,43 @@
#include <glib/gstrfuncs.h>
struct _RsvgDefs {
GHashTable *hash;
GHashTable *hash;
};
RsvgDefs *
rsvg_defs_new (void)
{
RsvgDefs *result = g_new (RsvgDefs, 1);
result->hash = g_hash_table_new (g_str_hash, g_str_equal);
return result;
RsvgDefs *result = g_new (RsvgDefs, 1);
result->hash = g_hash_table_new (g_str_hash, g_str_equal);
return result;
}
RsvgDefVal *
rsvg_defs_lookup (const RsvgDefs *defs, const char *name)
{
return (RsvgDefVal *)g_hash_table_lookup (defs->hash, name);
return (RsvgDefVal *)g_hash_table_lookup (defs->hash, name);
}
void
rsvg_defs_set (RsvgDefs *defs, const char *name, RsvgDefVal *val)
{
g_hash_table_insert (defs->hash, g_strdup (name), val);
g_hash_table_insert (defs->hash, g_strdup (name), val);
}
static void
rsvg_defs_free_each (gpointer key, gpointer value, gpointer user_data)
{
RsvgDefVal *def_val = (RsvgDefVal *)value;
g_free (key);
def_val->free (def_val);
RsvgDefVal *def_val = (RsvgDefVal *)value;
g_free (key);
def_val->free (def_val);
}
void
rsvg_defs_free (RsvgDefs *defs)
{
g_hash_table_foreach (defs->hash, rsvg_defs_free_each, NULL);
g_hash_table_destroy (defs->hash);
g_free (defs);
g_hash_table_foreach (defs->hash, rsvg_defs_free_each, NULL);
g_hash_table_destroy (defs->hash);
g_free (defs);
}
/* vim: set sw=4: -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
#ifndef RSVG_DEFS_H
#define RSVG_DEFS_H
/* A module for handling SVG defs */
#include <glib/gtypes.h>
G_BEGIN_DECLS
typedef struct _RsvgDefs RsvgDefs;
typedef struct _RsvgDefVal RsvgDefVal;
typedef enum {
/* todo: general question: should this be high level, ie a generic
paint server, coupled with a paint server interface; or low level,
ie specific definable things? For now, we're going low level,
but it's not clear that's the best way to go. */
RSVG_DEF_LINGRAD,
RSVG_DEF_RADGRAD,
RSVG_DEF_PATTERN
/* todo: general question: should this be high level, ie a generic
paint server, coupled with a paint server interface; or low level,
ie specific definable things? For now, we're going low level,
but it's not clear that's the best way to go. */
RSVG_DEF_LINGRAD,
RSVG_DEF_RADGRAD,
RSVG_DEF_PATTERN
} RsvgDefType;
struct _RsvgDefVal {
RsvgDefType type;
void (*free) (RsvgDefVal *self);
RsvgDefType type;
void (*free) (RsvgDefVal *self);
};
RsvgDefs *
......@@ -29,3 +38,7 @@ rsvg_defs_set (RsvgDefs *defs, const char *name, RsvgDefVal *val);
void
rsvg_defs_free (RsvgDefs *defs);
G_END_DECLS
#endif
/* vim: set sw=4: -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
/*
rsvg-file-util.c: SAX-based renderer for SVG files into a GdkPixbuf.
Copyright (C) 2000 Eazel, Inc.
Copyright (C) 2002 Dom Lachowicz <cinamod@hotmail.com>
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU Library 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 Library 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.
Author: Raph Levien <raph@artofcode.com>
*/
#include "config.h"
#include "rsvg.h"
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#if ENABLE_GNOME_VFS
#include <libgnomevfs/gnome-vfs.h>
#endif
#define SVG_BUFFER_SIZE (1024 * 8)
typedef enum {
RSVG_SIZE_ZOOM,
RSVG_SIZE_WH,
RSVG_SIZE_WH_MAX,
RSVG_SIZE_ZOOM_MAX
} RsvgSizeType;
struct RsvgSizeCallbackData
{
RsvgSizeType type;
double x_zoom;
double y_zoom;
gint width;
gint height;
};
static void
rsvg_size_callback (int *width,
int *height,
gpointer data)
{
struct RsvgSizeCallbackData *real_data = (struct RsvgSizeCallbackData *) data;
double zoomx, zoomy, zoom;
switch (real_data->type) {
case RSVG_SIZE_ZOOM:
if (*width < 0 || *height < 0)
return;
*width = floor (real_data->x_zoom * *width + 0.5);
*height = floor (real_data->y_zoom * *height + 0.5);
return;
case RSVG_SIZE_ZOOM_MAX:
if (*width < 0 || *height < 0)
return;
*width = floor (real_data->x_zoom * *width + 0.5);
*height = floor (real_data->y_zoom * *height + 0.5);
if (*width > real_data->width || *height > real_data->height)
{
zoomx = (double) real_data->width / *width;
zoomy = (double) real_data->height / *height;
zoom = MIN (zoomx, zoomy);
*width = floor (zoom * *width + 0.5);
*height = floor (zoom * *height + 0.5);
}
return;
case RSVG_SIZE_WH_MAX:
if (*width < 0 || *height < 0)
return;
zoomx = (double) real_data->width / *width;
zoomy = (double) real_data->height / *height;
zoom = MIN (zoomx, zoomy);
*width = floor (zoom * *width + 0.5);
*height = floor (zoom * *height + 0.5);
return;
case RSVG_SIZE_WH:
if (real_data->width != -1)
*width = real_data->width;
if (real_data->height != -1)
*height = real_data->height;
return;
}
g_assert_not_reached ();
}
static GdkPixbuf *
rsvg_pixbuf_from_file_with_size_data (const gchar * file_name,
struct RsvgSizeCallbackData * data,
GError ** error)
{
char chars[SVG_BUFFER_SIZE];
gint result;
GdkPixbuf *retval;
RsvgHandle *handle;
#if ENABLE_GNOME_VFS
GnomeVFSHandle * f = NULL;
if (GNOME_VFS_OK != gnome_vfs_open (&handle, file_name, GNOME_VFS_OPEN_READ))
{
/* FIXME: Set up error. */
return NULL;
}
#else
FILE *f = fopen (file_name, "r");
if (!f)
{
/* FIXME: Set up error. */
return NULL;
}
#endif
handle = rsvg_handle_new ();
rsvg_handle_set_size_callback (handle, rsvg_size_callback, data, NULL);
#if ENABLE_GNOME_VFS
while (GNOME_VFS_OK == gnome_vfs_read (f,chars, SVG_BUFFER_SIZE, &result))
rsvg_handle_write (handle, chars, result, error);
#else
while ((result = fread (chars, 1, SVG_BUFFER_SIZE, f)) > 0)
rsvg_handle_write (handle, chars, result, error);
#endif
rsvg_handle_close (handle, error);
retval = rsvg_handle_get_pixbuf (handle);
#if ENABLE_GNOME_VFS
gnome_vfs_close (f);
#else
fclose (f);
#endif
rsvg_handle_free (handle);
return retval;
}
/**
* rsvg_pixbuf_from_file:
* @file_name: A file name
* @error: return location for errors
*
* Loads a new #GdkPixbuf from @file_name and returns it. The caller must
* assume the reference to the reurned pixbuf. If an error occurred, @error is
* set and %NULL is returned.
*
* Return value: A newly allocated #GdkPixbuf, or %NULL
**/
GdkPixbuf *
rsvg_pixbuf_from_file (const gchar *file_name,
GError **error)
{
return rsvg_pixbuf_from_file_at_size (file_name, -1, -1, error);
}
/**
* rsvg_pixbuf_from_file_at_zoom:
* @file_name: A file name
* @x_zoom: The horizontal zoom factor
* @y_zoom: The vertical zoom factor
* @error: return location for errors
*
* Loads a new #GdkPixbuf from @file_name and returns it. This pixbuf is scaled
* from the size indicated by the file by a factor of @x_zoom and @y_zoom. The
* caller must assume the reference to the returned pixbuf. If an error
* occurred, @error is set and %NULL is returned.
*
* Return value: A newly allocated #GdkPixbuf, or %NULL
**/
GdkPixbuf *
rsvg_pixbuf_from_file_at_zoom (const gchar *file_name,
double x_zoom,
double y_zoom,
GError **error)
{
struct RsvgSizeCallbackData data;
g_return_val_if_fail (file_name != NULL, NULL);
g_return_val_if_fail (x_zoom > 0.0 && y_zoom > 0.0, NULL);
data.type = RSVG_SIZE_ZOOM;
data.x_zoom = x_zoom;
data.y_zoom = y_zoom;
return rsvg_pixbuf_from_file_with_size_data (file_name, &data, error);
}
/**
* rsvg_pixbuf_from_file_at_zoom_with_max:
* @file_name: A file name
* @x_zoom: The horizontal zoom factor
* @y_zoom: The vertical zoom factor
* @max_width: The requested max width
* @max_height: The requested max heigh
* @error: return location for errors
*
* Loads a new #GdkPixbuf from @file_name and returns it. This pixbuf is scaled
* from the size indicated by the file by a factor of @x_zoom and @y_zoom. If the
* resulting pixbuf would be larger than max_width/max_heigh it is uniformly scaled
* down to fit in that rectangle. The caller must assume the reference to the
* returned pixbuf. If an error occurred, @error is set and %NULL is returned.