summaryrefslogtreecommitdiff
path: root/librsvg/rsvg-paint-server.c
diff options
context:
space:
mode:
Diffstat (limited to 'librsvg/rsvg-paint-server.c')
-rw-r--r--librsvg/rsvg-paint-server.c345
1 files changed, 0 insertions, 345 deletions
diff --git a/librsvg/rsvg-paint-server.c b/librsvg/rsvg-paint-server.c
deleted file mode 100644
index 53e34e022..000000000
--- a/librsvg/rsvg-paint-server.c
+++ /dev/null
@@ -1,345 +0,0 @@
-/*
- rsvg-paint-server.c: Implement the SVG paint server abstraction.
-
- Copyright (C) 2000 Eazel, Inc.
-
- 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.
-
- Author: Raph Levien <raph@artofcode.com>
-*/
-
-#include <string.h>
-#include <ctype.h>
-
-#include <glib.h>
-
-#include <libart_lgpl/art_misc.h>
-#include <libart_lgpl/art_alphagamma.h>
-#include <libart_lgpl/art_filterlevel.h>
-#include <libart_lgpl/art_affine.h>
-#include "art_render.h"
-#include "art_render_gradient.h"
-
-#include "rsvg-css.h"
-#include "rsvg-defs.h"
-#include "rsvg-paint-server.h"
-
-typedef struct _RsvgPaintServerSolid RsvgPaintServerSolid;
-typedef struct _RsvgPaintServerLinGrad RsvgPaintServerLinGrad;
-typedef struct _RsvgPaintServerRadGrad RsvgPaintServerRadGrad;
-
-struct _RsvgPaintServer {
- int refcnt;
- void (*free) (RsvgPaintServer *self);
- void (*render) (RsvgPaintServer *self, ArtRender *ar, const RsvgPSCtx *ctx);
-};
-
-struct _RsvgPaintServerSolid {
- RsvgPaintServer super;
- guint32 rgb;
-};
-
-struct _RsvgPaintServerLinGrad {
- RsvgPaintServer super;
- RsvgLinearGradient *gradient;
- ArtGradientLinear *agl;
-};
-
-struct _RsvgPaintServerRadGrad {
- RsvgPaintServer super;
- RsvgRadialGradient *gradient;
- ArtGradientRadial *agr;
-};
-
-static void
-rsvg_paint_server_solid_free (RsvgPaintServer *self)
-{
- g_free (self);
-}
-
-static void
-rsvg_paint_server_solid_render (RsvgPaintServer *self, ArtRender *ar,
- const RsvgPSCtx *ctx)
-{
- RsvgPaintServerSolid *z = (RsvgPaintServerSolid *)self;
- guint32 rgb = z->rgb;
- ArtPixMaxDepth color[3];
-
- color[0] = ART_PIX_MAX_FROM_8 (rgb >> 16);
- color[1] = ART_PIX_MAX_FROM_8 ((rgb >> 8) & 0xff);
- color[2] = ART_PIX_MAX_FROM_8 (rgb & 0xff);
-
- art_render_image_solid (ar, color);
-}
-
-static RsvgPaintServer *
-rsvg_paint_server_solid (guint32 rgb)
-{
- RsvgPaintServerSolid *result = g_new (RsvgPaintServerSolid, 1);
-
- result->super.refcnt = 1;
- result->super.free = rsvg_paint_server_solid_free;
- result->super.render = rsvg_paint_server_solid_render;
-
- result->rgb = rgb;
-
- return &result->super;
-}
-
-static void
-rsvg_paint_server_lin_grad_free (RsvgPaintServer *self)
-{
- RsvgPaintServerLinGrad *z = (RsvgPaintServerLinGrad *)self;
-
- g_free (z->agl->stops);
- g_free (z->agl);
- g_free (self);
-}
-
-static ArtGradientStop *
-rsvg_paint_art_stops_from_rsvg (RsvgGradientStops *rstops)
-{
- ArtGradientStop *stops;
- int n_stop = rstops->n_stop;
- int i;
-
- stops = g_new (ArtGradientStop, n_stop);
- for (i = 0; i < n_stop; i++)
- {
- guint32 rgba;
- guint32 r, g, b, a;
-
- stops[i].offset = rstops->stop[i].offset;
- rgba = rstops->stop[i].rgba;
- /* convert from separated to premultiplied alpha */
- a = rgba & 0xff;
- r = (rgba >> 24) * a + 0x80;
- r = (r + (r >> 8)) >> 8;
- g = ((rgba >> 16) & 0xff) * a + 0x80;
- g = (g + (g >> 8)) >> 8;
- b = ((rgba >> 8) & 0xff) * a + 0x80;
- b = (b + (b >> 8)) >> 8;
- stops[i].color[0] = ART_PIX_MAX_FROM_8(r);
- stops[i].color[1] = ART_PIX_MAX_FROM_8(g);
- stops[i].color[2] = ART_PIX_MAX_FROM_8(b);
- stops[i].color[3] = ART_PIX_MAX_FROM_8(a);
- }
- return stops;
-}
-
-static void
-rsvg_paint_server_lin_grad_render (RsvgPaintServer *self, ArtRender *ar,
- const RsvgPSCtx *ctx)
-{
- RsvgPaintServerLinGrad *z = (RsvgPaintServerLinGrad *)self;
- RsvgLinearGradient *rlg = z->gradient;
- ArtGradientLinear *agl;
- double x1, y1, x2, y2;
- double dx, dy, scale;
-
- agl = z->agl;
- if (agl == NULL)
- {
- agl = g_new (ArtGradientLinear, 1);
- agl->n_stops = rlg->stops->n_stop;
- agl->stops = rsvg_paint_art_stops_from_rsvg (rlg->stops);
- z->agl = agl;
- }
-
- /* compute [xy][12] in pixel space */
- /* todo: this code implicitly implements gradientUnits = userSpace */
- x1 = rlg->x1 * rlg->affine[0] + rlg->y1 * rlg->affine[2] + rlg->affine[4];
- y1 = rlg->x1 * rlg->affine[1] + rlg->y1 * rlg->affine[3] + rlg->affine[5];
- x2 = rlg->x2 * rlg->affine[0] + rlg->y2 * rlg->affine[2] + rlg->affine[4];
- y2 = rlg->x2 * rlg->affine[1] + rlg->y2 * rlg->affine[3] + rlg->affine[5];
-
- /* solve a, b, c so ax1 + by1 + c = 0 and ax2 + by2 + c = 1, maximum
- gradient is in x1,y1 to x2,y2 dir */
- dx = x2 - x1;
- dy = y2 - y1;
- scale = 1.0 / (dx * dx + dy * dy);
- agl->a = dx * scale;
- agl->b = dy * scale;
- agl->c = -(x1 * agl->a + y1 * agl->b);
-
- agl->spread = rlg->spread;
- art_render_gradient_linear (ar, agl, ART_FILTER_NEAREST);
-}
-
-static RsvgPaintServer *
-rsvg_paint_server_lin_grad (RsvgLinearGradient *gradient)
-{
- RsvgPaintServerLinGrad *result = g_new (RsvgPaintServerLinGrad, 1);
-
- result->super.refcnt = 1;
- result->super.free = rsvg_paint_server_lin_grad_free;
- result->super.render = rsvg_paint_server_lin_grad_render;
-
- result->gradient = gradient;
- result->agl = NULL;
-
- return &result->super;
-}
-
-static void
-rsvg_paint_server_rad_grad_free (RsvgPaintServer *self)
-{
- RsvgPaintServerRadGrad *z = (RsvgPaintServerRadGrad *)self;
-
- g_free (z->agr->stops);
- g_free (z->agr);
- g_free (self);
-}
-
-static void
-rsvg_paint_server_rad_grad_render (RsvgPaintServer *self, ArtRender *ar,
- const RsvgPSCtx *ctx)
-{
- RsvgPaintServerRadGrad *z = (RsvgPaintServerRadGrad *)self;
- RsvgRadialGradient *rrg = z->gradient;
- ArtGradientRadial *agr;
- double aff1[6], aff2[6];
-
- agr = z->agr;
- if (agr == NULL)
- {
- agr = g_new (ArtGradientRadial, 1);
- agr->n_stops = rrg->stops->n_stop;
- agr->stops = rsvg_paint_art_stops_from_rsvg (rrg->stops);
- z->agr = agr;
- }
-
- /* todo: this code implicitly implements gradientUnits = userSpace */
- art_affine_scale (aff1, rrg->r, rrg->r);
- art_affine_translate (aff2, rrg->cx, rrg->cy);
- art_affine_multiply (aff1, aff1, aff2);
- art_affine_multiply (aff1, aff1, rrg->affine);
- art_affine_invert (agr->affine, aff1);
-
- agr->fx = (rrg->fx - rrg->cx) / rrg->r;
- agr->fy = (rrg->fy - rrg->cy) / rrg->r;
-
- art_render_gradient_radial (ar, agr, ART_FILTER_NEAREST);
-}
-
-static RsvgPaintServer *
-rsvg_paint_server_rad_grad (RsvgRadialGradient *gradient)
-{
- RsvgPaintServerRadGrad *result = g_new (RsvgPaintServerRadGrad, 1);
-
- result->super.refcnt = 1;
- result->super.free = rsvg_paint_server_rad_grad_free;
- result->super.render = rsvg_paint_server_rad_grad_render;
-
- result->gradient = gradient;
- result->agr = NULL;
-
- return &result->super;
-}
-
-/**
- * rsvg_paint_server_parse: Parse an SVG paint specification.
- * @defs: Defs for looking up gradients.
- * @str: The SVG paint specification string to parse.
- *
- * Parses the paint specification @str, creating a new paint server
- * object.
- *
- * Return value: The newly created paint server, or NULL on error.
- **/
-RsvgPaintServer *
-rsvg_paint_server_parse (const RsvgDefs *defs, const char *str)
-{
- guint32 rgb;
-
- if (!strcmp (str, "none"))
- return NULL;
- if (!strncmp (str, "url(", 4))
- {
- const char *p = str + 4;
- int ix;
- char *name;
- RsvgDefVal *val;
-
- while (isspace (*p)) p++;
- if (*p != '#')
- return NULL;
- p++;
- for (ix = 0; p[ix]; ix++)
- if (p[ix] == ')') break;
- if (p[ix] != ')')
- return NULL;
- name = g_strndup (p, ix);
- val = rsvg_defs_lookup (defs, name);
- g_free (name);
- if (val == NULL)
- return NULL;
- switch (val->type)
- {
- case RSVG_DEF_LINGRAD:
- return rsvg_paint_server_lin_grad ((RsvgLinearGradient *)val);
- case RSVG_DEF_RADGRAD:
- return rsvg_paint_server_rad_grad ((RsvgRadialGradient *)val);
- default:
- return NULL;
- }
- }
- else
- {
- rgb = rsvg_css_parse_color (str);
- return rsvg_paint_server_solid (rgb);
- }
-}
-
-/**
- * rsvg_render_paint_server: Render paint server as image source for libart.
- * @ar: Libart render object.
- * @ps: Paint server object.
- *
- * Hooks up @ps as an image source for a libart rendering operation.
- **/
-void
-rsvg_render_paint_server (ArtRender *ar, RsvgPaintServer *ps,
- const RsvgPSCtx *ctx)
-{
- if (ps != NULL)
- ps->render (ps, ar, ctx);
-}
-
-/**
- * rsvg_paint_server_ref: Reference a paint server object.
- * @ps: The paint server object to reference.
- **/
-void
-rsvg_paint_server_ref (RsvgPaintServer *ps)
-{
- if (ps == NULL)
- return;
- ps->refcnt++;
-}
-
-/**
- * rsvg_paint_server_unref: Unreference a paint server object.
- * @ps: The paint server object to unreference.
- **/
-void
-rsvg_paint_server_unref (RsvgPaintServer *ps)
-{
- if (ps == NULL)
- return;
- if (--ps->refcnt == 0)
- ps->free (ps);
-}