aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--libart_lgpl/Makefile.am18
-rw-r--r--libart_lgpl/art_affine.c109
-rw-r--r--libart_lgpl/art_affine.h24
-rw-r--r--libart_lgpl/art_alphagamma.c85
-rw-r--r--libart_lgpl/art_alphagamma.h6
-rw-r--r--libart_lgpl/art_pixbuf.c172
-rw-r--r--libart_lgpl/art_pixbuf.h25
-rw-r--r--libart_lgpl/art_rect.c38
-rw-r--r--libart_lgpl/art_rect.h8
-rw-r--r--libart_lgpl/art_render.c552
-rw-r--r--libart_lgpl/art_render.h21
-rw-r--r--libart_lgpl/art_render_gradient.c716
-rw-r--r--libart_lgpl/art_render_gradient.h81
-rw-r--r--libart_lgpl/art_render_mask.c168
-rw-r--r--libart_lgpl/art_render_mask.h43
-rw-r--r--libart_lgpl/art_render_svp.c421
-rw-r--r--libart_lgpl/art_render_svp.h42
-rw-r--r--libart_lgpl/art_rgb_a_affine.c149
-rw-r--r--libart_lgpl/art_rgb_a_affine.h47
-rw-r--r--libart_lgpl/art_rgb_bitmap_affine.c198
-rw-r--r--libart_lgpl/art_rgb_bitmap_affine.h47
-rw-r--r--libart_lgpl/art_rgb_pixbuf_affine.c104
-rw-r--r--libart_lgpl/art_rgb_pixbuf_affine.h46
-rw-r--r--libart_lgpl/art_rgba.c258
-rw-r--r--libart_lgpl/art_rgba.h45
-rw-r--r--libart_lgpl/art_svp_ops.c155
-rw-r--r--libart_lgpl/art_svp_ops.h3
-rw-r--r--libart_lgpl/art_svp_wind.c1545
-rw-r--r--libart_lgpl/art_svp_wind.h7
-rw-r--r--libart_lgpl/art_uta_ops.c112
-rw-r--r--libart_lgpl/art_uta_ops.h38
-rw-r--r--libart_lgpl/art_vpath.c126
-rw-r--r--libart_lgpl/art_vpath.h9
-rw-r--r--libart_lgpl/libart.h1
-rw-r--r--libgnomecanvas/gnome-canvas-text.c2
-rw-r--r--libgnomecanvas/gnome-canvas.c1
36 files changed, 0 insertions, 5422 deletions
diff --git a/libart_lgpl/Makefile.am b/libart_lgpl/Makefile.am
index bc45e33137..8f71243893 100644
--- a/libart_lgpl/Makefile.am
+++ b/libart_lgpl/Makefile.am
@@ -21,18 +21,11 @@ libart_lgplinclude_HEADERS = \
art_rect_svp.h \
art_rect_uta.h \
art_render.h \
- art_render_gradient.h \
- art_render_mask.h \
- art_render_svp.h \
art_rgb.h \
- art_rgb_a_affine.h \
art_rgb_affine.h \
art_rgb_affine_private.h \
- art_rgb_bitmap_affine.h \
- art_rgb_pixbuf_affine.h \
art_rgb_rgba_affine.h \
art_rgb_svp.h \
- art_rgba.h \
art_svp.h \
art_svp_intersect.h \
art_svp_ops.h \
@@ -42,7 +35,6 @@ libart_lgplinclude_HEADERS = \
art_svp_vpath_stroke.h \
art_svp_wind.h \
art_uta.h \
- art_uta_ops.h \
art_uta_rect.h \
art_uta_svp.h \
art_uta_vpath.h \
@@ -54,7 +46,6 @@ libart_lgplinclude_HEADERS = \
libart_lgpl_la_SOURCES = \
art_affine.c \
- art_alphagamma.c \
art_bpath.c \
art_gray_svp.c \
art_misc.c \
@@ -63,18 +54,11 @@ libart_lgpl_la_SOURCES = \
art_rect_svp.c \
art_rect_uta.c \
art_render.c \
- art_render_gradient.c \
- art_render_mask.c \
- art_render_svp.c \
art_rgb.c \
- art_rgb_a_affine.c \
art_rgb_affine.c \
art_rgb_affine_private.c \
- art_rgb_bitmap_affine.c \
- art_rgb_pixbuf_affine.c \
art_rgb_rgba_affine.c \
art_rgb_svp.c \
- art_rgba.c \
art_svp.c \
art_svp_intersect.c \
art_svp_ops.c \
@@ -82,9 +66,7 @@ libart_lgpl_la_SOURCES = \
art_svp_render_aa.c \
art_svp_vpath.c \
art_svp_vpath_stroke.c \
- art_svp_wind.c \
art_uta.c \
- art_uta_ops.c \
art_uta_rect.c \
art_uta_svp.c \
art_uta_vpath.c \
diff --git a/libart_lgpl/art_affine.c b/libart_lgpl/art_affine.c
index 9f332a3520..96007d09c9 100644
--- a/libart_lgpl/art_affine.c
+++ b/libart_lgpl/art_affine.c
@@ -77,29 +77,6 @@ art_affine_invert (double dst[6], const double src[6])
dst[5] = -src[4] * dst[1] - src[5] * dst[3];
}
-/**
- * art_affine_flip: Flip an affine transformation horizontally and/or vertically.
- * @dst_affine: Where the resulting affine is stored.
- * @src_affine: The original affine transformation.
- * @horiz: Whether or not to flip horizontally.
- * @vert: Whether or not to flip horizontally.
- *
- * Flips the affine transform. FALSE for both @horiz and @vert implements
- * a simple copy operation. TRUE for both @horiz and @vert is a
- * 180 degree rotation. It is ok for @src_affine and @dst_affine to
- * be equal pointers.
- **/
-void
-art_affine_flip (double dst_affine[6], const double src_affine[6], int horz, int vert)
-{
- dst_affine[0] = horz ? - src_affine[0] : src_affine[0];
- dst_affine[1] = horz ? - src_affine[1] : src_affine[1];
- dst_affine[2] = vert ? - src_affine[2] : src_affine[2];
- dst_affine[3] = vert ? - src_affine[3] : src_affine[3];
- dst_affine[4] = horz ? - src_affine[4] : src_affine[4];
- dst_affine[5] = vert ? - src_affine[5] : src_affine[5];
-}
-
#define EPSILON 1e-6
/* It's ridiculous I have to write this myself. This is hardcoded to
@@ -335,55 +312,6 @@ art_affine_scale (double dst[6], double sx, double sy)
}
/**
- * art_affine_rotate: Set up a rotation affine transform.
- * @dst: Where to store the resulting affine transform.
- * @theta: Rotation angle in degrees.
- *
- * Sets up a rotation matrix. In the standard libart coordinate
- * system, in which increasing y moves downward, this is a
- * counterclockwise rotation. In the standard PostScript coordinate
- * system, which is reversed in the y direction, it is a clockwise
- * rotation.
- **/
-void
-art_affine_rotate (double dst[6], double theta)
-{
- double s, c;
-
- s = sin (theta * M_PI / 180.0);
- c = cos (theta * M_PI / 180.0);
- dst[0] = c;
- dst[1] = s;
- dst[2] = -s;
- dst[3] = c;
- dst[4] = 0;
- dst[5] = 0;
-}
-
-/**
- * art_affine_shear: Set up a shearing matrix.
- * @dst: Where to store the resulting affine transform.
- * @theta: Shear angle in degrees.
- *
- * Sets up a shearing matrix. In the standard libart coordinate system
- * and a small value for theta, || becomes \\. Horizontal lines remain
- * unchanged.
- **/
-void
-art_affine_shear (double dst[6], double theta)
-{
- double t;
-
- t = tan (theta * M_PI / 180.0);
- dst[0] = 1;
- dst[1] = 0;
- dst[2] = t;
- dst[3] = 1;
- dst[4] = 0;
- dst[5] = 0;
-}
-
-/**
* art_affine_translate: Set up a translation matrix.
* @dst: Where to store the resulting affine transform.
* @tx: X translation amount.
@@ -419,40 +347,3 @@ art_affine_expansion (const double src[6])
return sqrt (fabs (src[0] * src[3] - src[1] * src[2]));
}
-/**
- * art_affine_rectilinear: Determine whether the affine transformation is rectilinear.
- * @src: The original affine transformation.
- *
- * Determines whether @src is rectilinear, i.e. grid-aligned
- * rectangles are transformed to other grid-aligned rectangles. The
- * implementation has epsilon-tolerance for roundoff errors.
- *
- * Return value: TRUE if @src is rectilinear.
- **/
-int
-art_affine_rectilinear (const double src[6])
-{
- return ((fabs (src[1]) < EPSILON && fabs (src[2]) < EPSILON) ||
- (fabs (src[0]) < EPSILON && fabs (src[3]) < EPSILON));
-}
-
-/**
- * art_affine_equal: Determine whether two affine transformations are equal.
- * @matrix1: An affine transformation.
- * @matrix2: Another affine transformation.
- *
- * Determines whether @matrix1 and @matrix2 are equal, with
- * epsilon-tolerance for roundoff errors.
- *
- * Return value: TRUE if @matrix1 and @matrix2 are equal.
- **/
-int
-art_affine_equal (double matrix1[6], double matrix2[6])
-{
- return (fabs (matrix1[0] - matrix2[0]) < EPSILON &&
- fabs (matrix1[1] - matrix2[1]) < EPSILON &&
- fabs (matrix1[2] - matrix2[2]) < EPSILON &&
- fabs (matrix1[3] - matrix2[3]) < EPSILON &&
- fabs (matrix1[4] - matrix2[4]) < EPSILON &&
- fabs (matrix1[5] - matrix2[5]) < EPSILON);
-}
diff --git a/libart_lgpl/art_affine.h b/libart_lgpl/art_affine.h
index 0baee70941..83f64b94ec 100644
--- a/libart_lgpl/art_affine.h
+++ b/libart_lgpl/art_affine.h
@@ -33,12 +33,6 @@ art_affine_point (ArtPoint *dst, const ArtPoint *src,
void
art_affine_invert (double dst_affine[6], const double src_affine[6]);
-/* flip the matrix, FALSE, FALSE is a simple copy operation, and
- TRUE, TRUE equals a rotation by 180 degrees */
-void
-art_affine_flip (double dst_affine[6], const double src_affine[6],
- int horz, int vert);
-
void
art_affine_to_string (char str[128], const double src[6]);
@@ -54,14 +48,6 @@ art_affine_identity (double dst[6]);
void
art_affine_scale (double dst[6], double sx, double sy);
-/* set up a rotation matrix; theta is given in degrees */
-void
-art_affine_rotate (double dst[6], double theta);
-
-/* set up a shearing matrix; theta is given in degrees */
-void
-art_affine_shear (double dst[6], double theta);
-
/* set up a translation matrix */
void
art_affine_translate (double dst[6], double tx, double ty);
@@ -71,16 +57,6 @@ art_affine_translate (double dst[6], double tx, double ty);
double
art_affine_expansion (const double src[6]);
-/* Determine whether the affine transformation is rectilinear,
- i.e. whether a rectangle aligned to the grid is transformed into
- another rectangle aligned to the grid. */
-int
-art_affine_rectilinear (const double src[6]);
-
-/* Determine whether two affine transformations are equal within grid allignment */
-int
-art_affine_equal (double matrix1[6], double matrix2[6]);
-
#ifdef __cplusplus
}
diff --git a/libart_lgpl/art_alphagamma.c b/libart_lgpl/art_alphagamma.c
deleted file mode 100644
index 4651883cf5..0000000000
--- a/libart_lgpl/art_alphagamma.c
+++ /dev/null
@@ -1,85 +0,0 @@
-/* Libart_LGPL - library of basic graphic primitives
- * Copyright (C) 1998 Raph Levien
- *
- * This library 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 library 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 library; if not, write to the
- * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- */
-
-/* Some functions to build alphagamma tables */
-
-#include "config.h"
-#include "art_alphagamma.h"
-
-#include <math.h>
-
-/**
- * art_alphagamma_new: Create a new #ArtAlphaGamma.
- * @gamma: Gamma value.
- *
- * Create a new #ArtAlphaGamma for a specific value of @gamma. When
- * correctly implemented (which is generally not the case in libart),
- * alpha compositing with an alphagamma parameter is equivalent to
- * applying the gamma transformation to source images, doing the alpha
- * compositing (in linear intensity space), then applying the inverse
- * gamma transformation, bringing it back to a gamma-adjusted
- * intensity space.
- *
- * Return value: The newly created #ArtAlphaGamma.
- **/
-ArtAlphaGamma *
-art_alphagamma_new (double gamma)
-{
- int tablesize;
- ArtAlphaGamma *alphagamma;
- int i;
- int *table;
- art_u8 *invtable;
- double s, r_gamma;
-
- tablesize = ceil (gamma * 8);
- if (tablesize < 10)
- tablesize = 10;
-
- alphagamma = (ArtAlphaGamma *)art_alloc (sizeof(ArtAlphaGamma) +
- ((1 << tablesize) - 1) *
- sizeof(art_u8));
- alphagamma->gamma = gamma;
- alphagamma->invtable_size = tablesize;
-
- table = alphagamma->table;
- for (i = 0; i < 256; i++)
- table[i] = (int)floor (((1 << tablesize) - 1) *
- pow (i * (1.0 / 255), gamma) + 0.5);
-
- invtable = alphagamma->invtable;
- s = 1.0 / ((1 << tablesize) - 1);
- r_gamma = 1.0 / gamma;
- for (i = 0; i < 1 << tablesize; i++)
- invtable[i] = (int)floor (255 * pow (i * s, r_gamma) + 0.5);
-
- return alphagamma;
-}
-
-/**
- * art_alphagamma_free: Free an #ArtAlphaGamma.
- * @alphagamma: An #ArtAlphaGamma.
- *
- * Frees the #ArtAlphaGamma.
- **/
-void
-art_alphagamma_free (ArtAlphaGamma *alphagamma)
-{
- art_free (alphagamma);
-}
diff --git a/libart_lgpl/art_alphagamma.h b/libart_lgpl/art_alphagamma.h
index 5f766c95ba..f3ee35765f 100644
--- a/libart_lgpl/art_alphagamma.h
+++ b/libart_lgpl/art_alphagamma.h
@@ -38,12 +38,6 @@ struct _ArtAlphaGamma {
art_u8 invtable[1];
};
-ArtAlphaGamma *
-art_alphagamma_new (double gamma);
-
-void
-art_alphagamma_free (ArtAlphaGamma *alphagamma);
-
#ifdef __cplusplus
}
#endif /* __cplusplus */
diff --git a/libart_lgpl/art_pixbuf.c b/libart_lgpl/art_pixbuf.c
index e99375392e..c624c7dd7d 100644
--- a/libart_lgpl/art_pixbuf.c
+++ b/libart_lgpl/art_pixbuf.c
@@ -111,175 +111,3 @@ art_pixbuf_new_rgba_dnotify (art_u8 *pixels, int width, int height, int rowstrid
return pixbuf;
}
-/**
- * art_pixbuf_new_const_rgb: Create a new RGB #ArtPixBuf with constant pixel data.
- * @pixels: A buffer containing the actual pixel data.
- * @width: The width of the pixbuf.
- * @height: The height of the pixbuf.
- * @rowstride: The rowstride of the pixbuf.
- *
- * Creates a generic data structure for holding a buffer of RGB
- * pixels. It is possible to think of an #ArtPixBuf as a
- * virtualization over specific pixel buffer formats.
- *
- * No action is taken when the #ArtPixBuf is destroyed. Thus, this
- * function is useful when the pixel data is constant or statically
- * allocated.
- *
- * Return value: The newly created #ArtPixBuf.
- **/
-ArtPixBuf *
-art_pixbuf_new_const_rgb (const art_u8 *pixels, int width, int height, int rowstride)
-{
- return art_pixbuf_new_rgb_dnotify ((art_u8 *) pixels, width, height, rowstride, NULL, NULL);
-}
-
-/**
- * art_pixbuf_new_const_rgba: Create a new RGBA #ArtPixBuf with constant pixel data.
- * @pixels: A buffer containing the actual pixel data.
- * @width: The width of the pixbuf.
- * @height: The height of the pixbuf.
- * @rowstride: The rowstride of the pixbuf.
- *
- * Creates a generic data structure for holding a buffer of RGBA
- * pixels. It is possible to think of an #ArtPixBuf as a
- * virtualization over specific pixel buffer formats.
- *
- * No action is taken when the #ArtPixBuf is destroyed. Thus, this
- * function is suitable when the pixel data is constant or statically
- * allocated.
- *
- * Return value: The newly created #ArtPixBuf.
- **/
-ArtPixBuf *
-art_pixbuf_new_const_rgba (const art_u8 *pixels, int width, int height, int rowstride)
-{
- return art_pixbuf_new_rgba_dnotify ((art_u8 *) pixels, width, height, rowstride, NULL, NULL);
-}
-
-static void
-art_pixel_destroy (void *func_data, void *data)
-{
- art_free (data);
-}
-
-/**
- * art_pixbuf_new_rgb: Create a new RGB #ArtPixBuf.
- * @pixels: A buffer containing the actual pixel data.
- * @width: The width of the pixbuf.
- * @height: The height of the pixbuf.
- * @rowstride: The rowstride of the pixbuf.
- *
- * Creates a generic data structure for holding a buffer of RGB
- * pixels. It is possible to think of an #ArtPixBuf as a
- * virtualization over specific pixel buffer formats.
- *
- * The @pixels buffer is freed with art_free() when the #ArtPixBuf is
- * destroyed. Thus, this function is suitable when the pixel data is
- * allocated with art_alloc().
- *
- * Return value: The newly created #ArtPixBuf.
- **/
-ArtPixBuf *
-art_pixbuf_new_rgb (art_u8 *pixels, int width, int height, int rowstride)
-{
- return art_pixbuf_new_rgb_dnotify (pixels, width, height, rowstride, NULL, art_pixel_destroy);
-}
-
-/**
- * art_pixbuf_new_rgba: Create a new RGBA #ArtPixBuf.
- * @pixels: A buffer containing the actual pixel data.
- * @width: The width of the pixbuf.
- * @height: The height of the pixbuf.
- * @rowstride: The rowstride of the pixbuf.
- *
- * Creates a generic data structure for holding a buffer of RGBA
- * pixels. It is possible to think of an #ArtPixBuf as a
- * virtualization over specific pixel buffer formats.
- *
- * The @pixels buffer is freed with art_free() when the #ArtPixBuf is
- * destroyed. Thus, this function is suitable when the pixel data is
- * allocated with art_alloc().
- *
- * Return value: The newly created #ArtPixBuf.
- **/
-ArtPixBuf *
-art_pixbuf_new_rgba (art_u8 *pixels, int width, int height, int rowstride)
-{
- return art_pixbuf_new_rgba_dnotify (pixels, width, height, rowstride, NULL, art_pixel_destroy);
-}
-
-/**
- * art_pixbuf_free: Destroy an #ArtPixBuf.
- * @pixbuf: The #ArtPixBuf to be destroyed.
- *
- * Destroys the #ArtPixBuf, calling the destroy notification function
- * (if non-NULL) so that the memory for the pixel buffer can be
- * properly reclaimed.
- **/
-void
-art_pixbuf_free (ArtPixBuf *pixbuf)
-{
- ArtDestroyNotify destroy = pixbuf->destroy;
- void *destroy_data = pixbuf->destroy_data;
- art_u8 *pixels = pixbuf->pixels;
-
- pixbuf->pixels = NULL;
- pixbuf->destroy = NULL;
- pixbuf->destroy_data = NULL;
-
- if (destroy)
- destroy (destroy_data, pixels);
-
- art_free (pixbuf);
-}
-
-/**
- * art_pixbuf_free_shallow:
- * @pixbuf: The #ArtPixBuf to be destroyed.
- *
- * Destroys the #ArtPixBuf without calling the destroy notification function.
- *
- * This function is deprecated. Use the _dnotify variants for
- * allocation instead.
- **/
-void
-art_pixbuf_free_shallow (ArtPixBuf *pixbuf)
-{
- art_free (pixbuf);
-}
-
-/**
- * art_pixbuf_duplicate: Duplicate a pixbuf.
- * @pixbuf: The #ArtPixBuf to duplicate.
- *
- * Duplicates a pixbuf, including duplicating the buffer.
- *
- * Return value: The duplicated pixbuf.
- **/
-ArtPixBuf *
-art_pixbuf_duplicate (const ArtPixBuf *pixbuf)
-{
- ArtPixBuf *result;
- int size;
-
- result = art_new (ArtPixBuf, 1);
-
- result->format = pixbuf->format;
- result->n_channels = pixbuf->n_channels;
- result->has_alpha = pixbuf->has_alpha;
- result->bits_per_sample = pixbuf->bits_per_sample;
-
- size = (pixbuf->height - 1) * pixbuf->rowstride +
- pixbuf->width * ((pixbuf->n_channels * pixbuf->bits_per_sample + 7) >> 3);
- result->pixels = art_alloc (size);
- memcpy (result->pixels, pixbuf->pixels, size);
-
- result->width = pixbuf->width;
- result->height = pixbuf->height;
- result->rowstride = pixbuf->rowstride;
- result->destroy_data = NULL;
- result->destroy = art_pixel_destroy;
-
- return result;
-}
diff --git a/libart_lgpl/art_pixbuf.h b/libart_lgpl/art_pixbuf.h
index 31f5620671..6d79f5d653 100644
--- a/libart_lgpl/art_pixbuf.h
+++ b/libart_lgpl/art_pixbuf.h
@@ -59,20 +59,6 @@ struct _ArtPixBuf {
ArtDestroyNotify destroy;
};
-/* allocate an ArtPixBuf from art_alloc()ed pixels (automated destruction) */
-ArtPixBuf *
-art_pixbuf_new_rgb (art_u8 *pixels, int width, int height, int rowstride);
-
-ArtPixBuf *
-art_pixbuf_new_rgba (art_u8 *pixels, int width, int height, int rowstride);
-
-/* allocate an ArtPixBuf from constant pixels (no destruction) */
-ArtPixBuf *
-art_pixbuf_new_const_rgb (const art_u8 *pixels, int width, int height, int rowstride);
-
-ArtPixBuf *
-art_pixbuf_new_const_rgba (const art_u8 *pixels, int width, int height, int rowstride);
-
/* allocate an ArtPixBuf and notify creator upon destruction */
ArtPixBuf *
art_pixbuf_new_rgb_dnotify (art_u8 *pixels, int width, int height, int rowstride,
@@ -82,17 +68,6 @@ ArtPixBuf *
art_pixbuf_new_rgba_dnotify (art_u8 *pixels, int width, int height, int rowstride,
void *dfunc_data, ArtDestroyNotify dfunc);
-/* free an ArtPixBuf with destroy notification */
-void
-art_pixbuf_free (ArtPixBuf *pixbuf);
-
-/* deprecated function, use the _dnotify variants for allocation instead */
-void
-art_pixbuf_free_shallow (ArtPixBuf *pixbuf);
-
-ArtPixBuf *
-art_pixbuf_duplicate (const ArtPixBuf *pixbuf);
-
#ifdef __cplusplus
}
#endif
diff --git a/libart_lgpl/art_rect.c b/libart_lgpl/art_rect.c
index c9dd5b3702..6d318a80eb 100644
--- a/libart_lgpl/art_rect.c
+++ b/libart_lgpl/art_rect.c
@@ -48,28 +48,6 @@ art_irect_copy (ArtIRect *dest, const ArtIRect *src) {
}
/**
- * art_irect_union: Find union of two integer rectangles.
- * @dest: Where the result is stored.
- * @src1: A source rectangle.
- * @src2: Another source rectangle.
- *
- * Finds the smallest rectangle that includes @src1 and @src2.
- **/
-void
-art_irect_union (ArtIRect *dest, const ArtIRect *src1, const ArtIRect *src2) {
- if (art_irect_empty (src1)) {
- art_irect_copy (dest, src2);
- } else if (art_irect_empty (src2)) {
- art_irect_copy (dest, src1);
- } else {
- dest->x0 = MIN (src1->x0, src2->x0);
- dest->y0 = MIN (src1->y0, src2->y0);
- dest->x1 = MAX (src1->x1, src2->x1);
- dest->y1 = MAX (src1->y1, src2->y1);
- }
-}
-
-/**
* art_irect_intersection: Find intersection of two integer rectangles.
* @dest: Where the result is stored.
* @src1: A source rectangle.
@@ -141,22 +119,6 @@ art_drect_union (ArtDRect *dest, const ArtDRect *src1, const ArtDRect *src2) {
}
/**
- * art_drect_intersection: Find intersection of two rectangles.
- * @dest: Where the result is stored.
- * @src1: A source rectangle.
- * @src2: Another source rectangle.
- *
- * Finds the intersection of @src1 and @src2.
- **/
-void
-art_drect_intersect (ArtDRect *dest, const ArtDRect *src1, const ArtDRect *src2) {
- dest->x0 = MAX (src1->x0, src2->x0);
- dest->y0 = MAX (src1->y0, src2->y0);
- dest->x1 = MIN (src1->x1, src2->x1);
- dest->y1 = MIN (src1->y1, src2->y1);
-}
-
-/**
* art_irect_empty: Determine whether rectangle is empty.
* @src: The source rectangle.
*
diff --git a/libart_lgpl/art_rect.h b/libart_lgpl/art_rect.h
index 088079f712..247cbea3e9 100644
--- a/libart_lgpl/art_rect.h
+++ b/libart_lgpl/art_rect.h
@@ -40,10 +40,6 @@ struct _ArtIRect {
/* Make a copy of the rectangle. */
void art_irect_copy (ArtIRect *dest, const ArtIRect *src);
-/* Find the smallest rectangle that includes both source rectangles. */
-void art_irect_union (ArtIRect *dest,
- const ArtIRect *src1, const ArtIRect *src2);
-
/* Return the intersection of the two rectangles */
void art_irect_intersect (ArtIRect *dest,
const ArtIRect *src1, const ArtIRect *src2);
@@ -58,10 +54,6 @@ void art_drect_copy (ArtDRect *dest, const ArtDRect *src);
void art_drect_union (ArtDRect *dest,
const ArtDRect *src1, const ArtDRect *src2);
-/* Return the intersection of the two rectangles */
-void art_drect_intersect (ArtDRect *dest,
- const ArtDRect *src1, const ArtDRect *src2);
-
/* Return true if the rectangle is empty. */
int art_drect_empty (const ArtDRect *src);
diff --git a/libart_lgpl/art_render.c b/libart_lgpl/art_render.c
index 65b344cc56..771f15fe44 100644
--- a/libart_lgpl/art_render.c
+++ b/libart_lgpl/art_render.c
@@ -39,115 +39,10 @@ struct _ArtRenderPriv {
ArtRenderCallback **callbacks;
};
-ArtRender *
-art_render_new (int x0, int y0, int x1, int y1,
- art_u8 *pixels, int rowstride,
- int n_chan, int depth, ArtAlphaType alpha_type,
- ArtAlphaGamma *alphagamma)
-{
- ArtRenderPriv *priv;
- ArtRender *result;
-
- priv = art_new (ArtRenderPriv, 1);
- result = &priv->super;
-
- if (n_chan > ART_MAX_CHAN)
- {
- art_warn ("art_render_new: n_chan = %d, exceeds %d max\n",
- n_chan, ART_MAX_CHAN);
- return NULL;
- }
- if (depth > ART_MAX_DEPTH)
- {
- art_warn ("art_render_new: depth = %d, exceeds %d max\n",
- depth, ART_MAX_DEPTH);
- return NULL;
- }
- if (x0 >= x1)
- {
- art_warn ("art_render_new: x0 >= x1 (x0 = %d, x1 = %d)\n", x0, x1);
- return NULL;
- }
- result->x0 = x0;
- result->y0 = y0;
- result->x1 = x1;
- result->y1 = y1;
- result->pixels = pixels;
- result->rowstride = rowstride;
- result->n_chan = n_chan;
- result->depth = depth;
- result->alpha_type = alpha_type;
-
- result->clear = ART_FALSE;
- result->opacity = 0x10000;
- result->compositing_mode = ART_COMPOSITE_NORMAL;
- result->alphagamma = alphagamma;
-
- result->alpha_buf = NULL;
- result->image_buf = NULL;
-
- result->run = NULL;
- result->span_x = NULL;
-
- result->need_span = ART_FALSE;
-
- priv->image_source = NULL;
-
- priv->n_mask_source = 0;
- priv->mask_source = NULL;
-
- return result;
-}
-
/* todo on clear routines: I haven't really figured out what to do
with clearing the alpha channel. It _should_ be possible to clear
to an arbitrary RGBA color. */
-/**
- * art_render_clear: Set clear color.
- * @clear_color: Color with which to clear dest.
- *
- * Sets clear color, equivalent to actually clearing the destination
- * buffer before rendering. This is the most general form.
- **/
-void
-art_render_clear (ArtRender *render, const ArtPixMaxDepth *clear_color)
-{
- int i;
- int n_ch = render->n_chan + (render->alpha_type != ART_ALPHA_NONE);
-
- render->clear = ART_TRUE;
- for (i = 0; i < n_ch; i++)
- render->clear_color[i] = clear_color[i];
-}
-
-/**
- * art_render_clear_rgb: Set clear color, given in RGB format.
- * @clear_rgb: Clear color, in 0xRRGGBB format.
- *
- * Sets clear color, equivalent to actually clearing the destination
- * buffer before rendering.
- **/
-void
-art_render_clear_rgb (ArtRender *render, art_u32 clear_rgb)
-{
- if (render->n_chan != 3)
- art_warn ("art_render_clear_rgb: called on render with %d channels, only works with 3\n",
- render->n_chan);
- else
- {
- int r, g, b;
-
- render->clear = ART_TRUE;
- r = clear_rgb >> 16;
- g = (clear_rgb >> 8) & 0xff;
- b = clear_rgb & 0xff;
- render->clear_color[0] = ART_PIX_MAX_FROM_8(r);
- render->clear_color[1] = ART_PIX_MAX_FROM_8(g);
- render->clear_color[2] = ART_PIX_MAX_FROM_8(b);
- }
-}
-
static void
art_render_nop_done (ArtRenderCallback *self, ArtRender *render)
{
@@ -238,43 +133,6 @@ const ArtRenderCallback art_render_clear_16_obj =
#endif /* ART_MAX_DEPTH >= 16 */
-/* todo: inline */
-static ArtRenderCallback *
-art_render_choose_clear_callback (ArtRender *render)
-{
- ArtRenderCallback *clear_callback;
-
- if (render->depth == 8)
- {
- if (render->n_chan == 3 &&
- render->alpha_type == ART_ALPHA_NONE)
- clear_callback = (ArtRenderCallback *)&art_render_clear_rgb8_obj;
- else
- clear_callback = (ArtRenderCallback *)&art_render_clear_8_obj;
- }
-#if ART_MAX_DEPTH >= 16
- else if (render->depth == 16)
- clear_callback = (ArtRenderCallback *)&art_render_clear_16_obj;
-#endif
- else
- {
- art_die ("art_render_choose_clear_callback: inconsistent render->depth = %d\n",
- render->depth);
- }
- return clear_callback;
-}
-
-#if 0
-/* todo: get around to writing this */
-static void
-art_render_composite_render_noa_8_norm (ArtRenderCallback *self, ArtRender *render,
- art_u8 *dest, int y)
-{
- int width = render->x1 - render->x0;
-
-}
-#endif
-
/* This is the most general form of the function. It is slow but
(hopefully) correct. Actually, I'm still worried about roundoff
errors in the premul case - it seems to me that an off-by-one could
@@ -882,27 +740,6 @@ const ArtRenderCallback art_render_composite_8_opt2_obj =
};
-/* todo: inline */
-static ArtRenderCallback *
-art_render_choose_compositing_callback (ArtRender *render)
-{
- if (render->depth == 8 && render->buf_depth == 8)
- {
- if (render->n_chan == 3 &&
- render->alpha_buf == NULL &&
- render->alpha_type == ART_ALPHA_SEPARATE)
- {
- if (render->buf_alpha == ART_ALPHA_NONE)
- return (ArtRenderCallback *)&art_render_composite_8_opt1_obj;
- else if (render->buf_alpha == ART_ALPHA_PREMUL)
- return (ArtRenderCallback *)&art_render_composite_8_opt2_obj;
- }
-
- return (ArtRenderCallback *)&art_render_composite_8_obj;
- }
- return (ArtRenderCallback *)&art_render_composite_obj;
-}
-
/**
* art_render_invoke_callbacks: Invoke the callbacks in the render object.
* @render: The render object.
@@ -930,184 +767,6 @@ art_render_invoke_callbacks (ArtRender *render, art_u8 *dest, int y)
}
/**
- * art_render_invoke: Perform the requested rendering task.
- * @render: The render object.
- *
- * Invokes the renderer and all sources associated with it, to perform
- * the requested rendering task.
- **/
-void
-art_render_invoke (ArtRender *render)
-{
- ArtRenderPriv *priv = (ArtRenderPriv *)render;
- int width;
- int best_driver, best_score;
- int i;
- int n_callbacks, n_callbacks_max;
- ArtImageSource *image_source;
- ArtImageSourceFlags image_flags;
- int buf_depth;
- ArtAlphaType buf_alpha;
- art_boolean first = ART_TRUE;
-
- if (render == NULL)
- {
- art_warn ("art_render_invoke: called with render == NULL\n");
- return;
- }
- if (priv->image_source == NULL)
- {
- art_warn ("art_render_invoke: no image source given\n");
- return;
- }
-
- width = render->x1 - render->x0;
-
- render->run = art_new (ArtRenderMaskRun, width + 1);
-
- /* Elect a mask source as driver. */
- best_driver = -1;
- best_score = 0;
- for (i = 0; i < priv->n_mask_source; i++)
- {
- int score;
- ArtMaskSource *mask_source;
-
- mask_source = priv->mask_source[i];
- score = mask_source->can_drive (mask_source, render);
- if (score > best_score)
- {
- best_score = score;
- best_driver = i;
- }
- }
-
- /* Allocate alpha buffer if needed. */
- if (priv->n_mask_source > 1 ||
- (priv->n_mask_source == 1 && best_driver < 0))
- {
- render->alpha_buf = art_new (art_u8, (width * render->depth) >> 3);
- }
-
- /* Negotiate image rendering and compositing. */
- image_source = priv->image_source;
- image_source->negotiate (image_source, render, &image_flags, &buf_depth,
- &buf_alpha);
-
- /* Build callback list. */
- n_callbacks_max = priv->n_mask_source + 3;
- priv->callbacks = art_new (ArtRenderCallback *, n_callbacks_max);
- n_callbacks = 0;
- for (i = 0; i < priv->n_mask_source; i++)
- if (i != best_driver)
- {
- ArtMaskSource *mask_source = priv->mask_source[i];
-
- mask_source->prepare (mask_source, render, first);
- first = ART_FALSE;
- priv->callbacks[n_callbacks++] = &mask_source->super;
- }
-
- if (render->clear && !(image_flags & ART_IMAGE_SOURCE_CAN_CLEAR))
- priv->callbacks[n_callbacks++] =
- art_render_choose_clear_callback (render);
-
- priv->callbacks[n_callbacks++] = &image_source->super;
-
- /* Allocate image buffer and add compositing callback if needed. */
- if (!(image_flags & ART_IMAGE_SOURCE_CAN_COMPOSITE))
- {
- int bytespp = ((render->n_chan + (buf_alpha != ART_ALPHA_NONE)) *
- buf_depth) >> 3;
- render->buf_depth = buf_depth;
- render->buf_alpha = buf_alpha;
- render->image_buf = art_new (art_u8, width * bytespp);
- priv->callbacks[n_callbacks++] =
- art_render_choose_compositing_callback (render);
- }
-
- priv->n_callbacks = n_callbacks;
-
- if (render->need_span)
- render->span_x = art_new (int, width + 1);
-
- /* Invoke the driver */
- if (best_driver >= 0)
- {
- ArtMaskSource *driver;
-
- driver = priv->mask_source[best_driver];
- driver->invoke_driver (driver, render);
- }
- else
- {
- art_u8 *dest_ptr = render->pixels;
- int y;
-
- /* Dummy driver */
- render->n_run = 2;
- render->run[0].x = render->x0;
- render->run[0].alpha = 0x8000 + 0xff * render->opacity;
- render->run[1].x = render->x1;
- render->run[1].alpha = 0x8000;
- if (render->need_span)
- {
- render->n_span = 2;
- render->span_x[0] = render->x0;
- render->span_x[1] = render->x1;
- }
- for (y = render->y0; y < render->y1; y++)
- {
- art_render_invoke_callbacks (render, dest_ptr, y);
- dest_ptr += render->rowstride;
- }
- }
-
- if (priv->mask_source != NULL)
- art_free (priv->mask_source);
-
- /* clean up callbacks */
- for (i = 0; i < priv->n_callbacks; i++)
- {
- ArtRenderCallback *callback;
-
- callback = priv->callbacks[i];
- callback->done (callback, render);
- }
-
- /* Tear down object */
- if (render->alpha_buf != NULL)
- art_free (render->alpha_buf);
- if (render->image_buf != NULL)
- art_free (render->image_buf);
- art_free (render->run);
- if (render->span_x != NULL)
- art_free (render->span_x);
- art_free (priv->callbacks);
- art_free (render);
-}
-
-/**
- * art_render_mask_solid: Add a solid translucent mask.
- * @render: The render object.
- * @opacity: Opacity in [0..0x10000] form.
- *
- * Adds a translucent mask to the rendering object.
- **/
-void
-art_render_mask_solid (ArtRender *render, int opacity)
-{
- art_u32 old_opacity = render->opacity;
- art_u32 new_opacity_tmp;
-
- if (opacity == 0x10000)
- /* avoid potential overflow */
- return;
- new_opacity_tmp = old_opacity * (art_u32)opacity + 0x8000;
- render->opacity = new_opacity_tmp >> 16;
-}
-
-/**
* art_render_add_mask_source: Add a mask source to the render object.
* @render: Render object.
* @mask_source: Mask source to add.
@@ -1170,214 +829,3 @@ struct _ArtImageSourceSolid {
art_boolean init;
};
-static void
-art_render_image_solid_done (ArtRenderCallback *self, ArtRender *render)
-{
- ArtImageSourceSolid *z = (ArtImageSourceSolid *)self;
-
- if (z->rgbtab != NULL)
- art_free (z->rgbtab);
- art_free (self);
-}
-
-static void
-art_render_image_solid_rgb8_opaq_init (ArtImageSourceSolid *self, ArtRender *render)
-{
- ArtImageSourceSolid *z = (ArtImageSourceSolid *)self;
- ArtPixMaxDepth color_max;
- int r_fg, g_fg, b_fg;
- int r_bg, g_bg, b_bg;
- int r, g, b;
- int dr, dg, db;
- int i;
- int tmp;
- art_u32 *rgbtab;
-
- rgbtab = art_new (art_u32, 256);
- z->rgbtab = rgbtab;
-
- color_max = self->color[0];
- r_fg = ART_PIX_8_FROM_MAX (color_max);
- color_max = self->color[1];
- g_fg = ART_PIX_8_FROM_MAX (color_max);
- color_max = self->color[2];
- b_fg = ART_PIX_8_FROM_MAX (color_max);
-
- color_max = render->clear_color[0];
- r_bg = ART_PIX_8_FROM_MAX (color_max);
- color_max = render->clear_color[1];
- g_bg = ART_PIX_8_FROM_MAX (color_max);
- color_max = render->clear_color[2];
- b_bg = ART_PIX_8_FROM_MAX (color_max);
-
- r = (r_bg << 16) + 0x8000;
- g = (g_bg << 16) + 0x8000;
- b = (b_bg << 16) + 0x8000;
- tmp = ((r_fg - r_bg) << 16) + 0x80;
- dr = (tmp + (tmp >> 8)) >> 8;
- tmp = ((g_fg - g_bg) << 16) + 0x80;
- dg = (tmp + (tmp >> 8)) >> 8;
- tmp = ((b_fg - b_bg) << 16) + 0x80;
- db = (tmp + (tmp >> 8)) >> 8;
-
- for (i = 0; i < 256; i++)
- {
- rgbtab[i] = (r & 0xff0000) | ((g & 0xff0000) >> 8) | (b >> 16);
- r += dr;
- g += dg;
- b += db;
- }
-}
-
-static void
-art_render_image_solid_rgb8_opaq (ArtRenderCallback *self, ArtRender *render,
- art_u8 *dest, int y)
-{
- ArtImageSourceSolid *z = (ArtImageSourceSolid *)self;
- ArtRenderMaskRun *run = render->run;
- int n_run = render->n_run;
- art_u32 *rgbtab = z->rgbtab;
- art_u32 rgb;
- int x0 = render->x0;
- int x1 = render->x1;
- int run_x0, run_x1;
- int i;
- int ix;
-
- if (n_run > 0)
- {
- run_x1 = run[0].x;
- if (run_x1 > x0)
- {
- rgb = rgbtab[0];
- art_rgb_fill_run (dest,
- rgb >> 16, (rgb >> 8) & 0xff, rgb & 0xff,
- run_x1 - x0);
- }
- for (i = 0; i < n_run - 1; i++)
- {
- run_x0 = run_x1;
- run_x1 = run[i + 1].x;
- rgb = rgbtab[(run[i].alpha >> 16) & 0xff];
- ix = (run_x0 - x0) * 3;
-#define OPTIMIZE_LEN_1
-#ifdef OPTIMIZE_LEN_1
- if (run_x1 - run_x0 == 1)
- {
- dest[ix] = rgb >> 16;
- dest[ix + 1] = (rgb >> 8) & 0xff;
- dest[ix + 2] = rgb & 0xff;
- }
- else
- {
- art_rgb_fill_run (dest + ix,
- rgb >> 16, (rgb >> 8) & 0xff, rgb & 0xff,
- run_x1 - run_x0);
- }
-#else
- art_rgb_fill_run (dest + ix,
- rgb >> 16, (rgb >> 8) & 0xff, rgb & 0xff,
- run_x1 - run_x0);
-#endif
- }
- }
- else
- {
- run_x1 = x0;
- }
- if (run_x1 < x1)
- {
- rgb = rgbtab[0];
- art_rgb_fill_run (dest + (run_x1 - x0) * 3,
- rgb >> 16, (rgb >> 8) & 0xff, rgb & 0xff,
- x1 - run_x1);
- }
-}
-
-static void
-art_render_image_solid_rgb8 (ArtRenderCallback *self, ArtRender *render,
- art_u8 *dest, int y)
-{
- ArtImageSourceSolid *z = (ArtImageSourceSolid *)self;
- int width = render->x1 - render->x0;
- art_u8 r, g, b;
- ArtPixMaxDepth color_max;
-
- /* todo: replace this simple test with real sparseness */
- if (z->init)
- return;
- z->init = ART_TRUE;
-
- color_max = z->color[0];
- r = ART_PIX_8_FROM_MAX (color_max);
- color_max = z->color[1];
- g = ART_PIX_8_FROM_MAX (color_max);
- color_max = z->color[2];
- b = ART_PIX_8_FROM_MAX (color_max);
-
- art_rgb_fill_run (render->image_buf, r, g, b, width);
-}
-
-static void
-art_render_image_solid_negotiate (ArtImageSource *self, ArtRender *render,
- ArtImageSourceFlags *p_flags,
- int *p_buf_depth, ArtAlphaType *p_alpha)
-{
- ArtImageSourceSolid *z = (ArtImageSourceSolid *)self;
- ArtImageSourceFlags flags = 0;
- static void (*render_cbk) (ArtRenderCallback *self, ArtRender *render,
- art_u8 *dest, int y);
-
- render_cbk = NULL;
-
- if (render->depth == 8 && render->n_chan == 3 &&
- render->alpha_type == ART_ALPHA_NONE)
- {
- if (render->clear)
- {
- render_cbk = art_render_image_solid_rgb8_opaq;
- flags |= ART_IMAGE_SOURCE_CAN_CLEAR | ART_IMAGE_SOURCE_CAN_COMPOSITE;
- art_render_image_solid_rgb8_opaq_init (z, render);
- }
- }
- if (render_cbk == NULL)
- {
- if (render->depth == 8)
- {
- render_cbk = art_render_image_solid_rgb8;
- *p_buf_depth = 8;
- *p_alpha = ART_ALPHA_NONE; /* todo */
- }
- }
- /* todo: general case */
- self->super.render = render_cbk;
- *p_flags = flags;
-}
-
-/**
- * art_render_image_solid: Add a solid color image source.
- * @render: The render object.
- * @color: Color.
- *
- * Adds an image source with the solid color given by @color. The
- * color need not be retained in memory after this call.
- **/
-void
-art_render_image_solid (ArtRender *render, ArtPixMaxDepth *color)
-{
- ArtImageSourceSolid *image_source;
- int i;
-
- image_source = art_new (ArtImageSourceSolid, 1);
- image_source->super.super.render = NULL;
- image_source->super.super.done = art_render_image_solid_done;
- image_source->super.negotiate = art_render_image_solid_negotiate;
-
- for (i = 0; i < render->n_chan; i++)
- image_source->color[i] = color[i];
-
- image_source->rgbtab = NULL;
- image_source->init = ART_FALSE;
-
- art_render_add_image_source (render, &image_source->super);
-}
diff --git a/libart_lgpl/art_render.h b/libart_lgpl/art_render.h
index 399033cd0f..db0933ea83 100644
--- a/libart_lgpl/art_render.h
+++ b/libart_lgpl/art_render.h
@@ -139,27 +139,6 @@ struct _ArtRender {
art_boolean need_span;
};
-ArtRender *
-art_render_new (int x0, int y0, int x1, int y1,
- art_u8 *pixels, int rowstride,
- int n_chan, int depth, ArtAlphaType alpha_type,
- ArtAlphaGamma *alphagamma);
-
-void
-art_render_invoke (ArtRender *render);
-
-void
-art_render_clear (ArtRender *render, const ArtPixMaxDepth *clear_color);
-
-void
-art_render_clear_rgb (ArtRender *render, art_u32 clear_rgb);
-
-void
-art_render_mask_solid (ArtRender *render, int opacity);
-
-void
-art_render_image_solid (ArtRender *render, ArtPixMaxDepth *color);
-
/* The next two functions are for custom mask sources only. */
void
art_render_add_mask_source (ArtRender *render, ArtMaskSource *mask_source);
diff --git a/libart_lgpl/art_render_gradient.c b/libart_lgpl/art_render_gradient.c
deleted file mode 100644
index bf93c6fff1..0000000000
--- a/libart_lgpl/art_render_gradient.c
+++ /dev/null
@@ -1,716 +0,0 @@
-/*
- * art_render_gradient.c: Gradient image source for modular rendering.
- *
- * Libart_LGPL - library of basic graphic primitives
- * Copyright (C) 2000 Raph Levien
- *
- * This library 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 library 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 library; if not, write to the
- * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- *
- * Authors: Raph Levien <raph@acm.org>
- * Alexander Larsson <alla@lysator.liu.se>
- */
-
-#include "config.h"
-#include "art_render_gradient.h"
-
-#include <math.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-#include <assert.h>
-
-/* Hack to find out how to define alloca on different platforms.
- * Modified version of glib/galloca.h.
- */
-
-#ifdef __GNUC__
-/* GCC does the right thing */
-# undef alloca
-# define alloca(size) __builtin_alloca (size)
-#elif defined (HAVE_ALLOCA_H)
-/* a native and working alloca.h is there */
-# include <alloca.h>
-#else /* !__GNUC__ && !HAVE_ALLOCA_H */
-# ifdef _MSC_VER
-# include <malloc.h>
-# define alloca _alloca
-# else /* !_MSC_VER */
-# ifdef _AIX
- #pragma alloca
-# else /* !_AIX */
-# ifndef alloca /* predefined by HP cc +Olibcalls */
-char *alloca ();
-# endif /* !alloca */
-# endif /* !_AIX */
-# endif /* !_MSC_VER */
-#endif /* !__GNUC__ && !HAVE_ALLOCA_H */
-
-#undef DEBUG_SPEW
-
-typedef struct _ArtImageSourceGradLin ArtImageSourceGradLin;
-typedef struct _ArtImageSourceGradRad ArtImageSourceGradRad;
-
-/* The stops will be copied right after this structure */
-struct _ArtImageSourceGradLin {
- ArtImageSource super;
- ArtGradientLinear gradient;
- ArtGradientStop stops[1];
-};
-
-/* The stops will be copied right after this structure */
-struct _ArtImageSourceGradRad {
- ArtImageSource super;
- ArtGradientRadial gradient;
- double a;
- ArtGradientStop stops[1];
-};
-
-#define EPSILON 1e-6
-
-#ifndef MAX
-#define MAX(a, b) (((a) > (b)) ? (a) : (b))
-#endif /* MAX */
-
-#ifndef MIN
-#define MIN(a, b) (((a) < (b)) ? (a) : (b))
-#endif /* MIN */
-
-static void
-art_rgba_gradient_run (art_u8 *buf,
- art_u8 *color1,
- art_u8 *color2,
- int len)
-{
- int i;
- int r, g, b, a;
- int dr, dg, db, da;
-
-#ifdef DEBUG_SPEW
- printf ("gradient run from %3d %3d %3d %3d to %3d %3d %3d %3d in %d pixels\n",
- color1[0], color1[1], color1[2], color1[3],
- color2[0], color2[1], color2[2], color2[3],
- len);
-#endif
-
- r = (color1[0] << 16) + 0x8000;
- g = (color1[1] << 16) + 0x8000;
- b = (color1[2] << 16) + 0x8000;
- a = (color1[3] << 16) + 0x8000;
- dr = ((color2[0] - color1[0]) << 16) / len;
- dg = ((color2[1] - color1[1]) << 16) / len;
- db = ((color2[2] - color1[2]) << 16) / len;
- da = ((color2[3] - color1[3]) << 16) / len;
-
- for (i = 0; i < len; i++)
- {
- *buf++ = (r>>16);
- *buf++ = (g>>16);
- *buf++ = (b>>16);
- *buf++ = (a>>16);
-
- r += dr;
- g += dg;
- b += db;
- a += da;
- }
-}
-
-static void
-calc_color_at (ArtGradientStop *stops,
- int n_stops,
- ArtGradientSpread spread,
- double offset,
- double offset_fraction,
- int favor_start,
- int ix,
- art_u8 *color)
-{
- double off0, off1;
- int j;
-
- if (spread == ART_GRADIENT_PAD)
- {
- if (offset < 0.0)
- {
- color[0] = ART_PIX_8_FROM_MAX (stops[0].color[0]);
- color[1] = ART_PIX_8_FROM_MAX (stops[0].color[1]);
- color[2] = ART_PIX_8_FROM_MAX (stops[0].color[2]);
- color[3] = ART_PIX_8_FROM_MAX (stops[0].color[3]);
- return;
- }
- if (offset >= 1.0)
- {
- color[0] = ART_PIX_8_FROM_MAX (stops[n_stops-1].color[0]);
- color[1] = ART_PIX_8_FROM_MAX (stops[n_stops-1].color[1]);
- color[2] = ART_PIX_8_FROM_MAX (stops[n_stops-1].color[2]);
- color[3] = ART_PIX_8_FROM_MAX (stops[n_stops-1].color[3]);
- return;
- }
- }
-
- if (ix > 0 && ix < n_stops)
- {
- off0 = stops[ix - 1].offset;
- off1 = stops[ix].offset;
- if (fabs (off1 - off0) > EPSILON)
- {
- double interp;
- double o;
- o = offset_fraction;
-
- if ((fabs (o) < EPSILON) && (!favor_start))
- o = 1.0;
- else if ((fabs (o-1.0) < EPSILON) && (favor_start))
- o = 0.0;
-
- /*
- if (offset_fraction == 0.0 && !favor_start)
- offset_fraction = 1.0;
- */
-
- interp = (o - off0) / (off1 - off0);
- for (j = 0; j < 4; j++)
- {
- int z0, z1;
- int z;
- z0 = stops[ix - 1].color[j];
- z1 = stops[ix].color[j];
- z = floor (z0 + (z1 - z0) * interp + 0.5);
- color[j] = ART_PIX_8_FROM_MAX (z);
- }
- return;
- }
- /* If offsets are too close to safely do the division, just
- pick the ix color. */
- color[0] = ART_PIX_8_FROM_MAX (stops[ix].color[0]);
- color[1] = ART_PIX_8_FROM_MAX (stops[ix].color[1]);
- color[2] = ART_PIX_8_FROM_MAX (stops[ix].color[2]);
- color[3] = ART_PIX_8_FROM_MAX (stops[ix].color[3]);
- return;
- }
-
- printf ("WARNING! bad ix %d in calc_color_at() [internal error]\n", ix);
- assert (0);
-}
-
-static void
-art_render_gradient_linear_render_8 (ArtRenderCallback *self,
- ArtRender *render,
- art_u8 *dest, int y)
-{
- ArtImageSourceGradLin *z = (ArtImageSourceGradLin *)self;
- const ArtGradientLinear *gradient = &(z->gradient);
- int i;
- int width = render->x1 - render->x0;
- int len;
- double offset, d_offset;
- double offset_fraction;
- int next_stop;
- int ix;
- art_u8 color1[4], color2[4];
- int n_stops = gradient->n_stops;
- int extra_stops;
- ArtGradientStop *stops = gradient->stops;
- ArtGradientStop *tmp_stops;
- art_u8 *bufp = render->image_buf;
- ArtGradientSpread spread = gradient->spread;
-
-#ifdef DEBUG_SPEW
- printf ("x1: %d, x2: %d, y: %d\n", render->x0, render->x1, y);
- printf ("spread: %d, stops:", gradient->spread);
- for (i=0;i<n_stops;i++)
- {
- printf ("%f, ", gradient->stops[i].offset);
- }
- printf ("\n");
- printf ("a: %f, b: %f, c: %f\n", gradient->a, gradient->b, gradient->c);
-#endif
-
- offset = render->x0 * gradient->a + y * gradient->b + gradient->c;
- d_offset = gradient->a;
-
- /* We need to force the gradient to extend the whole 0..1 segment,
- because the rest of the code doesn't handle partial gradients
- correctly */
- if ((gradient->stops[0].offset > EPSILON /* == 0.0 */) ||
- (gradient->stops[n_stops-1].offset < (1.0 - EPSILON)))
- {
- extra_stops = 0;
- tmp_stops = stops = alloca (sizeof (ArtGradientStop) * (n_stops + 2));
- if (gradient->stops[0].offset > EPSILON /* 0.0 */)
- {
- memcpy (tmp_stops, gradient->stops, sizeof (ArtGradientStop));
- tmp_stops[0].offset = 0.0;
- tmp_stops += 1;
- extra_stops++;
- }
- memcpy (tmp_stops, gradient->stops, sizeof (ArtGradientStop) * n_stops);
- if (gradient->stops[n_stops-1].offset < (1.0 - EPSILON))
- {
- tmp_stops += n_stops;
- memcpy (tmp_stops, &gradient->stops[n_stops-1], sizeof (ArtGradientStop));
- tmp_stops[0].offset = 1.0;
- extra_stops++;
- }
- n_stops += extra_stops;
-
-
-#ifdef DEBUG_SPEW
- printf ("start/stop modified stops:");
- for (i=0;i<n_stops;i++)
- {
- printf ("%f, ", stops[i].offset);
- }
- printf ("\n");
-#endif
-
- }
-
- if (spread == ART_GRADIENT_REFLECT)
- {
- tmp_stops = stops;
- stops = alloca (sizeof (ArtGradientStop) * n_stops * 2);
- memcpy (stops, tmp_stops, sizeof (ArtGradientStop) * n_stops);
-
- for (i = 0; i< n_stops; i++)
- {
- stops[n_stops * 2 - 1 - i].offset = (1.0 - stops[i].offset / 2.0);
- memcpy (stops[n_stops * 2 - 1 - i].color, stops[i].color, sizeof (stops[i].color));
- stops[i].offset = stops[i].offset / 2.0;
- }
-
- spread = ART_GRADIENT_REPEAT;
- offset = offset / 2.0;
- d_offset = d_offset / 2.0;
-
- n_stops = 2 * n_stops;
-
-#ifdef DEBUG_SPEW
- printf ("reflect modified stops:");
- for (i=0;i<n_stops;i++)
- {
- printf ("%f, ", stops[i].offset);
- }
- printf ("\n");
-#endif
- }
-
- offset_fraction = offset - floor (offset);
-#ifdef DEBUG_SPEW
- printf ("inital offset: %f, fraction: %f d_offset: %f\n", offset, offset_fraction, d_offset);
-#endif
- /* ix is selected so that offset_fraction is
- stops[ix-1] <= offset_fraction <= stops[ix]
- If offset_fraction is equal to one of the edges, ix
- is selected so the the section of the line extending
- in the same direction as d_offset is between ix-1 and ix.
- */
- for (ix = 0; ix < n_stops; ix++)
- if (stops[ix].offset > offset_fraction ||
- (d_offset < 0.0 && fabs (stops[ix].offset - offset_fraction) < EPSILON))
- break;
- if (ix == 0)
- ix = n_stops - 1;
- else if (ix == n_stops)
- ix = n_stops - 1;
-
-#ifdef DEBUG_SPEW
- printf ("Initial ix: %d\n", ix);
-#endif
-
- assert (ix > 0);
- assert (ix < n_stops);
- assert ((stops[ix-1].offset <= offset_fraction + EPSILON) ||
- ((stops[ix].offset > (1.0 - EPSILON)) && (offset_fraction < EPSILON /* == 0.0*/)));
- assert (offset_fraction <= stops[ix].offset);
- /* FIXME: These asserts may be broken, it is for now
- safer to not use them. Should be fixed!
- See bug #121850
- assert ((offset_fraction != stops[ix-1].offset) ||
- (d_offset >= 0.0));
- assert ((offset_fraction != stops[ix].offset) ||
- (d_offset <= 0.0));
- */
-
- while (width > 0)
- {
-#ifdef DEBUG_SPEW
- printf ("ix: %d\n", ix);
- printf ("start offset: %f\n", offset);
-#endif
- calc_color_at (stops, n_stops,
- spread,
- offset,
- offset_fraction,
- (d_offset > -EPSILON),
- ix,
- color1);
-
- if (d_offset > 0)
- next_stop = ix;
- else
- next_stop = ix-1;
-
-#ifdef DEBUG_SPEW
- printf ("next_stop: %d\n", next_stop);
-#endif
- if (fabs (d_offset) > EPSILON)
- {
- double o;
- o = offset_fraction;
-
- if ((fabs (o) <= EPSILON) && (ix == n_stops - 1))
- o = 1.0;
- else if ((fabs (o-1.0) <= EPSILON) && (ix == 1))
- o = 0.0;
-
-#ifdef DEBUG_SPEW
- printf ("o: %f\n", o);
-#endif
- len = (int)floor (fabs ((stops[next_stop].offset - o) / d_offset)) + 1;
- len = MAX (len, 0);
- len = MIN (len, width);
- }
- else
- {
- len = width;
- }
-#ifdef DEBUG_SPEW
- printf ("len: %d\n", len);
-#endif
- if (len > 0)
- {
- offset = offset + (len-1) * d_offset;
- offset_fraction = offset - floor (offset);
-#ifdef DEBUG_SPEW
- printf ("end offset: %f, fraction: %f\n", offset, offset_fraction);
-#endif
- calc_color_at (stops, n_stops,
- spread,
- offset,
- offset_fraction,
- (d_offset < EPSILON),
- ix,
- color2);
-
- art_rgba_gradient_run (bufp,
- color1,
- color2,
- len);
- offset += d_offset;
- offset_fraction = offset - floor (offset);
- }
-
- if (d_offset > 0)
- {
- do
- {
- ix++;
- if (ix == n_stops)
- ix = 1;
- /* Note: offset_fraction can actually be one here on x86 machines that
- does calculations with extended precision, but later rounds to 64bit.
- This happens if the 80bit offset_fraction is larger than the
- largest 64bit double that is less than one.
- */
- }
- while (!((stops[ix-1].offset <= offset_fraction &&
- offset_fraction < stops[ix].offset) ||
- (ix == 1 && offset_fraction > (1.0 - EPSILON))));
- }
- else
- {
- do
- {
- ix--;
- if (ix == 0)
- ix = n_stops - 1;
- }
- while (!((stops[ix-1].offset < offset_fraction &&
- offset_fraction <= stops[ix].offset) ||
- (ix == n_stops - 1 && offset_fraction < EPSILON /* == 0.0*/)));
- }
-
- bufp += 4*len;
- width -= len;
- }
-}
-
-
-/**
- * art_render_gradient_setpix: Set a gradient pixel.
- * @render: The render object.
- * @dst: Pointer to destination (where to store pixel).
- * @n_stops: Number of stops in @stops.
- * @stops: The stops for the gradient.
- * @offset: The offset.
- *
- * @n_stops must be > 0.
- *
- * Sets a gradient pixel, storing it at @dst.
- **/
-static void
-art_render_gradient_setpix (ArtRender *render,
- art_u8 *dst,
- int n_stops, ArtGradientStop *stops,
- double offset)
-{
- int ix;
- int j;
- double off0, off1;
- int n_ch = render->n_chan + 1;
-
- for (ix = 0; ix < n_stops; ix++)
- if (stops[ix].offset > offset)
- break;
- /* stops[ix - 1].offset < offset < stops[ix].offset */
- if (ix > 0 && ix < n_stops)
- {
- off0 = stops[ix - 1].offset;
- off1 = stops[ix].offset;
- if (fabs (off1 - off0) > EPSILON)
- {
- double interp;
-
- interp = (offset - off0) / (off1 - off0);
- for (j = 0; j < n_ch; j++)
- {
- int z0, z1;
- int z;
- z0 = stops[ix - 1].color[j];
- z1 = stops[ix].color[j];
- z = floor (z0 + (z1 - z0) * interp + 0.5);
- if (render->buf_depth == 8)
- dst[j] = ART_PIX_8_FROM_MAX (z);
- else /* (render->buf_depth == 16) */
- ((art_u16 *)dst)[j] = z;
- }
- return;
- }
- }
- else if (ix == n_stops)
- ix--;
-
- for (j = 0; j < n_ch; j++)
- {
- int z;
- z = stops[ix].color[j];
- if (render->buf_depth == 8)
- dst[j] = ART_PIX_8_FROM_MAX (z);
- else /* (render->buf_depth == 16) */
- ((art_u16 *)dst)[j] = z;
- }
-}
-
-static void
-art_render_gradient_linear_done (ArtRenderCallback *self, ArtRender *render)
-{
- art_free (self);
-}
-
-static void
-art_render_gradient_linear_render (ArtRenderCallback *self, ArtRender *render,
- art_u8 *dest, int y)
-{
- ArtImageSourceGradLin *z = (ArtImageSourceGradLin *)self;
- const ArtGradientLinear *gradient = &(z->gradient);
- int pixstride = (render->n_chan + 1) * (render->depth >> 3);
- int x;
- int width = render->x1 - render->x0;
- double offset, d_offset;
- double actual_offset;
- int n_stops = gradient->n_stops;
- ArtGradientStop *stops = gradient->stops;
- art_u8 *bufp = render->image_buf;
- ArtGradientSpread spread = gradient->spread;
-
- offset = render->x0 * gradient->a + y * gradient->b + gradient->c;
- d_offset = gradient->a;
-
- for (x = 0; x < width; x++)
- {
- if (spread == ART_GRADIENT_PAD)
- actual_offset = offset;
- else if (spread == ART_GRADIENT_REPEAT)
- actual_offset = offset - floor (offset);
- else /* (spread == ART_GRADIENT_REFLECT) */
- {
- double tmp;
-
- tmp = offset - 2 * floor (0.5 * offset);
- actual_offset = tmp > 1 ? 2 - tmp : tmp;
- }
- art_render_gradient_setpix (render, bufp, n_stops, stops, actual_offset);
- offset += d_offset;
- bufp += pixstride;
- }
-}
-
-static void
-art_render_gradient_linear_negotiate (ArtImageSource *self, ArtRender *render,
- ArtImageSourceFlags *p_flags,
- int *p_buf_depth, ArtAlphaType *p_alpha)
-{
- if (render->depth == 8 &&
- render->n_chan == 3)
- {
- self->super.render = art_render_gradient_linear_render_8;
- *p_flags = 0;
- *p_buf_depth = 8;
- *p_alpha = ART_ALPHA_PREMUL;
- return;
- }
-
- self->super.render = art_render_gradient_linear_render;
- *p_flags = 0;
- *p_buf_depth = render->depth;
- *p_alpha = ART_ALPHA_PREMUL;
-}
-
-/**
- * art_render_gradient_linear: Add a linear gradient image source.
- * @render: The render object.
- * @gradient: The linear gradient.
- *
- * Adds the linear gradient @gradient as the image source for rendering
- * in the render object @render.
- **/
-void
-art_render_gradient_linear (ArtRender *render,
- const ArtGradientLinear *gradient,
- ArtFilterLevel level)
-{
- ArtImageSourceGradLin *image_source = art_alloc (sizeof (ArtImageSourceGradLin) +
- sizeof (ArtGradientStop) * (gradient->n_stops - 1));
-
- image_source->super.super.render = NULL;
- image_source->super.super.done = art_render_gradient_linear_done;
- image_source->super.negotiate = art_render_gradient_linear_negotiate;
-
- /* copy the gradient into the structure */
- image_source->gradient = *gradient;
- image_source->gradient.stops = image_source->stops;
- memcpy (image_source->gradient.stops, gradient->stops, sizeof (ArtGradientStop) * gradient->n_stops);
-
- art_render_add_image_source (render, &image_source->super);
-}
-
-static void
-art_render_gradient_radial_done (ArtRenderCallback *self, ArtRender *render)
-{
- art_free (self);
-}
-
-static void
-art_render_gradient_radial_render (ArtRenderCallback *self, ArtRender *render,
- art_u8 *dest, int y)
-{
- ArtImageSourceGradRad *z = (ArtImageSourceGradRad *)self;
- const ArtGradientRadial *gradient = &(z->gradient);
- int pixstride = (render->n_chan + 1) * (render->depth >> 3);
- int x;
- int x0 = render->x0;
- int width = render->x1 - x0;
- int n_stops = gradient->n_stops;
- ArtGradientStop *stops = gradient->stops;
- art_u8 *bufp = render->image_buf;
- double fx = gradient->fx;
- double fy = gradient->fy;
- double dx, dy;
- const double *affine = gradient->affine;
- double aff0 = affine[0];
- double aff1 = affine[1];
- const double a = z->a;
- const double arecip = 1.0 / a;
- double b, db;
- double c, dc, ddc;
- double b_a, db_a;
- double rad, drad, ddrad;
-
- dx = x0 * aff0 + y * affine[2] + affine[4] - fx;
- dy = x0 * aff1 + y * affine[3] + affine[5] - fy;
- b = dx * fx + dy * fy;
- db = aff0 * fx + aff1 * fy;
- c = dx * dx + dy * dy;
- dc = 2 * aff0 * dx + aff0 * aff0 + 2 * aff1 * dy + aff1 * aff1;
- ddc = 2 * aff0 * aff0 + 2 * aff1 * aff1;
-
- b_a = b * arecip;
- db_a = db * arecip;
-
- rad = b_a * b_a + c * arecip;
- drad = 2 * b_a * db_a + db_a * db_a + dc * arecip;
- ddrad = 2 * db_a * db_a + ddc * arecip;
-
- for (x = 0; x < width; x++)
- {
- double z;
-
- if (rad > 0)
- z = b_a + sqrt (rad);
- else
- z = b_a;
- art_render_gradient_setpix (render, bufp, n_stops, stops, z);
- bufp += pixstride;
- b_a += db_a;
- rad += drad;
- drad += ddrad;
- }
-}
-
-static void
-art_render_gradient_radial_negotiate (ArtImageSource *self, ArtRender *render,
- ArtImageSourceFlags *p_flags,
- int *p_buf_depth, ArtAlphaType *p_alpha)
-{
- self->super.render = art_render_gradient_radial_render;
- *p_flags = 0;
- *p_buf_depth = render->depth;
- *p_alpha = ART_ALPHA_PREMUL;
-}
-
-/**
- * art_render_gradient_radial: Add a radial gradient image source.
- * @render: The render object.
- * @gradient: The radial gradient.
- *
- * Adds the radial gradient @gradient as the image source for rendering
- * in the render object @render.
- **/
-void
-art_render_gradient_radial (ArtRender *render,
- const ArtGradientRadial *gradient,
- ArtFilterLevel level)
-{
- ArtImageSourceGradRad *image_source = art_alloc (sizeof (ArtImageSourceGradRad) +
- sizeof (ArtGradientStop) * (gradient->n_stops - 1));
- double fx = gradient->fx;
- double fy = gradient->fy;
-
- image_source->super.super.render = NULL;
- image_source->super.super.done = art_render_gradient_radial_done;
- image_source->super.negotiate = art_render_gradient_radial_negotiate;
-
- /* copy the gradient into the structure */
- image_source->gradient = *gradient;
- image_source->gradient.stops = image_source->stops;
- memcpy (image_source->gradient.stops, gradient->stops, sizeof (ArtGradientStop) * gradient->n_stops);
-
- /* todo: sanitycheck fx, fy? */
- image_source->a = 1 - fx * fx - fy * fy;
-
- art_render_add_image_source (render, &image_source->super);
-}
diff --git a/libart_lgpl/art_render_gradient.h b/libart_lgpl/art_render_gradient.h
deleted file mode 100644
index ff539033f1..0000000000
--- a/libart_lgpl/art_render_gradient.h
+++ /dev/null
@@ -1,81 +0,0 @@
-/*
- * art_render_gradient.h: Gradient image source for modular rendering.
- *
- * Libart_LGPL - library of basic graphic primitives
- * Copyright (C) 2000 Raph Levien
- *
- * This library 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 library 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 library; if not, write to the
- * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- *
- * Authors: Raph Levien <raph@acm.org>
- * Alexander Larsson <alla@lysator.liu.se>
- */
-
-#ifndef __ART_RENDER_GRADIENT_H__
-#define __ART_RENDER_GRADIENT_H__
-
-#include <libart_lgpl/art_filterlevel.h>
-#include <libart_lgpl/art_render.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif /* __cplusplus */
-
-typedef struct _ArtGradientLinear ArtGradientLinear;
-typedef struct _ArtGradientRadial ArtGradientRadial;
-typedef struct _ArtGradientStop ArtGradientStop;
-
-typedef enum {
- ART_GRADIENT_PAD,
- ART_GRADIENT_REFLECT,
- ART_GRADIENT_REPEAT
-} ArtGradientSpread;
-
-struct _ArtGradientLinear {
- double a;
- double b;
- double c;
- ArtGradientSpread spread;
- int n_stops;
- ArtGradientStop *stops;
-};
-
-struct _ArtGradientRadial {
- double affine[6]; /* transforms user coordinates to unit circle */
- double fx, fy; /* focal point in unit circle coords */
- int n_stops;
- ArtGradientStop *stops;
-};
-
-struct _ArtGradientStop {
- double offset;
- ArtPixMaxDepth color[ART_MAX_CHAN + 1];
-};
-
-void
-art_render_gradient_linear (ArtRender *render,
- const ArtGradientLinear *gradient,
- ArtFilterLevel level);
-
-void
-art_render_gradient_radial (ArtRender *render,
- const ArtGradientRadial *gradient,
- ArtFilterLevel level);
-
-#ifdef __cplusplus
-}
-#endif /* __cplusplus */
-
-#endif /* __ART_RENDER_GRADIENT_H__ */
diff --git a/libart_lgpl/art_render_mask.c b/libart_lgpl/art_render_mask.c
deleted file mode 100644
index ce82608dcd..0000000000
--- a/libart_lgpl/art_render_mask.c
+++ /dev/null
@@ -1,168 +0,0 @@
-/*
- * art_render_mask.c: Alpha mask source for modular rendering.
- *
- * Libart_LGPL - library of basic graphic primitives
- * Copyright (C) 2000 Raph Levien
- *
- * This library 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 library 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 library; if not, write to the
- * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- *
- * Authors: Raph Levien <raph@acm.org>
- */
-
-#include "config.h"
-#include "art_render_mask.h"
-
-#include <string.h>
-
-
-typedef struct _ArtMaskSourceMask ArtMaskSourceMask;
-
-struct _ArtMaskSourceMask {
- ArtMaskSource super;
- ArtRender *render;
- art_boolean first;
- int x0;
- int y0;
- int x1;
- int y1;
- const art_u8 *mask_buf;
- int rowstride;
-};
-
-static void
-art_render_mask_done (ArtRenderCallback *self, ArtRender *render)
-{
- art_free (self);
-}
-
-static int
-art_render_mask_can_drive (ArtMaskSource *self, ArtRender *render)
-{
- return 0;
-}
-
-static void
-art_render_mask_render (ArtRenderCallback *self, ArtRender *render,
- art_u8 *dest, int y)
-{
- ArtMaskSourceMask *z = (ArtMaskSourceMask *)self;
- int x0 = render->x0, x1 = render->x1;
- int z_x0 = z->x0, z_x1 = z->x1;
- int width = x1 - x0;
- int z_width = z_x1 - z_x0;
- art_u8 *alpha_buf = render->alpha_buf;
-
- if (y < z->y0 || y >= z->y1 || z_width <= 0)
- memset (alpha_buf, 0, width);
- else
- {
- const art_u8 *src_line = z->mask_buf + (y - z->y0) * z->rowstride;
- art_u8 *dst_line = alpha_buf + z_x0 - x0;
-
- if (z_x0 > x0)
- memset (alpha_buf, 0, z_x0 - x0);
-
- if (z->first)
- memcpy (dst_line, src_line, z_width);
- else
- {
- int x;
-
- for (x = 0; x < z_width; x++)
- {
- int v;
- v = src_line[x];
- if (v)
- {
- v = v * dst_line[x] + 0x80;
- v = (v + (v >> 8)) >> 8;
- dst_line[x] = v;
- }
- else
- {
- dst_line[x] = 0;
- }
- }
- }
-
- if (z_x1 < x1)
- memset (alpha_buf + z_x1 - x0, 0, x1 - z_x1);
- }
-}
-
-static void
-art_render_mask_prepare (ArtMaskSource *self, ArtRender *render,
- art_boolean first)
-{
- ArtMaskSourceMask *z = (ArtMaskSourceMask *)self;
- self->super.render = art_render_mask_render;
- z->first = first;
-}
-
-/**
- * art_render_mask: Use an alpha buffer as a render mask source.
- * @render: Render object.
- * @x0: Left coordinate of mask rect.
- * @y0: Top coordinate of mask rect.
- * @x1: Right coordinate of mask rect.
- * @y1: Bottom coordinate of mask rect.
- * @mask_buf: Buffer containing 8bpp alpha mask data.
- * @rowstride: Rowstride of @mask_buf.
- *
- * Adds @mask_buf to the render object as a mask. Note: @mask_buf must
- * remain allocated until art_render_invoke() is called on @render.
- **/
-void
-art_render_mask (ArtRender *render,
- int x0, int y0, int x1, int y1,
- const art_u8 *mask_buf, int rowstride)
-{
- ArtMaskSourceMask *mask_source;
-
- if (x0 < render->x0)
- {
- mask_buf += render->x0 - x0;
- x0 = render->x0;
- }
- if (x1 > render->x1)
- x1 = render->x1;
-
- if (y0 < render->y0)
- {
- mask_buf += (render->y0 - y0) * rowstride;
- y0 = render->y0;
- }
- if (y1 > render->y1)
- y1 = render->y1;
-
- mask_source = art_new (ArtMaskSourceMask, 1);
-
- mask_source->super.super.render = NULL;
- mask_source->super.super.done = art_render_mask_done;
- mask_source->super.can_drive = art_render_mask_can_drive;
- mask_source->super.invoke_driver = NULL;
- mask_source->super.prepare = art_render_mask_prepare;
- mask_source->render = render;
- mask_source->x0 = x0;
- mask_source->y0 = y0;
- mask_source->x1 = x1;
- mask_source->y1 = y1;
- mask_source->mask_buf = mask_buf;
- mask_source->rowstride = rowstride;
-
- art_render_add_mask_source (render, &mask_source->super);
-
-}
diff --git a/libart_lgpl/art_render_mask.h b/libart_lgpl/art_render_mask.h
deleted file mode 100644
index ef126e8042..0000000000
--- a/libart_lgpl/art_render_mask.h
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * art_render_mask.h: Alpha mask source for modular rendering.
- *
- * Libart_LGPL - library of basic graphic primitives
- * Copyright (C) 2000 Raph Levien
- *
- * This library 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 library 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 library; if not, write to the
- * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- *
- * Authors: Raph Levien <raph@acm.org>
- */
-
-#ifndef __ART_RENDER_MASK_H__
-#define __ART_RENDER_MASK_H__
-
-#include <libart_lgpl/art_render.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif /* __cplusplus */
-
-void
-art_render_mask (ArtRender *render,
- int x0, int y0, int x1, int y1,
- const art_u8 *mask_buf, int rowstride);
-
-#ifdef __cplusplus
-}
-#endif /* __cplusplus */
-
-#endif /* __ART_RENDER_MASK_H__ */
diff --git a/libart_lgpl/art_render_svp.c b/libart_lgpl/art_render_svp.c
deleted file mode 100644
index af75b7718e..0000000000
--- a/libart_lgpl/art_render_svp.c
+++ /dev/null
@@ -1,421 +0,0 @@
-/*
- * art_render_gradient.c: SVP mask source for modular rendering.
- *
- * Libart_LGPL - library of basic graphic primitives
- * Copyright (C) 2000 Raph Levien
- *
- * This library 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 library 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 library; if not, write to the
- * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- *
- * Authors: Raph Levien <raph@acm.org>
- */
-
-#include "art_render_svp.h"
-#include "art_svp_render_aa.h"
-
-typedef struct _ArtMaskSourceSVP ArtMaskSourceSVP;
-
-struct _ArtMaskSourceSVP {
- ArtMaskSource super;
- ArtRender *render;
- const ArtSVP *svp;
- art_u8 *dest_ptr;
-};
-
-static void
-art_render_svp_done (ArtRenderCallback *self, ArtRender *render)
-{
- art_free (self);
-}
-
-static int
-art_render_svp_can_drive (ArtMaskSource *self, ArtRender *render)
-{
- return 10;
-}
-
-/* The basic art_render_svp_callback function is repeated four times,
- for all combinations of non-unit opacity and generating spans. In
- general, I'd consider this bad style, but in this case I plead
- a measurable performance improvement. */
-
-static void
-art_render_svp_callback (void *callback_data, int y,
- int start, ArtSVPRenderAAStep *steps, int n_steps)
-{
- ArtMaskSourceSVP *z = (ArtMaskSourceSVP *)callback_data;
- ArtRender *render = z->render;
- int n_run = 0;
- int i;
- int running_sum = start;
- int x0 = render->x0;
- int x1 = render->x1;
- int run_x0, run_x1;
- ArtRenderMaskRun *run = render->run;
-
- if (n_steps > 0)
- {
- run_x1 = steps[0].x;
- if (run_x1 > x0 && running_sum > 0x80ff)
- {
- run[0].x = x0;
- run[0].alpha = running_sum;
- n_run++;
- }
-
- for (i = 0; i < n_steps - 1; i++)
- {
- running_sum += steps[i].delta;
- run_x0 = run_x1;
- run_x1 = steps[i + 1].x;
- if (run_x1 > run_x0)
- {
- run[n_run].x = run_x0;
- run[n_run].alpha = running_sum;
- n_run++;
- }
- }
- if (x1 > run_x1)
- {
- running_sum += steps[n_steps - 1].delta;
- run[n_run].x = run_x1;
- run[n_run].alpha = running_sum;
- n_run++;
- }
- if (running_sum > 0x80ff)
- {
- run[n_run].x = x1;
- run[n_run].alpha = 0x8000;
- n_run++;
- }
- }
- else if ((running_sum >> 16) > 0)
- {
- run[0].x = x0;
- run[0].alpha = running_sum;
- run[1].x = x1;
- run[1].alpha = running_sum;
- n_run = 2;
- }
-
- render->n_run = n_run;
-
- art_render_invoke_callbacks (render, z->dest_ptr, y);
-
- z->dest_ptr += render->rowstride;
-}
-
-static void
-art_render_svp_callback_span (void *callback_data, int y,
- int start, ArtSVPRenderAAStep *steps, int n_steps)
-{
- ArtMaskSourceSVP *z = (ArtMaskSourceSVP *)callback_data;
- ArtRender *render = z->render;
- int n_run = 0;
- int n_span = 0;
- int i;
- int running_sum = start;
- int x0 = render->x0;
- int x1 = render->x1;
- int run_x0, run_x1;
- ArtRenderMaskRun *run = render->run;
- int *span_x = render->span_x;
-
- if (n_steps > 0)
- {
- run_x1 = steps[0].x;
- if (run_x1 > x0 && running_sum > 0x80ff)
- {
- run[0].x = x0;
- run[0].alpha = running_sum;
- n_run++;
- span_x[0] = x0;
- n_span++;
- }
-
- for (i = 0; i < n_steps - 1; i++)
- {
- running_sum += steps[i].delta;
- run_x0 = run_x1;
- run_x1 = steps[i + 1].x;
- if (run_x1 > run_x0)
- {
- run[n_run].x = run_x0;
- run[n_run].alpha = running_sum;
- n_run++;
- if ((n_span & 1) != (running_sum > 0x80ff))
- span_x[n_span++] = run_x0;
- }
- }
- if (x1 > run_x1)
- {
- running_sum += steps[n_steps - 1].delta;
- run[n_run].x = run_x1;
- run[n_run].alpha = running_sum;
- n_run++;
- if ((n_span & 1) != (running_sum > 0x80ff))
- span_x[n_span++] = run_x1;
- }
- if (running_sum > 0x80ff)
- {
- run[n_run].x = x1;
- run[n_run].alpha = 0x8000;
- n_run++;
- span_x[n_span++] = x1;
- }
- }
- else if ((running_sum >> 16) > 0)
- {
- run[0].x = x0;
- run[0].alpha = running_sum;
- run[1].x = x1;
- run[1].alpha = running_sum;
- n_run = 2;
- span_x[0] = x0;
- span_x[1] = x1;
- n_span = 2;
- }
-
- render->n_run = n_run;
- render->n_span = n_span;
-
- art_render_invoke_callbacks (render, z->dest_ptr, y);
-
- z->dest_ptr += render->rowstride;
-}
-
-static void
-art_render_svp_callback_opacity (void *callback_data, int y,
- int start, ArtSVPRenderAAStep *steps, int n_steps)
-{
- ArtMaskSourceSVP *z = (ArtMaskSourceSVP *)callback_data;
- ArtRender *render = z->render;
- int n_run = 0;
- int i;
- art_u32 running_sum;
- int x0 = render->x0;
- int x1 = render->x1;
- int run_x0, run_x1;
- ArtRenderMaskRun *run = render->run;
- art_u32 opacity = render->opacity;
- art_u32 alpha;
-
- running_sum = start - 0x7f80;
-
- if (n_steps > 0)
- {
- run_x1 = steps[0].x;
- alpha = ((running_sum >> 8) * opacity + 0x80080) >> 8;
- if (run_x1 > x0 && alpha > 0x80ff)
- {
- run[0].x = x0;
- run[0].alpha = alpha;
- n_run++;
- }
-
- for (i = 0; i < n_steps - 1; i++)
- {
- running_sum += steps[i].delta;
- run_x0 = run_x1;
- run_x1 = steps[i + 1].x;
- if (run_x1 > run_x0)
- {
- run[n_run].x = run_x0;
- alpha = ((running_sum >> 8) * opacity + 0x80080) >> 8;
- run[n_run].alpha = alpha;
- n_run++;
- }
- }
- if (x1 > run_x1)
- {
- running_sum += steps[n_steps - 1].delta;
- run[n_run].x = run_x1;
- alpha = ((running_sum >> 8) * opacity + 0x80080) >> 8;
- run[n_run].alpha = alpha;
- n_run++;
- }
- if (alpha > 0x80ff)
- {
- run[n_run].x = x1;
- run[n_run].alpha = 0x8000;
- n_run++;
- }
- }
- else if ((running_sum >> 16) > 0)
- {
- run[0].x = x0;
- run[0].alpha = running_sum;
- run[1].x = x1;
- run[1].alpha = running_sum;
- n_run = 2;
- }
-
- render->n_run = n_run;
-
- art_render_invoke_callbacks (render, z->dest_ptr, y);
-
- z->dest_ptr += render->rowstride;
-}
-
-static void
-art_render_svp_callback_opacity_span (void *callback_data, int y,
- int start, ArtSVPRenderAAStep *steps, int n_steps)
-{
- ArtMaskSourceSVP *z = (ArtMaskSourceSVP *)callback_data;
- ArtRender *render = z->render;
- int n_run = 0;
- int n_span = 0;
- int i;
- art_u32 running_sum;
- int x0 = render->x0;
- int x1 = render->x1;
- int run_x0, run_x1;
- ArtRenderMaskRun *run = render->run;
- int *span_x = render->span_x;
- art_u32 opacity = render->opacity;
- art_u32 alpha;
-
- running_sum = start - 0x7f80;
-
- if (n_steps > 0)
- {
- run_x1 = steps[0].x;
- alpha = ((running_sum >> 8) * opacity + 0x800080) >> 8;
- if (run_x1 > x0 && alpha > 0x80ff)
- {
- run[0].x = x0;
- run[0].alpha = alpha;
- n_run++;
- span_x[0] = x0;
- n_span++;
- }
-
- for (i = 0; i < n_steps - 1; i++)
- {
- running_sum += steps[i].delta;
- run_x0 = run_x1;
- run_x1 = steps[i + 1].x;
- if (run_x1 > run_x0)
- {
- run[n_run].x = run_x0;
- alpha = ((running_sum >> 8) * opacity + 0x800080) >> 8;
- run[n_run].alpha = alpha;
- n_run++;
- if ((n_span & 1) != (alpha > 0x80ff))
- span_x[n_span++] = run_x0;
- }
- }
- if (x1 > run_x1)
- {
- running_sum += steps[n_steps - 1].delta;
- run[n_run].x = run_x1;
- alpha = ((running_sum >> 8) * opacity + 0x800080) >> 8;
- run[n_run].alpha = alpha;
- n_run++;
- if ((n_span & 1) != (alpha > 0x80ff))
- span_x[n_span++] = run_x1;
- }
- if (alpha > 0x80ff)
- {
- run[n_run].x = x1;
- run[n_run].alpha = 0x8000;
- n_run++;
- span_x[n_span++] = x1;
- }
- }
- else if ((running_sum >> 16) > 0)
- {
- run[0].x = x0;
- run[0].alpha = running_sum;
- run[1].x = x1;
- run[1].alpha = running_sum;
- n_run = 2;
- span_x[0] = x0;
- span_x[1] = x1;
- n_span = 2;
- }
-
- render->n_run = n_run;
- render->n_span = n_span;
-
- art_render_invoke_callbacks (render, z->dest_ptr, y);
-
- z->dest_ptr += render->rowstride;
-}
-
-static void
-art_render_svp_invoke_driver (ArtMaskSource *self, ArtRender *render)
-{
- ArtMaskSourceSVP *z = (ArtMaskSourceSVP *)self;
- void (*callback) (void *callback_data,
- int y,
- int start,
- ArtSVPRenderAAStep *steps, int n_steps);
-
- z->dest_ptr = render->pixels;
- if (render->opacity == 0x10000)
- {
- if (render->need_span)
- callback = art_render_svp_callback_span;
- else
- callback = art_render_svp_callback;
- }
- else
- {
- if (render->need_span)
- callback = art_render_svp_callback_opacity_span;
- else
- callback = art_render_svp_callback_opacity;
- }
-
- art_svp_render_aa (z->svp,
- render->x0, render->y0,
- render->x1, render->y1, callback,
- self);
- art_render_svp_done (&self->super, render);
-}
-
-G_GNUC_NORETURN static void
-art_render_svp_prepare (ArtMaskSource *self, ArtRender *render,
- art_boolean first)
-{
- /* todo */
- art_die ("art_render_svp non-driver mode not yet implemented.\n");
-}
-
-/**
- * art_render_svp: Use an SVP as a render mask source.
- * @render: Render object.
- * @svp: SVP.
- *
- * Adds @svp to the render object as a mask. Note: @svp must remain
- * allocated until art_render_invoke() is called on @render.
- **/
-void
-art_render_svp (ArtRender *render, const ArtSVP *svp)
-{
- ArtMaskSourceSVP *mask_source;
- mask_source = art_new (ArtMaskSourceSVP, 1);
-
- mask_source->super.super.render = NULL;
- mask_source->super.super.done = art_render_svp_done;
- mask_source->super.can_drive = art_render_svp_can_drive;
- mask_source->super.invoke_driver = art_render_svp_invoke_driver;
- mask_source->super.prepare = art_render_svp_prepare;
- mask_source->render = render;
- mask_source->svp = svp;
-
- art_render_add_mask_source (render, &mask_source->super);
-}
diff --git a/libart_lgpl/art_render_svp.h b/libart_lgpl/art_render_svp.h
deleted file mode 100644
index edb1f92374..0000000000
--- a/libart_lgpl/art_render_svp.h
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- * art_render_svp.h: SVP mask source for modular rendering.
- *
- * Libart_LGPL - library of basic graphic primitives
- * Copyright (C) 2000 Raph Levien
- *
- * This library 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 library 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 library; if not, write to the
- * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- *
- * Authors: Raph Levien <raph@acm.org>
- */
-
-#ifndef __ART_RENDER_SVP_H__
-#define __ART_RENDER_SVP_H__
-
-#include <libart_lgpl/art_render.h>
-#include <libart_lgpl/art_svp.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif /* __cplusplus */
-
-void
-art_render_svp (ArtRender *render, const ArtSVP *svp);
-
-#ifdef __cplusplus
-}
-#endif /* __cplusplus */
-
-#endif /* __ART_RENDER_SVP_H__ */
diff --git a/libart_lgpl/art_rgb_a_affine.c b/libart_lgpl/art_rgb_a_affine.c
deleted file mode 100644
index ff38e2a5eb..0000000000
--- a/libart_lgpl/art_rgb_a_affine.c
+++ /dev/null
@@ -1,149 +0,0 @@
-/* Libart_LGPL - library of basic graphic primitives
- * Copyright (C) 1998 Raph Levien
- *
- * This library 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 library 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 library; if not, write to the
- * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- */
-
-#include "config.h"
-#include "art_rgb_a_affine.h"
-
-#include <math.h>
-
-#include "art_affine.h"
-#include "art_point.h"
-#include "art_rgb_affine_private.h"
-
-/* This module handles compositing of affine-transformed alpha only images
- over rgb pixel buffers. */
-
-/* Composite the source image over the destination image, applying the
- affine transform. */
-
-/**
- * art_rgb_a_affine: Affine transform source Alpha image and composite.
- * @dst: Destination image RGB buffer.
- * @x0: Left coordinate of destination rectangle.
- * @y0: Top coordinate of destination rectangle.
- * @x1: Right coordinate of destination rectangle.
- * @y1: Bottom coordinate of destination rectangle.
- * @dst_rowstride: Rowstride of @dst buffer.
- * @src: Source image alpha buffer.
- * @src_width: Width of source image.
- * @src_height: Height of source image.
- * @src_rowstride: Rowstride of @src buffer.
- * @rgb: RGB foreground color, in 0xRRGGBB.
- * @affine: Affine transform.
- * @level: Filter level.
- * @alphagamma: #ArtAlphaGamma for gamma-correcting the compositing.
- *
- * Affine transform the solid color rgb with alpha specified by the
- * source image stored in @src, compositing over the area of destination
- * image @dst specified by the rectangle (@x0, @y0) - (@x1, @y1).
- * As usual in libart, the left and top edges of this rectangle are
- * included, and the right and bottom edges are excluded.
- *
- * The @alphagamma parameter specifies that the alpha compositing be
- * done in a gamma-corrected color space. In the current
- * implementation, it is ignored.
- *
- * The @level parameter specifies the speed/quality tradeoff of the
- * image interpolation. Currently, only ART_FILTER_NEAREST is
- * implemented.
- **/
-void
-art_rgb_a_affine (art_u8 *dst,
- int x0, int y0, int x1, int y1, int dst_rowstride,
- const art_u8 *src,
- int src_width, int src_height, int src_rowstride,
- art_u32 rgb,
- const double affine[6],
- ArtFilterLevel level,
- ArtAlphaGamma *alphagamma)
-{
- /* Note: this is a slow implementation, and is missing all filter
- levels other than NEAREST. It is here for clarity of presentation
- and to establish the interface. */
- int x, y;
- double inv[6];
- art_u8 *dst_p, *dst_linestart;
- const art_u8 *src_p;
- ArtPoint pt, src_pt;
- int src_x, src_y;
- int alpha;
- art_u8 bg_r, bg_g, bg_b;
- art_u8 fg_r, fg_g, fg_b;
- int tmp;
- int run_x0, run_x1;
- art_u8 r, g, b;
-
- r = (rgb>>16)&0xff;
- g = (rgb>>8)&0xff;
- b = (rgb)&0xff;
-
- dst_linestart = dst;
- art_affine_invert (inv, affine);
- for (y = y0; y < y1; y++)
- {
- pt.y = y + 0.5;
- run_x0 = x0;
- run_x1 = x1;
- art_rgb_affine_run (&run_x0, &run_x1, y, src_width, src_height,
- inv);
- dst_p = dst_linestart + (run_x0 - x0) * 3;
- for (x = run_x0; x < run_x1; x++)
- {
- pt.x = x + 0.5;
- art_affine_point (&src_pt, &pt, inv);
- src_x = floor (src_pt.x);
- src_y = floor (src_pt.y);
- src_p = src + (src_y * src_rowstride) + src_x;
- if (src_x >= 0 && src_x < src_width &&
- src_y >= 0 && src_y < src_height)
- {
-
- alpha = *src_p;
- if (alpha)
- {
- if (alpha == 255)
- {
- dst_p[0] = r;
- dst_p[1] = g;
- dst_p[2] = b;
- }
- else
- {
- bg_r = dst_p[0];
- bg_g = dst_p[1];
- bg_b = dst_p[2];
-
- tmp = (r - bg_r) * alpha;
- fg_r = bg_r + ((tmp + (tmp >> 8) + 0x80) >> 8);
- tmp = (g - bg_g) * alpha;
- fg_g = bg_g + ((tmp + (tmp >> 8) + 0x80) >> 8);
- tmp = (b - bg_b) * alpha;
- fg_b = bg_b + ((tmp + (tmp >> 8) + 0x80) >> 8);
-
- dst_p[0] = fg_r;
- dst_p[1] = fg_g;
- dst_p[2] = fg_b;
- }
- }
- } else { dst_p[0] = 255; dst_p[1] = 0; dst_p[2] = 0; }
- dst_p += 3;
- }
- dst_linestart += dst_rowstride;
- }
-}
diff --git a/libart_lgpl/art_rgb_a_affine.h b/libart_lgpl/art_rgb_a_affine.h
deleted file mode 100644
index 756fcbaaee..0000000000
--- a/libart_lgpl/art_rgb_a_affine.h
+++ /dev/null
@@ -1,47 +0,0 @@
-/* Libart_LGPL - library of basic graphic primitives
- * Copyright (C) 1998 Raph Levien
- *
- * This library 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 library 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 library; if not, write to the
- * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- */
-
-#ifndef __ART_RGB_A_AFFINE_H__
-#define __ART_RGB_A_AFFINE_H__
-
-/* This module handles compositing of affine-transformed alpha only images
- over rgb pixel buffers. */
-
-#include <libart_lgpl/art_filterlevel.h>
-#include <libart_lgpl/art_alphagamma.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-void
-art_rgb_a_affine (art_u8 *dst,
- int x0, int y0, int x1, int y1, int dst_rowstride,
- const art_u8 *src,
- int src_width, int src_height, int src_rowstride,
- art_u32 rgb,
- const double affine[6],
- ArtFilterLevel level,
- ArtAlphaGamma *alphagamma);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif
diff --git a/libart_lgpl/art_rgb_bitmap_affine.c b/libart_lgpl/art_rgb_bitmap_affine.c
deleted file mode 100644
index 825f8b5638..0000000000
--- a/libart_lgpl/art_rgb_bitmap_affine.c
+++ /dev/null
@@ -1,198 +0,0 @@
-/* Libart_LGPL - library of basic graphic primitives
- * Copyright (C) 1998 Raph Levien
- *
- * This library 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 library 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 library; if not, write to the
- * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- */
-
-#include "config.h"
-#include "art_rgb_bitmap_affine.h"
-
-#include <math.h>
-#include "art_misc.h"
-#include "art_point.h"
-#include "art_affine.h"
-#include "art_rgb_affine_private.h"
-
-/* This module handles compositing of affine-transformed bitmap images
- over rgb pixel buffers. */
-
-/* Composite the source image over the destination image, applying the
- affine transform. Foreground color is given and assumed to be
- opaque, background color is assumed to be fully transparent. */
-
-static void
-art_rgb_bitmap_affine_opaque (art_u8 *dst,
- int x0, int y0, int x1, int y1,
- int dst_rowstride,
- const art_u8 *src,
- int src_width, int src_height, int src_rowstride,
- art_u32 rgb,
- const double affine[6],
- ArtFilterLevel level,
- ArtAlphaGamma *alphagamma)
-{
- /* Note: this is a slow implementation, and is missing all filter
- levels other than NEAREST. It is here for clarity of presentation
- and to establish the interface. */
- int x, y;
- double inv[6];
- art_u8 *dst_p, *dst_linestart;
- const art_u8 *src_p;
- ArtPoint pt, src_pt;
- int src_x, src_y;
- art_u8 r, g, b;
- int run_x0, run_x1;
-
- r = rgb >> 16;
- g = (rgb >> 8) & 0xff;
- b = rgb & 0xff;
- dst_linestart = dst;
- art_affine_invert (inv, affine);
- for (y = y0; y < y1; y++)
- {
- pt.y = y + 0.5;
- run_x0 = x0;
- run_x1 = x1;
- art_rgb_affine_run (&run_x0, &run_x1, y, src_width, src_height,
- inv);
- dst_p = dst_linestart + (run_x0 - x0) * 3;
- for (x = run_x0; x < run_x1; x++)
- {
- pt.x = x + 0.5;
- art_affine_point (&src_pt, &pt, inv);
- src_x = floor (src_pt.x);
- src_y = floor (src_pt.y);
- src_p = src + (src_y * src_rowstride) + (src_x >> 3);
- if (*src_p & (128 >> (src_x & 7)))
- {
- dst_p[0] = r;
- dst_p[1] = g;
- dst_p[2] = b;
- }
- dst_p += 3;
- }
- dst_linestart += dst_rowstride;
- }
-}
-/* Composite the source image over the destination image, applying the
- affine transform. Foreground color is given, background color is
- assumed to be fully transparent. */
-
-/**
- * art_rgb_bitmap_affine: Affine transform source bitmap image and composite.
- * @dst: Destination image RGB buffer.
- * @x0: Left coordinate of destination rectangle.
- * @y0: Top coordinate of destination rectangle.
- * @x1: Right coordinate of destination rectangle.
- * @y1: Bottom coordinate of destination rectangle.
- * @dst_rowstride: Rowstride of @dst buffer.
- * @src: Source image bitmap buffer.
- * @src_width: Width of source image.
- * @src_height: Height of source image.
- * @src_rowstride: Rowstride of @src buffer.
- * @rgba: RGBA foreground color, in 0xRRGGBBAA.
- * @affine: Affine transform.
- * @level: Filter level.
- * @alphagamma: #ArtAlphaGamma for gamma-correcting the compositing.
- *
- * Affine transform the source image stored in @src, compositing over
- * the area of destination image @dst specified by the rectangle
- * (@x0, @y0) - (@x1, @y1).
- *
- * The source bitmap stored with MSB as the leftmost pixel. Source 1
- * bits correspond to the semitransparent color @rgba, while source 0
- * bits are transparent.
- *
- * See art_rgb_affine() for a description of additional parameters.
- **/
-void
-art_rgb_bitmap_affine (art_u8 *dst,
- int x0, int y0, int x1, int y1, int dst_rowstride,
- const art_u8 *src,
- int src_width, int src_height, int src_rowstride,
- art_u32 rgba,
- const double affine[6],
- ArtFilterLevel level,
- ArtAlphaGamma *alphagamma)
-{
- /* Note: this is a slow implementation, and is missing all filter
- levels other than NEAREST. It is here for clarity of presentation
- and to establish the interface. */
- int x, y;
- double inv[6];
- art_u8 *dst_p, *dst_linestart;
- const art_u8 *src_p;
- ArtPoint pt, src_pt;
- int src_x, src_y;
- int alpha;
- art_u8 bg_r, bg_g, bg_b;
- art_u8 fg_r, fg_g, fg_b;
- art_u8 r, g, b;
- int run_x0, run_x1;
-
- alpha = rgba & 0xff;
- if (alpha == 0xff)
- {
- art_rgb_bitmap_affine_opaque (dst, x0, y0, x1, y1, dst_rowstride,
- src,
- src_width, src_height, src_rowstride,
- rgba >> 8,
- affine,
- level,
- alphagamma);
- return;
- }
- /* alpha = (65536 * alpha) / 255; */
- alpha = (alpha << 8) + alpha + (alpha >> 7);
- r = rgba >> 24;
- g = (rgba >> 16) & 0xff;
- b = (rgba >> 8) & 0xff;
- dst_linestart = dst;
- art_affine_invert (inv, affine);
- for (y = y0; y < y1; y++)
- {
- pt.y = y + 0.5;
- run_x0 = x0;
- run_x1 = x1;
- art_rgb_affine_run (&run_x0, &run_x1, y, src_width, src_height,
- inv);
- dst_p = dst_linestart + (run_x0 - x0) * 3;
- for (x = run_x0; x < run_x1; x++)
- {
- pt.x = x + 0.5;
- art_affine_point (&src_pt, &pt, inv);
- src_x = floor (src_pt.x);
- src_y = floor (src_pt.y);
- src_p = src + (src_y * src_rowstride) + (src_x >> 3);
- if (*src_p & (128 >> (src_x & 7)))
- {
- bg_r = dst_p[0];
- bg_g = dst_p[1];
- bg_b = dst_p[2];
-
- fg_r = bg_r + (((r - bg_r) * alpha + 0x8000) >> 16);
- fg_g = bg_g + (((g - bg_g) * alpha + 0x8000) >> 16);
- fg_b = bg_b + (((b - bg_b) * alpha + 0x8000) >> 16);
-
- dst_p[0] = fg_r;
- dst_p[1] = fg_g;
- dst_p[2] = fg_b;
- }
- dst_p += 3;
- }
- dst_linestart += dst_rowstride;
- }
-}
diff --git a/libart_lgpl/art_rgb_bitmap_affine.h b/libart_lgpl/art_rgb_bitmap_affine.h
deleted file mode 100644
index 6c7d21d648..0000000000
--- a/libart_lgpl/art_rgb_bitmap_affine.h
+++ /dev/null
@@ -1,47 +0,0 @@
-/* Libart_LGPL - library of basic graphic primitives
- * Copyright (C) 1998 Raph Levien
- *
- * This library 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 library 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 library; if not, write to the
- * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- */
-
-#ifndef __ART_RGB_BITMAP_AFFINE_H__
-#define __ART_RGB_BITMAP_AFFINE_H__
-
-/* This module handles compositing of affine-transformed bitmap images
- over rgb pixel buffers. */
-
-#include <libart_lgpl/art_filterlevel.h>
-#include <libart_lgpl/art_alphagamma.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-void
-art_rgb_bitmap_affine (art_u8 *dst,
- int x0, int y0, int x1, int y1, int dst_rowstride,
- const art_u8 *src,
- int src_width, int src_height, int src_rowstride,
- art_u32 rgba,
- const double affine[6],
- ArtFilterLevel level,
- ArtAlphaGamma *alphagamma);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif
diff --git a/libart_lgpl/art_rgb_pixbuf_affine.c b/libart_lgpl/art_rgb_pixbuf_affine.c
deleted file mode 100644
index 0a25b575db..0000000000
--- a/libart_lgpl/art_rgb_pixbuf_affine.c
+++ /dev/null
@@ -1,104 +0,0 @@
-/* Libart_LGPL - library of basic graphic primitives
- * Copyright (C) 1998 Raph Levien
- *
- * This library 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 library 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 library; if not, write to the
- * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- */
-
-#include "config.h"
-#include "art_rgb_pixbuf_affine.h"
-
-#include <math.h>
-#include "art_misc.h"
-#include "art_point.h"
-#include "art_affine.h"
-#include "art_pixbuf.h"
-#include "art_rgb_affine.h"
-#include "art_rgb_affine.h"
-#include "art_rgb_rgba_affine.h"
-
-/* This module handles compositing of affine-transformed generic
- pixbuf images over rgb pixel buffers. */
-
-/* Composite the source image over the destination image, applying the
- affine transform. */
-/**
- * art_rgb_pixbuf_affine: Affine transform source RGB pixbuf and composite.
- * @dst: Destination image RGB buffer.
- * @x0: Left coordinate of destination rectangle.
- * @y0: Top coordinate of destination rectangle.
- * @x1: Right coordinate of destination rectangle.
- * @y1: Bottom coordinate of destination rectangle.
- * @dst_rowstride: Rowstride of @dst buffer.
- * @pixbuf: source image pixbuf.
- * @affine: Affine transform.
- * @level: Filter level.
- * @alphagamma: #ArtAlphaGamma for gamma-correcting the compositing.
- *
- * Affine transform the source image stored in @src, compositing over
- * the area of destination image @dst specified by the rectangle
- * (@x0, @y0) - (@x1, @y1). As usual in libart, the left and top edges
- * of this rectangle are included, and the right and bottom edges are
- * excluded.
- *
- * The @alphagamma parameter specifies that the alpha compositing be
- * done in a gamma-corrected color space. In the current
- * implementation, it is ignored.
- *
- * The @level parameter specifies the speed/quality tradeoff of the
- * image interpolation. Currently, only ART_FILTER_NEAREST is
- * implemented.
- **/
-void
-art_rgb_pixbuf_affine (art_u8 *dst,
- int x0, int y0, int x1, int y1, int dst_rowstride,
- const ArtPixBuf *pixbuf,
- const double affine[6],
- ArtFilterLevel level,
- ArtAlphaGamma *alphagamma)
-{
- if (pixbuf->format != ART_PIX_RGB)
- {
- art_warn ("art_rgb_pixbuf_affine: need RGB format image\n");
- return;
- }
-
- if (pixbuf->bits_per_sample != 8)
- {
- art_warn ("art_rgb_pixbuf_affine: need 8-bit sample data\n");
- return;
- }
-
- if (pixbuf->n_channels != 3 + (pixbuf->has_alpha != 0))
- {
- art_warn ("art_rgb_pixbuf_affine: need 8-bit sample data\n");
- return;
- }
-
- if (pixbuf->has_alpha)
- art_rgb_rgba_affine (dst, x0, y0, x1, y1, dst_rowstride,
- pixbuf->pixels,
- pixbuf->width, pixbuf->height, pixbuf->rowstride,
- affine,
- level,
- alphagamma);
- else
- art_rgb_affine (dst, x0, y0, x1, y1, dst_rowstride,
- pixbuf->pixels,
- pixbuf->width, pixbuf->height, pixbuf->rowstride,
- affine,
- level,
- alphagamma);
-}
diff --git a/libart_lgpl/art_rgb_pixbuf_affine.h b/libart_lgpl/art_rgb_pixbuf_affine.h
deleted file mode 100644
index 8d5b466858..0000000000
--- a/libart_lgpl/art_rgb_pixbuf_affine.h
+++ /dev/null
@@ -1,46 +0,0 @@
-/* Libart_LGPL - library of basic graphic primitives
- * Copyright (C) 1998 Raph Levien
- *
- * This library 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 library 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 library; if not, write to the
- * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- */
-
-#ifndef __ART_RGB_PIXBUF_AFFINE_H__
-#define __ART_RGB_PIXBUF_AFFINE_H__
-
-/* This module handles compositing of affine-transformed generic
- pixbuf images over rgb pixel buffers. */
-
-#include <libart_lgpl/art_filterlevel.h>
-#include <libart_lgpl/art_alphagamma.h>
-#include <libart_lgpl/art_pixbuf.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-void
-art_rgb_pixbuf_affine (art_u8 *dst,
- int x0, int y0, int x1, int y1, int dst_rowstride,
- const ArtPixBuf *pixbuf,
- const double affine[6],
- ArtFilterLevel level,
- ArtAlphaGamma *alphagamma);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif
diff --git a/libart_lgpl/art_rgba.c b/libart_lgpl/art_rgba.c
deleted file mode 100644
index cde183cc52..0000000000
--- a/libart_lgpl/art_rgba.c
+++ /dev/null
@@ -1,258 +0,0 @@
-/*
- * art_rgba.c: Functions for manipulating RGBA pixel data.
- *
- * Libart_LGPL - library of basic graphic primitives
- * Copyright (C) 2000 Raph Levien
- *
- * This library 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 library 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 library; if not, write to the
- * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- */
-
-#include "config.h"
-#include "art_rgba.h"
-
-#define ART_OPTIMIZE_SPACE
-
-#ifndef ART_OPTIMIZE_SPACE
-#include "art_rgba_table.c"
-#endif
-
-/**
- * art_rgba_rgba_composite: Composite RGBA image over RGBA buffer.
- * @dst: Destination RGBA buffer.
- * @src: Source RGBA buffer.
- * @n: Number of RGBA pixels to composite.
- *
- * Composites the RGBA pixels in @dst over the @src buffer.
- **/
-void
-art_rgba_rgba_composite (art_u8 *dst, const art_u8 *src, int n)
-{
- int i;
-#ifdef WORDS_BIGENDIAN
- art_u32 src_rgba, dst_rgba;
-#else
- art_u32 src_abgr, dst_abgr;
-#endif
- art_u8 src_alpha, dst_alpha;
-
- for (i = 0; i < n; i++)
- {
-#ifdef WORDS_BIGENDIAN
- src_rgba = ((art_u32 *)src)[i];
- src_alpha = src_rgba & 0xff;
-#else
- src_abgr = ((art_u32 *)src)[i];
- src_alpha = (src_abgr >> 24) & 0xff;
-#endif
- if (src_alpha)
- {
- if (src_alpha == 0xff ||
- (
-#ifdef WORDS_BIGENDIAN
- dst_rgba = ((art_u32 *)dst)[i],
- dst_alpha = dst_rgba & 0xff,
-#else
- dst_abgr = ((art_u32 *)dst)[i],
- dst_alpha = (dst_abgr >> 24),
-#endif
- dst_alpha == 0))
-#ifdef WORDS_BIGENDIAN
- ((art_u32 *)dst)[i] = src_rgba;
-#else
- ((art_u32 *)dst)[i] = src_abgr;
-#endif
- else
- {
- int r, g, b, a;
- int src_r, src_g, src_b;
- int dst_r, dst_g, dst_b;
- int tmp;
- int c;
-
-#ifdef ART_OPTIMIZE_SPACE
- tmp = (255 - src_alpha) * (255 - dst_alpha) + 0x80;
- a = 255 - ((tmp + (tmp >> 8)) >> 8);
- c = ((src_alpha << 16) + (a >> 1)) / a;
-#else
- tmp = art_rgba_composite_table[(src_alpha << 8) + dst_alpha];
- c = tmp & 0x1ffff;
- a = tmp >> 24;
-#endif
-#ifdef WORDS_BIGENDIAN
- src_r = (src_rgba >> 24) & 0xff;
- src_g = (src_rgba >> 16) & 0xff;
- src_b = (src_rgba >> 8) & 0xff;
- dst_r = (dst_rgba >> 24) & 0xff;
- dst_g = (dst_rgba >> 16) & 0xff;
- dst_b = (dst_rgba >> 8) & 0xff;
-#else
- src_r = src_abgr & 0xff;
- src_g = (src_abgr >> 8) & 0xff;
- src_b = (src_abgr >> 16) & 0xff;
- dst_r = dst_abgr & 0xff;
- dst_g = (dst_abgr >> 8) & 0xff;
- dst_b = (dst_abgr >> 16) & 0xff;
-#endif
- r = dst_r + (((src_r - dst_r) * c + 0x8000) >> 16);
- g = dst_g + (((src_g - dst_g) * c + 0x8000) >> 16);
- b = dst_b + (((src_b - dst_b) * c + 0x8000) >> 16);
-#ifdef WORDS_BIGENDIAN
- ((art_u32 *)dst)[i] = (r << 24) | (g << 16) | (b << 8) | a;
-#else
- ((art_u32 *)dst)[i] = (a << 24) | (b << 16) | (g << 8) | r;
-#endif
- }
- }
-#if 0
- /* it's not clear to me this optimization really wins */
- else
- {
- /* skip over run of transparent pixels */
- for (; i < n - 1; i++)
- {
-#ifdef WORDS_BIGENDIAN
- src_rgba = ((art_u32 *)src)[i + 1];
- if (src_rgba & 0xff)
- break;
-#else
- src_abgr = ((art_u32 *)src)[i + 1];
- if (src_abgr & 0xff000000)
- break;
-#endif
- }
- }
-#endif
- }
-}
-
-/**
- * art_rgba_fill_run: fill an RGBA buffer a solid RGB color.
- * @buf: Buffer to fill.
- * @r: Red, range 0..255.
- * @g: Green, range 0..255.
- * @b: Blue, range 0..255.
- * @n: Number of RGB triples to fill.
- *
- * Fills a buffer with @n copies of the (@r, @g, @b) triple, solid
- * alpha. Thus, locations @buf (inclusive) through @buf + 4 * @n
- * (exclusive) are written.
- **/
-void
-art_rgba_fill_run (art_u8 *buf, art_u8 r, art_u8 g, art_u8 b, int n)
-{
- int i;
-#ifdef WORDS_BIGENDIAN
- art_u32 src_rgba;
-#else
- art_u32 src_abgr;
-#endif
-
-#ifdef WORDS_BIGENDIAN
- src_rgba = (r << 24) | (g << 16) | (b << 8) | 255;
-#else
- src_abgr = (255 << 24) | (b << 16) | (g << 8) | r;
-#endif
- for (i = 0; i < n; i++)
- {
-#ifdef WORDS_BIGENDIAN
- ((art_u32 *)buf)[i] = src_rgba;
-#else
- ((art_u32 *)buf)[i] = src_abgr;
-#endif
- }
-}
-
-/**
- * art_rgba_run_alpha: Render semitransparent color over RGBA buffer.
- * @buf: Buffer for rendering.
- * @r: Red, range 0..255.
- * @g: Green, range 0..255.
- * @b: Blue, range 0..255.
- * @alpha: Alpha, range 0..255.
- * @n: Number of RGB triples to render.
- *
- * Renders a sequential run of solid (@r, @g, @b) color over @buf with
- * opacity @alpha. Note that the range of @alpha is 0..255, in contrast
- * to art_rgb_run_alpha, which has a range of 0..256.
- **/
-void
-art_rgba_run_alpha (art_u8 *buf, art_u8 r, art_u8 g, art_u8 b, int alpha, int n)
-{
- int i;
-#ifdef WORDS_BIGENDIAN
- art_u32 src_rgba, dst_rgba;
-#else
- art_u32 src_abgr, dst_abgr;
-#endif
- art_u8 dst_alpha;
- int a;
- int dst_r, dst_g, dst_b;
- int tmp;
- int c;
-
-#ifdef WORDS_BIGENDIAN
- src_rgba = (r << 24) | (g << 16) | (b << 8) | alpha;
-#else
- src_abgr = (alpha << 24) | (b << 16) | (g << 8) | r;
-#endif
- for (i = 0; i < n; i++)
- {
-#ifdef WORDS_BIGENDIAN
- dst_rgba = ((art_u32 *)buf)[i];
- dst_alpha = dst_rgba & 0xff;
-#else
- dst_abgr = ((art_u32 *)buf)[i];
- dst_alpha = (dst_abgr >> 24) & 0xff;
-#endif
- if (dst_alpha)
- {
-#ifdef ART_OPTIMIZE_SPACE
- tmp = (255 - alpha) * (255 - dst_alpha) + 0x80;
- a = 255 - ((tmp + (tmp >> 8)) >> 8);
- c = ((alpha << 16) + (a >> 1)) / a;
-#else
- tmp = art_rgba_composite_table[(alpha << 8) + dst_alpha];
- c = tmp & 0x1ffff;
- a = tmp >> 24;
-#endif
-#ifdef WORDS_BIGENDIAN
- dst_r = (dst_rgba >> 24) & 0xff;
- dst_g = (dst_rgba >> 16) & 0xff;
- dst_b = (dst_rgba >> 8) & 0xff;
-#else
- dst_r = dst_abgr & 0xff;
- dst_g = (dst_abgr >> 8) & 0xff;
- dst_b = (dst_abgr >> 16) & 0xff;
-#endif
- dst_r += (((r - dst_r) * c + 0x8000) >> 16);
- dst_g += (((g - dst_g) * c + 0x8000) >> 16);
- dst_b += (((b - dst_b) * c + 0x8000) >> 16);
-#ifdef WORDS_BIGENDIAN
- ((art_u32 *)buf)[i] = (dst_r << 24) | (dst_g << 16) | (dst_b << 8) | a;
-#else
- ((art_u32 *)buf)[i] = (a << 24) | (dst_b << 16) | (dst_g << 8) | dst_r;
-#endif
- }
- else
- {
-#ifdef WORDS_BIGENDIAN
- ((art_u32 *)buf)[i] = src_rgba;
-#else
- ((art_u32 *)buf)[i] = src_abgr;
-#endif
- }
- }
-}
diff --git a/libart_lgpl/art_rgba.h b/libart_lgpl/art_rgba.h
deleted file mode 100644
index 0d0fd432bd..0000000000
--- a/libart_lgpl/art_rgba.h
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
- * art_rgba.h: Functions for manipulating RGBA pixel data.
- *
- * Libart_LGPL - library of basic graphic primitives
- * Copyright (C) 2000 Raph Levien
- *
- * This library 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 library 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 library; if not, write to the
- * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- */
-
-#ifndef __ART_RGBA_H__
-#define __ART_RGBA_H__
-
-#include <libart_lgpl/art_misc.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif /* __cplusplus */
-
-void
-art_rgba_rgba_composite (art_u8 *dst, const art_u8 *src, int n);
-
-void
-art_rgba_fill_run (art_u8 *buf, art_u8 r, art_u8 g, art_u8 b, int n);
-
-void
-art_rgba_run_alpha (art_u8 *buf, art_u8 r, art_u8 g, art_u8 b, int alpha, int n);
-
-#ifdef __cplusplus
-}
-#endif /* __cplusplus */
-
-#endif
diff --git a/libart_lgpl/art_svp_ops.c b/libart_lgpl/art_svp_ops.c
index 5bb837c5ac..08991aac1b 100644
--- a/libart_lgpl/art_svp_ops.c
+++ b/libart_lgpl/art_svp_ops.c
@@ -183,69 +183,6 @@ art_svp_merge_perturbed (const ArtSVP *svp1, const ArtSVP *svp2)
}
#endif
-/* Compute the union of two vector paths.
-
- Status of this routine:
-
- Basic correctness: Seems to work.
-
- Numerical stability: We cheat (adding random perturbation). Thus,
- it seems very likely that no numerical stability problems will be
- seen in practice.
-
- Speed: Would be better if we didn't go to unsorted vector path
- and back to add the perturbation.
-
- Precision: The perturbation fuzzes the coordinates slightly. In
- cases of butting segments, razor thin long holes may appear.
-
-*/
-/**
- * art_svp_union: Compute the union of two sorted vector paths.
- * @svp1: One sorted vector path.
- * @svp2: The other sorted vector path.
- *
- * Computes the union of the two argument svp's. Given two svp's with
- * winding numbers of 0 and 1 everywhere, the resulting winding number
- * will be 1 where either (or both) of the argument svp's has a
- * winding number 1, 0 otherwise. The result is newly allocated.
- *
- * Currently, this routine has accuracy problems pending the
- * implementation of the new intersector.
- *
- * Return value: The union of @svp1 and @svp2.
- **/
-ArtSVP *
-art_svp_union (const ArtSVP *svp1, const ArtSVP *svp2)
-{
-#ifdef ART_USE_NEW_INTERSECTOR
- ArtSVP *svp3, *svp_new;
- ArtSvpWriter *swr;
-
- svp3 = art_svp_merge (svp1, svp2);
- swr = art_svp_writer_rewind_new (ART_WIND_RULE_POSITIVE);
- art_svp_intersector (svp3, swr);
- svp_new = art_svp_writer_rewind_reap (swr);
- art_free (svp3); /* shallow free because svp3 contains shared segments */
-
- return svp_new;
-#else
- ArtSVP *svp3, *svp4, *svp_new;
-
- svp3 = art_svp_merge_perturbed (svp1, svp2);
- svp4 = art_svp_uncross (svp3);
- art_svp_free (svp3);
-
- svp_new = art_svp_rewind_uncrossed (svp4, ART_WIND_RULE_POSITIVE);
-#ifdef VERBOSE
- print_ps_svp (svp4);
- print_ps_svp (svp_new);
-#endif
- art_svp_free (svp4);
- return svp_new;
-#endif
-}
-
/* Compute the intersection of two vector paths.
Status of this routine:
@@ -307,95 +244,3 @@ art_svp_intersect (const ArtSVP *svp1, const ArtSVP *svp2)
#endif
}
-/* Compute the symmetric difference of two vector paths.
-
- Status of this routine:
-
- Basic correctness: Seems to work.
-
- Numerical stability: We cheat (adding random perturbation). Thus,
- it seems very likely that no numerical stability problems will be
- seen in practice.
-
- Speed: We could do a lot better by scanning through the svp
- representations and culling out any segments that are exactly
- identical. It would also be better if we didn't go to unsorted
- vector path and back to add the perturbation.
-
- Precision: Awful. In the case of inputs which are similar (the
- common case for canvas display), the entire outline is "hairy." In
- addition, the perturbation fuzzes the coordinates slightly. It can
- be used as a conservative approximation.
-
-*/
-
-/**
- * art_svp_diff: Compute the symmetric difference of two sorted vector paths.
- * @svp1: One sorted vector path.
- * @svp2: The other sorted vector path.
- *
- * Computes the symmetric of the two argument svp's. Given two svp's
- * with winding numbers of 0 and 1 everywhere, the resulting winding
- * number will be 1 where either, but not both, of the argument svp's
- * has a winding number 1, 0 otherwise. The result is newly allocated.
- *
- * Currently, this routine has accuracy problems pending the
- * implementation of the new intersector.
- *
- * Return value: The symmetric difference of @svp1 and @svp2.
- **/
-ArtSVP *
-art_svp_diff (const ArtSVP *svp1, const ArtSVP *svp2)
-{
-#ifdef ART_USE_NEW_INTERSECTOR
- ArtSVP *svp3, *svp_new;
- ArtSvpWriter *swr;
-
- svp3 = art_svp_merge (svp1, svp2);
- swr = art_svp_writer_rewind_new (ART_WIND_RULE_ODDEVEN);
- art_svp_intersector (svp3, swr);
- svp_new = art_svp_writer_rewind_reap (swr);
- art_free (svp3); /* shallow free because svp3 contains shared segments */
-
- return svp_new;
-#else
- ArtSVP *svp3, *svp4, *svp_new;
-
- svp3 = art_svp_merge_perturbed (svp1, svp2);
- svp4 = art_svp_uncross (svp3);
- art_svp_free (svp3);
-
- svp_new = art_svp_rewind_uncrossed (svp4, ART_WIND_RULE_ODDEVEN);
- art_svp_free (svp4);
- return svp_new;
-#endif
-}
-
-#ifdef ART_USE_NEW_INTERSECTOR
-ArtSVP *
-art_svp_minus (const ArtSVP *svp1, const ArtSVP *svp2)
-{
- ArtSVP *svp2_mod;
- ArtSVP *svp3, *svp_new;
- ArtSvpWriter *swr;
- int i;
-
- svp2_mod = (ArtSVP *) svp2; /* get rid of the const for a while */
-
- /* First invert svp2 to "turn it inside out" */
- for (i = 0; i < svp2_mod->n_segs; i++)
- svp2_mod->segs[i].dir = !svp2_mod->segs[i].dir;
-
- svp3 = art_svp_merge (svp1, svp2_mod);
- swr = art_svp_writer_rewind_new (ART_WIND_RULE_POSITIVE);
- art_svp_intersector (svp3, swr);
- svp_new = art_svp_writer_rewind_reap (swr);
- art_free (svp3); /* shallow free because svp3 contains shared segments */
-
- /* Flip svp2 back to its original state */
- for (i = 0; i < svp2_mod->n_segs; i++)
- svp2_mod->segs[i].dir = !svp2_mod->segs[i].dir;
-
- return svp_new;
-}
-#endif /* ART_USE_NEW_INTERSECTOR */
diff --git a/libart_lgpl/art_svp_ops.h b/libart_lgpl/art_svp_ops.h
index 1e511f5ed2..8f150c28dc 100644
--- a/libart_lgpl/art_svp_ops.h
+++ b/libart_lgpl/art_svp_ops.h
@@ -28,10 +28,7 @@ extern "C" {
/* Vector path set operations, over sorted vpaths. */
-ArtSVP *art_svp_union (const ArtSVP *svp1, const ArtSVP *svp2);
ArtSVP *art_svp_intersect (const ArtSVP *svp1, const ArtSVP *svp2);
-ArtSVP *art_svp_diff (const ArtSVP *svp1, const ArtSVP *svp2);
-ArtSVP *art_svp_minus (const ArtSVP *svp1, const ArtSVP *svp2);
#ifdef __cplusplus
}
diff --git a/libart_lgpl/art_svp_wind.c b/libart_lgpl/art_svp_wind.c
deleted file mode 100644
index a12b1c7763..0000000000
--- a/libart_lgpl/art_svp_wind.c
+++ /dev/null
@@ -1,1545 +0,0 @@
-/* Libart_LGPL - library of basic graphic primitives
- * Copyright (C) 1998-2000 Raph Levien
- *
- * This library 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 library 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 library; if not, write to the
- * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- */
-
-/* Primitive intersection and winding number operations on sorted
- vector paths.
-
- These routines are internal to libart, used to construct operations
- like intersection, union, and difference. */
-
-#include "config.h"
-#include "art_svp_wind.h"
-
-#include <stdio.h> /* for printf of debugging info */
-#include <string.h> /* for memcpy */
-#include <math.h>
-#include "art_misc.h"
-
-#include "art_rect.h"
-#include "art_svp.h"
-
-#define noVERBOSE
-
-#define PT_EQ(p1,p2) ((p1).x == (p2).x && (p1).y == (p2).y)
-
-#define PT_CLOSE(p1,p2) (fabs ((p1).x - (p2).x) < 1e-6 && fabs ((p1).y - (p2).y) < 1e-6)
-
-/* return nonzero and set *p to the intersection point if the lines
- z0-z1 and z2-z3 intersect each other. */
-static int
-intersect_lines (ArtPoint z0, ArtPoint z1, ArtPoint z2, ArtPoint z3,
- ArtPoint *p)
-{
- double a01, b01, c01;
- double a23, b23, c23;
- double d0, d1, d2, d3;
- double det;
-
- /* if the vectors share an endpoint, they don't intersect */
- if (PT_EQ (z0, z2) || PT_EQ (z0, z3) || PT_EQ (z1, z2) || PT_EQ (z1, z3))
- return 0;
-
-#if 0
- if (PT_CLOSE (z0, z2) || PT_CLOSE (z0, z3) || PT_CLOSE (z1, z2) || PT_CLOSE (z1, z3))
- return 0;
-#endif
-
- /* find line equations ax + by + c = 0 */
- a01 = z0.y - z1.y;
- b01 = z1.x - z0.x;
- c01 = -(z0.x * a01 + z0.y * b01);
- /* = -((z0.y - z1.y) * z0.x + (z1.x - z0.x) * z0.y)
- = (z1.x * z0.y - z1.y * z0.x) */
-
- d2 = a01 * z2.x + b01 * z2.y + c01;
- d3 = a01 * z3.x + b01 * z3.y + c01;
- if ((d2 > 0) == (d3 > 0))
- return 0;
-
- a23 = z2.y - z3.y;
- b23 = z3.x - z2.x;
- c23 = -(z2.x * a23 + z2.y * b23);
-
- d0 = a23 * z0.x + b23 * z0.y + c23;
- d1 = a23 * z1.x + b23 * z1.y + c23;
- if ((d0 > 0) == (d1 > 0))
- return 0;
-
- /* now we definitely know that the lines intersect */
- /* solve the two linear equations ax + by + c = 0 */
- det = 1.0 / (a01 * b23 - a23 * b01);
- p->x = det * (c23 * b01 - c01 * b23);
- p->y = det * (c01 * a23 - c23 * a01);
-
- return 1;
-}
-
-#define EPSILON 1e-6
-
-static double
-trap_epsilon (double v)
-{
- const double epsilon = EPSILON;
-
- if (v < epsilon && v > -epsilon) return 0;
- else return v;
-}
-
-/* Determine the order of line segments z0-z1 and z2-z3.
- Return +1 if z2-z3 lies entirely to the right of z0-z1,
- -1 if entirely to the left,
- or 0 if overlap.
-
- The case analysis in this function is quite ugly. The fact that it's
- almost 200 lines long is ridiculous.
-
- Ok, so here's the plan to cut it down:
-
- First, do a bounding line comparison on the x coordinates. This is pretty
- much the common case, and should go quickly. It also takes care of the
- case where both lines are horizontal.
-
- Then, do d0 and d1 computation, but only if a23 is nonzero.
-
- Finally, do d2 and d3 computation, but only if a01 is nonzero.
-
- Fall through to returning 0 (this will happen when both lines are
- horizontal and they overlap).
- */
-static int
-x_order (ArtPoint z0, ArtPoint z1, ArtPoint z2, ArtPoint z3)
-{
- double a01, b01, c01;
- double a23, b23, c23;
- double d0, d1, d2, d3;
-
- if (z0.y == z1.y)
- {
- if (z2.y == z3.y)
- {
- double x01min, x01max;
- double x23min, x23max;
-
- if (z0.x > z1.x)
- {
- x01min = z1.x;
- x01max = z0.x;
- }
- else
- {
- x01min = z0.x;
- x01max = z1.x;
- }
-
- if (z2.x > z3.x)
- {
- x23min = z3.x;
- x23max = z2.x;
- }
- else
- {
- x23min = z2.x;
- x23max = z3.x;
- }
-
- if (x23min >= x01max) return 1;
- else if (x01min >= x23max) return -1;
- else return 0;
- }
- else
- {
- /* z0-z1 is horizontal, z2-z3 isn't */
- a23 = z2.y - z3.y;
- b23 = z3.x - z2.x;
- c23 = -(z2.x * a23 + z2.y * b23);
-
- if (z3.y < z2.y)
- {
- a23 = -a23;
- b23 = -b23;
- c23 = -c23;
- }
-
- d0 = trap_epsilon (a23 * z0.x + b23 * z0.y + c23);
- d1 = trap_epsilon (a23 * z1.x + b23 * z1.y + c23);
-
- if (d0 > 0)
- {
- if (d1 >= 0) return 1;
- else return 0;
- }
- else if (d0 == 0)
- {
- if (d1 > 0) return 1;
- else if (d1 < 0) return -1;
- else printf ("case 1 degenerate\n");
- return 0;
- }
- else /* d0 < 0 */
- {
- if (d1 <= 0) return -1;
- else return 0;
- }
- }
- }
- else if (z2.y == z3.y)
- {
- /* z2-z3 is horizontal, z0-z1 isn't */
- a01 = z0.y - z1.y;
- b01 = z1.x - z0.x;
- c01 = -(z0.x * a01 + z0.y * b01);
- /* = -((z0.y - z1.y) * z0.x + (z1.x - z0.x) * z0.y)
- = (z1.x * z0.y - z1.y * z0.x) */
-
- if (z1.y < z0.y)
- {
- a01 = -a01;
- b01 = -b01;
- c01 = -c01;
- }
-
- d2 = trap_epsilon (a01 * z2.x + b01 * z2.y + c01);
- d3 = trap_epsilon (a01 * z3.x + b01 * z3.y + c01);
-
- if (d2 > 0)
- {
- if (d3 >= 0) return -1;
- else return 0;
- }
- else if (d2 == 0)
- {
- if (d3 > 0) return -1;
- else if (d3 < 0) return 1;
- else printf ("case 2 degenerate\n");
- return 0;
- }
- else /* d2 < 0 */
- {
- if (d3 <= 0) return 1;
- else return 0;
- }
- }
-
- /* find line equations ax + by + c = 0 */
- a01 = z0.y - z1.y;
- b01 = z1.x - z0.x;
- c01 = -(z0.x * a01 + z0.y * b01);
- /* = -((z0.y - z1.y) * z0.x + (z1.x - z0.x) * z0.y)
- = -(z1.x * z0.y - z1.y * z0.x) */
-
- if (a01 > 0)
- {
- a01 = -a01;
- b01 = -b01;
- c01 = -c01;
- }
- /* so now, (a01, b01) points to the left, thus a01 * x + b01 * y + c01
- is negative if the point lies to the right of the line */
-
- d2 = trap_epsilon (a01 * z2.x + b01 * z2.y + c01);
- d3 = trap_epsilon (a01 * z3.x + b01 * z3.y + c01);
- if (d2 > 0)
- {
- if (d3 >= 0) return -1;
- }
- else if (d2 == 0)
- {
- if (d3 > 0) return -1;
- else if (d3 < 0) return 1;
- else
- fprintf (stderr, "colinear!\n");
- }
- else /* d2 < 0 */
- {
- if (d3 <= 0) return 1;
- }
-
- a23 = z2.y - z3.y;
- b23 = z3.x - z2.x;
- c23 = -(z2.x * a23 + z2.y * b23);
-
- if (a23 > 0)
- {
- a23 = -a23;
- b23 = -b23;
- c23 = -c23;
- }
- d0 = trap_epsilon (a23 * z0.x + b23 * z0.y + c23);
- d1 = trap_epsilon (a23 * z1.x + b23 * z1.y + c23);
- if (d0 > 0)
- {
- if (d1 >= 0) return 1;
- }
- else if (d0 == 0)
- {
- if (d1 > 0) return 1;
- else if (d1 < 0) return -1;
- else
- fprintf (stderr, "colinear!\n");
- }
- else /* d0 < 0 */
- {
- if (d1 <= 0) return -1;
- }
-
- return 0;
-}
-
-/* similar to x_order, but to determine whether point z0 + epsilon lies to
- the left of the line z2-z3 or to the right */
-static int
-x_order_2 (ArtPoint z0, ArtPoint z1, ArtPoint z2, ArtPoint z3)
-{
- double a23, b23, c23;
- double d0, d1;
-
- a23 = z2.y - z3.y;
- b23 = z3.x - z2.x;
- c23 = -(z2.x * a23 + z2.y * b23);
-
- if (a23 > 0)
- {
- a23 = -a23;
- b23 = -b23;
- c23 = -c23;
- }
-
- d0 = a23 * z0.x + b23 * z0.y + c23;
-
- if (d0 > EPSILON)
- return -1;
- else if (d0 < -EPSILON)
- return 1;
-
- d1 = a23 * z1.x + b23 * z1.y + c23;
- if (d1 > EPSILON)
- return -1;
- else if (d1 < -EPSILON)
- return 1;
-
- if (z0.x == z1.x && z1.x == z2.x && z2.x == z3.x)
- {
- art_dprint ("x_order_2: colinear and horizontally aligned!\n");
- return 0;
- }
-
- if (z0.x <= z2.x && z1.x <= z2.x && z0.x <= z3.x && z1.x <= z3.x)
- return -1;
- if (z0.x >= z2.x && z1.x >= z2.x && z0.x >= z3.x && z1.x >= z3.x)
- return 1;
-
- fprintf (stderr, "x_order_2: colinear!\n");
- return 0;
-}
-
-#ifdef DEAD_CODE
-/* Traverse the vector path, keeping it in x-sorted order.
-
- This routine doesn't actually do anything - it's just here for
- explanatory purposes. */
-void
-traverse (ArtSVP *vp)
-{
- int *active_segs;
- int n_active_segs;
- int *cursor;
- int seg_idx;
- double y;
- int tmp1, tmp2;
- int asi;
- int i, j;
-
- active_segs = art_new (int, vp->n_segs);
- cursor = art_new (int, vp->n_segs);
-
- n_active_segs = 0;
- seg_idx = 0;
- y = vp->segs[0].points[0].y;
- while (seg_idx < vp->n_segs || n_active_segs > 0)
- {
- printf ("y = %g\n", y);
- /* delete segments ending at y from active list */
- for (i = 0; i < n_active_segs; i++)
- {
- asi = active_segs[i];
- if (vp->segs[asi].n_points - 1 == cursor[asi] &&
- vp->segs[asi].points[cursor[asi]].y == y)
- {
- printf ("deleting %d\n", asi);
- n_active_segs--;
- for (j = i; j < n_active_segs; j++)
- active_segs[j] = active_segs[j + 1];
- i--;
- }
- }
-
- /* insert new segments into the active list */
- while (seg_idx < vp->n_segs && y == vp->segs[seg_idx].points[0].y)
- {
- cursor[seg_idx] = 0;
- printf ("inserting %d\n", seg_idx);
- for (i = 0; i < n_active_segs; i++)
- {
- asi = active_segs[i];
- if (x_order (vp->segs[asi].points[cursor[asi]],
- vp->segs[asi].points[cursor[asi] + 1],
- vp->segs[seg_idx].points[0],
- vp->segs[seg_idx].points[1]) == -1)
- break;
- }
- tmp1 = seg_idx;
- for (j = i; j < n_active_segs; j++)
- {
- tmp2 = active_segs[j];
- active_segs[j] = tmp1;
- tmp1 = tmp2;
- }
- active_segs[n_active_segs] = tmp1;
- n_active_segs++;
- seg_idx++;
- }
-
- /* all active segs cross the y scanline (considering segs to be
- closed on top and open on bottom) */
- for (i = 0; i < n_active_segs; i++)
- {
- asi = active_segs[i];
- printf ("%d (%g, %g) - (%g, %g) %s\n", asi,
- vp->segs[asi].points[cursor[asi]].x,
- vp->segs[asi].points[cursor[asi]].y,
- vp->segs[asi].points[cursor[asi] + 1].x,
- vp->segs[asi].points[cursor[asi] + 1].y,
- vp->segs[asi].dir ? "v" : "^");
- }
-
- /* advance y to the next event */
- if (n_active_segs == 0)
- {
- if (seg_idx < vp->n_segs)
- y = vp->segs[seg_idx].points[0].y;
- /* else we're done */
- }
- else
- {
- asi = active_segs[0];
- y = vp->segs[asi].points[cursor[asi] + 1].y;
- for (i = 1; i < n_active_segs; i++)
- {
- asi = active_segs[i];
- if (y > vp->segs[asi].points[cursor[asi] + 1].y)
- y = vp->segs[asi].points[cursor[asi] + 1].y;
- }
- if (seg_idx < vp->n_segs && y > vp->segs[seg_idx].points[0].y)
- y = vp->segs[seg_idx].points[0].y;
- }
-
- /* advance cursors to reach new y */
- for (i = 0; i < n_active_segs; i++)
- {
- asi = active_segs[i];
- while (cursor[asi] < vp->segs[asi].n_points - 1 &&
- y >= vp->segs[asi].points[cursor[asi] + 1].y)
- cursor[asi]++;
- }
- printf ("\n");
- }
- art_free (cursor);
- art_free (active_segs);
-}
-#endif
-
-/* I believe that the loop will always break with i=1.
-
- I think I'll want to change this from a simple sorted list to a
- modified stack. ips[*][0] will get its own data structure, and
- ips[*] will in general only be allocated if there is an intersection.
- Finally, the segment can be traced through the initial point
- (formerly ips[*][0]), backwards through the stack, and finally
- to cursor + 1.
-
- This change should cut down on allocation bandwidth, and also
- eliminate the iteration through n_ipl below.
-
-*/
-static void
-insert_ip (int seg_i, int *n_ips, int *n_ips_max, ArtPoint **ips, ArtPoint ip)
-{
- int i;
- ArtPoint tmp1, tmp2;
- int n_ipl;
- ArtPoint *ipl;
-
- n_ipl = n_ips[seg_i]++;
- if (n_ipl == n_ips_max[seg_i])
- art_expand (ips[seg_i], ArtPoint, n_ips_max[seg_i]);
- ipl = ips[seg_i];
- for (i = 1; i < n_ipl; i++)
- if (ipl[i].y > ip.y)
- break;
- tmp1 = ip;
- for (; i <= n_ipl; i++)
- {
- tmp2 = ipl[i];
- ipl[i] = tmp1;
- tmp1 = tmp2;
- }
-}
-
-/* test active segment (i - 1) against i for intersection, if
- so, add intersection point to both ips lists. */
-static void
-intersect_neighbors (int i, int *active_segs,
- int *n_ips, int *n_ips_max, ArtPoint **ips,
- int *cursor, ArtSVP *vp)
-{
- ArtPoint z0, z1, z2, z3;
- int asi01, asi23;
- ArtPoint ip;
-
- asi01 = active_segs[i - 1];
-
- z0 = ips[asi01][0];
- if (n_ips[asi01] == 1)
- z1 = vp->segs[asi01].points[cursor[asi01] + 1];
- else
- z1 = ips[asi01][1];
-
- asi23 = active_segs[i];
-
- z2 = ips[asi23][0];
- if (n_ips[asi23] == 1)
- z3 = vp->segs[asi23].points[cursor[asi23] + 1];
- else
- z3 = ips[asi23][1];
-
- if (intersect_lines (z0, z1, z2, z3, &ip))
- {
-#ifdef VERBOSE
- printf ("new intersection point: (%g, %g)\n", ip.x, ip.y);
-#endif
- insert_ip (asi01, n_ips, n_ips_max, ips, ip);
- insert_ip (asi23, n_ips, n_ips_max, ips, ip);
- }
-}
-
-/* Add a new point to a segment in the svp.
-
- Here, we also check to make sure that the segments satisfy nocross.
- However, this is only valuable for debugging, and could possibly be
- removed.
-*/
-static void
-svp_add_point (ArtSVP *svp, int *n_points_max,
- ArtPoint p, int *seg_map, int *active_segs, int n_active_segs,
- int i)
-{
- int asi, asi_left, asi_right;
- int n_points, n_points_left, n_points_right;
- ArtSVPSeg *seg;
-
- asi = seg_map[active_segs[i]];
- seg = &svp->segs[asi];
- n_points = seg->n_points;
- /* find out whether neighboring segments share a point */
- if (i > 0)
- {
- asi_left = seg_map[active_segs[i - 1]];
- n_points_left = svp->segs[asi_left].n_points;
- if (n_points_left > 1 &&
- PT_EQ (svp->segs[asi_left].points[n_points_left - 2],
- svp->segs[asi].points[n_points - 1]))
- {
- /* ok, new vector shares a top point with segment to the left -
- now, check that it satisfies ordering invariant */
- if (x_order (svp->segs[asi_left].points[n_points_left - 2],
- svp->segs[asi_left].points[n_points_left - 1],
- svp->segs[asi].points[n_points - 1],
- p) < 1)
-
- {
-#ifdef VERBOSE
- printf ("svp_add_point: cross on left!\n");
-#endif
- }
- }
- }
-
- if (i + 1 < n_active_segs)
- {
- asi_right = seg_map[active_segs[i + 1]];
- n_points_right = svp->segs[asi_right].n_points;
- if (n_points_right > 1 &&
- PT_EQ (svp->segs[asi_right].points[n_points_right - 2],
- svp->segs[asi].points[n_points - 1]))
- {
- /* ok, new vector shares a top point with segment to the right -
- now, check that it satisfies ordering invariant */
- if (x_order (svp->segs[asi_right].points[n_points_right - 2],
- svp->segs[asi_right].points[n_points_right - 1],
- svp->segs[asi].points[n_points - 1],
- p) > -1)
- {
-#ifdef VERBOSE
- printf ("svp_add_point: cross on right!\n");
-#endif
- }
- }
- }
- if (n_points_max[asi] == n_points)
- art_expand (seg->points, ArtPoint, n_points_max[asi]);
- seg->points[n_points] = p;
- if (p.x < seg->bbox.x0)
- seg->bbox.x0 = p.x;
- else if (p.x > seg->bbox.x1)
- seg->bbox.x1 = p.x;
- seg->bbox.y1 = p.y;
- seg->n_points++;
-}
-
-#if 0
-/* find where the segment (currently at i) is supposed to go, and return
- the target index - if equal to i, then there is no crossing problem.
-
- "Where it is supposed to go" is defined as following:
-
- Delete element i, re-insert at position target (bumping everything
- target and greater to the right).
- */
-static int
-find_crossing (int i, int *active_segs, int n_active_segs,
- int *cursor, ArtPoint **ips, int *n_ips, ArtSVP *vp)
-{
- int asi, asi_left, asi_right;
- ArtPoint p0, p1;
- ArtPoint p0l, p1l;
- ArtPoint p0r, p1r;
- int target;
-
- asi = active_segs[i];
- p0 = ips[asi][0];
- if (n_ips[asi] == 1)
- p1 = vp->segs[asi].points[cursor[asi] + 1];
- else
- p1 = ips[asi][1];
-
- for (target = i; target > 0; target--)
- {
- asi_left = active_segs[target - 1];
- p0l = ips[asi_left][0];
- if (n_ips[asi_left] == 1)
- p1l = vp->segs[asi_left].points[cursor[asi_left] + 1];
- else
- p1l = ips[asi_left][1];
- if (!PT_EQ (p0, p0l))
- break;
-
-#ifdef VERBOSE
- printf ("point matches on left (%g, %g) - (%g, %g) x (%g, %g) - (%g, %g)!\n",
- p0l.x, p0l.y, p1l.x, p1l.y, p0.x, p0.y, p1.x, p1.y);
-#endif
- if (x_order (p0l, p1l, p0, p1) == 1)
- break;
-
-#ifdef VERBOSE
- printf ("scanning to the left (i=%d, target=%d)\n", i, target);
-#endif
- }
-
- if (target < i) return target;
-
- for (; target < n_active_segs - 1; target++)
- {
- asi_right = active_segs[target + 1];
- p0r = ips[asi_right][0];
- if (n_ips[asi_right] == 1)
- p1r = vp->segs[asi_right].points[cursor[asi_right] + 1];
- else
- p1r = ips[asi_right][1];
- if (!PT_EQ (p0, p0r))
- break;
-
-#ifdef VERBOSE
- printf ("point matches on left (%g, %g) - (%g, %g) x (%g, %g) - (%g, %g)!\n",
- p0.x, p0.y, p1.x, p1.y, p0r.x, p0r.y, p1r.x, p1r.y);
-#endif
- if (x_order (p0r, p1r, p0, p1) == 1)
- break;
-
-#ifdef VERBOSE
- printf ("scanning to the right (i=%d, target=%d)\n", i, target);
-#endif
- }
-
- return target;
-}
-#endif
-
-/* This routine handles the case where the segment changes its position
- in the active segment list. Generally, this will happen when the
- segment (defined by i and cursor) shares a top point with a neighbor,
- but breaks the ordering invariant.
-
- Essentially, this routine sorts the lines [start..end), all of which
- share a top point. This is implemented as your basic insertion sort.
-
- This routine takes care of intersecting the appropriate neighbors,
- as well.
-
- A first argument of -1 immediately returns, which helps reduce special
- casing in the main unwind routine.
-*/
-static void
-fix_crossing (int start, int end, int *active_segs, int n_active_segs,
- int *cursor, ArtPoint **ips, int *n_ips, int *n_ips_max,
- ArtSVP *vp, int *seg_map,
- ArtSVP **p_new_vp, int *pn_segs_max,
- int **pn_points_max)
-{
- int i, j;
- int target;
- int asi, asj;
- ArtPoint p0i, p1i;
- ArtPoint p0j, p1j;
- int swap = 0;
-#ifdef VERBOSE
- int k;
-#endif
- ArtPoint *pts;
-
-#ifdef VERBOSE
- printf ("fix_crossing: [%d..%d)", start, end);
- for (k = 0; k < n_active_segs; k++)
- printf (" %d", active_segs[k]);
- printf ("\n");
-#endif
-
- if (start == -1)
- return;
-
- for (i = start + 1; i < end; i++)
- {
-
- asi = active_segs[i];
- if (cursor[asi] < vp->segs[asi].n_points - 1) {
- p0i = ips[asi][0];
- if (n_ips[asi] == 1)
- p1i = vp->segs[asi].points[cursor[asi] + 1];
- else
- p1i = ips[asi][1];
-
- for (j = i - 1; j >= start; j--)
- {
- asj = active_segs[j];
- if (cursor[asj] < vp->segs[asj].n_points - 1)
- {
- p0j = ips[asj][0];
- if (n_ips[asj] == 1)
- p1j = vp->segs[asj].points[cursor[asj] + 1];
- else
- p1j = ips[asj][1];
-
- /* we _hope_ p0i = p0j */
- if (x_order_2 (p0j, p1j, p0i, p1i) == -1)
- break;
- }
- }
-
- target = j + 1;
- /* target is where active_seg[i] _should_ be in active_segs */
-
- if (target != i)
- {
- swap = 1;
-
-#ifdef VERBOSE
- printf ("fix_crossing: at %i should be %i\n", i, target);
-#endif
-
- /* let's close off all relevant segments */
- for (j = i; j >= target; j--)
- {
- asi = active_segs[j];
- /* First conjunct: this isn't the last point in the original
- segment.
-
- Second conjunct: this isn't the first point in the new
- segment (i.e. already broken).
- */
- if (cursor[asi] < vp->segs[asi].n_points - 1 &&
- (*p_new_vp)->segs[seg_map[asi]].n_points != 1)
- {
- int seg_num;
- /* so break here */
-#ifdef VERBOSE
- printf ("closing off %d\n", j);
-#endif
-
- pts = art_new (ArtPoint, 16);
- pts[0] = ips[asi][0];
- seg_num = art_svp_add_segment (p_new_vp, pn_segs_max,
- pn_points_max,
- 1, vp->segs[asi].dir,
- pts,
- NULL);
- (*pn_points_max)[seg_num] = 16;
- seg_map[asi] = seg_num;
- }
- }
-
- /* now fix the ordering in active_segs */
- asi = active_segs[i];
- for (j = i; j > target; j--)
- active_segs[j] = active_segs[j - 1];
- active_segs[j] = asi;
- }
- }
- }
- if (swap && start > 0)
- {
- int as_start;
-
- as_start = active_segs[start];
- if (cursor[as_start] < vp->segs[as_start].n_points)
- {
-#ifdef VERBOSE
- printf ("checking intersection of %d, %d\n", start - 1, start);
-#endif
- intersect_neighbors (start, active_segs,
- n_ips, n_ips_max, ips,
- cursor, vp);
- }
- }
-
- if (swap && end < n_active_segs)
- {
- int as_end;
-
- as_end = active_segs[end - 1];
- if (cursor[as_end] < vp->segs[as_end].n_points)
- {
-#ifdef VERBOSE
- printf ("checking intersection of %d, %d\n", end - 1, end);
-#endif
- intersect_neighbors (end, active_segs,
- n_ips, n_ips_max, ips,
- cursor, vp);
- }
- }
- if (swap)
- {
-#ifdef VERBOSE
- printf ("fix_crossing return: [%d..%d)", start, end);
- for (k = 0; k < n_active_segs; k++)
- printf (" %d", active_segs[k]);
- printf ("\n");
-#endif
- }
-}
-
-/* Return a new sorted vector that covers the same area as the
- argument, but which satisfies the nocross invariant.
-
- Basically, this routine works by finding the intersection points,
- and cutting the segments at those points.
-
- Status of this routine:
-
- Basic correctness: Seems ok.
-
- Numerical stability: known problems in the case of points falling
- on lines, and colinear lines. For actual use, randomly perturbing
- the vertices is currently recommended.
-
- Speed: pretty good, although a more efficient priority queue, as
- well as bbox culling of potential intersections, are two
- optimizations that could help.
-
- Precision: pretty good, although the numerical stability problems
- make this routine unsuitable for precise calculations of
- differences.
-
-*/
-
-/* Here is a more detailed description of the algorithm. It follows
- roughly the structure of traverse (above), but is obviously quite
- a bit more complex.
-
- Here are a few important data structures:
-
- A new sorted vector path (new_svp).
-
- For each (active) segment in the original, a list of intersection
- points.
-
- Of course, the original being traversed.
-
- The following invariants hold (in addition to the invariants
- of the traverse procedure).
-
- The new sorted vector path lies entirely above the y scan line.
-
- The new sorted vector path keeps the nocross invariant.
-
- For each active segment, the y scan line crosses the line from the
- first to the second of the intersection points (where the second
- point is cursor + 1 if there is only one intersection point).
-
- The list of intersection points + the (cursor + 1) point is kept
- in nondecreasing y order.
-
- Of the active segments, none of the lines from first to second
- intersection point cross the 1st ip..2nd ip line of the left or
- right neighbor. (However, such a line may cross further
- intersection points of the neighbors, or segments past the
- immediate neighbors).
-
- Of the active segments, all lines from 1st ip..2nd ip are in
- strictly increasing x_order (this is very similar to the invariant
- of the traverse procedure, but is explicitly stated here in terms
- of ips). (this basically says that nocross holds on the active
- segments)
-
- The combination of the new sorted vector path, the path through all
- the intersection points to cursor + 1, and [cursor + 1, n_points)
- covers the same area as the argument.
-
- Another important data structure is mapping from original segment
- number to new segment number.
-
- The algorithm is perhaps best understood as advancing the cursors
- while maintaining these invariants. Here's roughly how it's done.
-
- When deleting segments from the active list, those segments are added
- to the new sorted vector path. In addition, the neighbors may intersect
- each other, so they are intersection tested (see below).
-
- When inserting new segments, they are intersection tested against
- their neighbors. The top point of the segment becomes the first
- intersection point.
-
- Advancing the cursor is just a bit different from the traverse
- routine, as the cursor may advance through the intersection points
- as well. Only when there is a single intersection point in the list
- does the cursor advance in the original segment. In either case,
- the new vector is intersection tested against both neighbors. It
- also causes the vector over which the cursor is advancing to be
- added to the new svp.
-
- Two steps need further clarification:
-
- Intersection testing: the 1st ip..2nd ip lines of the neighbors
- are tested to see if they cross (using intersect_lines). If so,
- then the intersection point is added to the ip list of both
- segments, maintaining the invariant that the list of intersection
- points is nondecreasing in y).
-
- Adding vector to new svp: if the new vector shares a top x
- coordinate with another vector, then it is checked to see whether
- it is in order. If not, then both segments are "broken," and then
- restarted. Note: in the case when both segments are in the same
- order, they may simply be swapped without breaking.
-
- For the time being, I'm going to put some of these operations into
- subroutines. If it turns out to be a performance problem, I could
- try to reorganize the traverse procedure so that each is only
- called once, and inline them. But if it's not a performance
- problem, I'll just keep it this way, because it will probably help
- to make the code clearer, and I believe this code could use all the
- clarity it can get. */
-/**
- * art_svp_uncross: Resolve self-intersections of an svp.
- * @vp: The original svp.
- *
- * Finds all the intersections within @vp, and constructs a new svp
- * with new points added at these intersections.
- *
- * This routine needs to be redone from scratch with numerical robustness
- * in mind. I'm working on it.
- *
- * Return value: The new svp.
- **/
-ArtSVP *
-art_svp_uncross (ArtSVP *vp)
-{
- int *active_segs;
- int n_active_segs;
- int *cursor;
- int seg_idx;
- double y;
- int tmp1, tmp2;
- int asi;
- int i, j;
- /* new data structures */
- /* intersection points; invariant: *ips[i] is only allocated if
- i is active */
- int *n_ips, *n_ips_max;
- ArtPoint **ips;
- /* new sorted vector path */
- int n_segs_max, seg_num;
- ArtSVP *new_vp;
- int *n_points_max;
- /* mapping from argument to new segment numbers - again, only valid
- if active */
- int *seg_map;
- double y_curs;
- ArtPoint p_curs;
- int first_share;
- double share_x;
- ArtPoint *pts;
-
- n_segs_max = 16;
- new_vp = (ArtSVP *)art_alloc (sizeof(ArtSVP) +
- (n_segs_max - 1) * sizeof(ArtSVPSeg));
- new_vp->n_segs = 0;
-
- if (vp->n_segs == 0)
- return new_vp;
-
- active_segs = art_new (int, vp->n_segs);
- cursor = art_new (int, vp->n_segs);
-
- seg_map = art_new (int, vp->n_segs);
- n_ips = art_new (int, vp->n_segs);
- n_ips_max = art_new (int, vp->n_segs);
- ips = art_new (ArtPoint *, vp->n_segs);
-
- n_points_max = art_new (int, n_segs_max);
-
- n_active_segs = 0;
- seg_idx = 0;
- y = vp->segs[0].points[0].y;
- while (seg_idx < vp->n_segs || n_active_segs > 0)
- {
-#ifdef VERBOSE
- printf ("y = %g\n", y);
-#endif
-
- /* maybe move deletions to end of loop (to avoid so much special
- casing on the end of a segment)? */
-
- /* delete segments ending at y from active list */
- for (i = 0; i < n_active_segs; i++)
- {
- asi = active_segs[i];
- if (vp->segs[asi].n_points - 1 == cursor[asi] &&
- vp->segs[asi].points[cursor[asi]].y == y)
- {
- do
- {
-#ifdef VERBOSE
- printf ("deleting %d\n", asi);
-#endif
- art_free (ips[asi]);
- n_active_segs--;
- for (j = i; j < n_active_segs; j++)
- active_segs[j] = active_segs[j + 1];
- if (i < n_active_segs)
- asi = active_segs[i];
- else
- break;
- }
- while (vp->segs[asi].n_points - 1 == cursor[asi] &&
- vp->segs[asi].points[cursor[asi]].y == y);
-
- /* test intersection of neighbors */
- if (i > 0 && i < n_active_segs)
- intersect_neighbors (i, active_segs,
- n_ips, n_ips_max, ips,
- cursor, vp);
-
- i--;
- }
- }
-
- /* insert new segments into the active list */
- while (seg_idx < vp->n_segs && y == vp->segs[seg_idx].points[0].y)
- {
-#ifdef VERBOSE
- printf ("inserting %d\n", seg_idx);
-#endif
- cursor[seg_idx] = 0;
- for (i = 0; i < n_active_segs; i++)
- {
- asi = active_segs[i];
- if (x_order_2 (vp->segs[seg_idx].points[0],
- vp->segs[seg_idx].points[1],
- vp->segs[asi].points[cursor[asi]],
- vp->segs[asi].points[cursor[asi] + 1]) == -1)
- break;
- }
-
- /* Create and initialize the intersection points data structure */
- n_ips[seg_idx] = 1;
- n_ips_max[seg_idx] = 2;
- ips[seg_idx] = art_new (ArtPoint, n_ips_max[seg_idx]);
- ips[seg_idx][0] = vp->segs[seg_idx].points[0];
-
- /* Start a new segment in the new vector path */
- pts = art_new (ArtPoint, 16);
- pts[0] = vp->segs[seg_idx].points[0];
- seg_num = art_svp_add_segment (&new_vp, &n_segs_max,
- &n_points_max,
- 1, vp->segs[seg_idx].dir,
- pts,
- NULL);
- n_points_max[seg_num] = 16;
- seg_map[seg_idx] = seg_num;
-
- tmp1 = seg_idx;
- for (j = i; j < n_active_segs; j++)
- {
- tmp2 = active_segs[j];
- active_segs[j] = tmp1;
- tmp1 = tmp2;
- }
- active_segs[n_active_segs] = tmp1;
- n_active_segs++;
-
- if (i > 0)
- intersect_neighbors (i, active_segs,
- n_ips, n_ips_max, ips,
- cursor, vp);
-
- if (i + 1 < n_active_segs)
- intersect_neighbors (i + 1, active_segs,
- n_ips, n_ips_max, ips,
- cursor, vp);
-
- seg_idx++;
- }
-
- /* all active segs cross the y scanline (considering segs to be
- closed on top and open on bottom) */
-#ifdef VERBOSE
- for (i = 0; i < n_active_segs; i++)
- {
- asi = active_segs[i];
- printf ("%d ", asi);
- for (j = 0; j < n_ips[asi]; j++)
- printf ("(%g, %g) - ",
- ips[asi][j].x,
- ips[asi][j].y);
- printf ("(%g, %g) %s\n",
- vp->segs[asi].points[cursor[asi] + 1].x,
- vp->segs[asi].points[cursor[asi] + 1].y,
- vp->segs[asi].dir ? "v" : "^");
- }
-#endif
-
- /* advance y to the next event
- Note: this is quadratic. We'd probably get decent constant
- factor speed improvement by caching the y_curs values. */
- if (n_active_segs == 0)
- {
- if (seg_idx < vp->n_segs)
- y = vp->segs[seg_idx].points[0].y;
- /* else we're done */
- }
- else
- {
- asi = active_segs[0];
- if (n_ips[asi] == 1)
- y = vp->segs[asi].points[cursor[asi] + 1].y;
- else
- y = ips[asi][1].y;
- for (i = 1; i < n_active_segs; i++)
- {
- asi = active_segs[i];
- if (n_ips[asi] == 1)
- y_curs = vp->segs[asi].points[cursor[asi] + 1].y;
- else
- y_curs = ips[asi][1].y;
- if (y > y_curs)
- y = y_curs;
- }
- if (seg_idx < vp->n_segs && y > vp->segs[seg_idx].points[0].y)
- y = vp->segs[seg_idx].points[0].y;
- }
-
- first_share = -1;
- share_x = 0; /* to avoid gcc warning, although share_x is never
- used when first_share is -1 */
- /* advance cursors to reach new y */
- for (i = 0; i < n_active_segs; i++)
- {
- asi = active_segs[i];
- if (n_ips[asi] == 1)
- p_curs = vp->segs[asi].points[cursor[asi] + 1];
- else
- p_curs = ips[asi][1];
- if (p_curs.y == y)
- {
- svp_add_point (new_vp, n_points_max,
- p_curs, seg_map, active_segs, n_active_segs, i);
-
- n_ips[asi]--;
- for (j = 0; j < n_ips[asi]; j++)
- ips[asi][j] = ips[asi][j + 1];
-
- if (n_ips[asi] == 0)
- {
- ips[asi][0] = p_curs;
- n_ips[asi] = 1;
- cursor[asi]++;
- }
-
- if (first_share < 0 || p_curs.x != share_x)
- {
- /* this is where crossings are detected, and if
- found, the active segments switched around. */
-
- fix_crossing (first_share, i,
- active_segs, n_active_segs,
- cursor, ips, n_ips, n_ips_max, vp, seg_map,
- &new_vp,
- &n_segs_max, &n_points_max);
-
- first_share = i;
- share_x = p_curs.x;
- }
-
- if (cursor[asi] < vp->segs[asi].n_points - 1)
- {
-
- if (i > 0)
- intersect_neighbors (i, active_segs,
- n_ips, n_ips_max, ips,
- cursor, vp);
-
- if (i + 1 < n_active_segs)
- intersect_neighbors (i + 1, active_segs,
- n_ips, n_ips_max, ips,
- cursor, vp);
- }
- }
- else
- {
- /* not on a cursor point */
- fix_crossing (first_share, i,
- active_segs, n_active_segs,
- cursor, ips, n_ips, n_ips_max, vp, seg_map,
- &new_vp,
- &n_segs_max, &n_points_max);
- first_share = -1;
- }
- }
-
- /* fix crossing on last shared group */
- fix_crossing (first_share, i,
- active_segs, n_active_segs,
- cursor, ips, n_ips, n_ips_max, vp, seg_map,
- &new_vp,
- &n_segs_max, &n_points_max);
-
-#ifdef VERBOSE
- printf ("\n");
-#endif
- }
-
- /* not necessary to sort, new segments only get added at y, which
- increases monotonically */
-#if 0
- qsort (&new_vp->segs, new_vp->n_segs, sizeof (svp_seg), svp_seg_compare);
- {
- int k;
- for (k = 0; k < new_vp->n_segs - 1; k++)
- {
- printf ("(%g, %g) - (%g, %g) %s (%g, %g) - (%g, %g)\n",
- new_vp->segs[k].points[0].x,
- new_vp->segs[k].points[0].y,
- new_vp->segs[k].points[1].x,
- new_vp->segs[k].points[1].y,
- svp_seg_compare (&new_vp->segs[k], &new_vp->segs[k + 1]) > 1 ? ">": "<",
- new_vp->segs[k + 1].points[0].x,
- new_vp->segs[k + 1].points[0].y,
- new_vp->segs[k + 1].points[1].x,
- new_vp->segs[k + 1].points[1].y);
- }
- }
-#endif
-
- art_free (n_points_max);
- art_free (seg_map);
- art_free (n_ips_max);
- art_free (n_ips);
- art_free (ips);
- art_free (cursor);
- art_free (active_segs);
-
- return new_vp;
-}
-
-#define noVERBOSE
-
-/* Rewind a svp satisfying the nocross invariant.
-
- The winding number of a segment is defined as the winding number of
- the points to the left while travelling in the direction of the
- segment. Therefore it preincrements and postdecrements as a scan
- line is traversed from left to right.
-
- Status of this routine:
-
- Basic correctness: Was ok in gfonted. However, this code does not
- yet compute bboxes for the resulting svp segs.
-
- Numerical stability: known problems in the case of horizontal
- segments in polygons with any complexity. For actual use, randomly
- perturbing the vertices is recommended.
-
- Speed: good.
-
- Precision: good, except that no attempt is made to remove "hair".
- Doing random perturbation just makes matters worse.
-
-*/
-/**
- * art_svp_rewind_uncrossed: Rewind an svp satisfying the nocross invariant.
- * @vp: The original svp.
- * @rule: The winding rule.
- *
- * Creates a new svp with winding number of 0 or 1 everywhere. The @rule
- * argument specifies a rule for how winding numbers in the original
- * @vp map to the winding numbers in the result.
- *
- * With @rule == ART_WIND_RULE_NONZERO, the resulting svp has a
- * winding number of 1 where @vp has a nonzero winding number.
- *
- * With @rule == ART_WIND_RULE_INTERSECT, the resulting svp has a
- * winding number of 1 where @vp has a winding number greater than
- * 1. It is useful for computing intersections.
- *
- * With @rule == ART_WIND_RULE_ODDEVEN, the resulting svp has a
- * winding number of 1 where @vp has an odd winding number. It is
- * useful for implementing the even-odd winding rule of the
- * PostScript imaging model.
- *
- * With @rule == ART_WIND_RULE_POSITIVE, the resulting svp has a
- * winding number of 1 where @vp has a positive winding number. It is
- * useful for implementing asymmetric difference.
- *
- * This routine needs to be redone from scratch with numerical robustness
- * in mind. I'm working on it.
- *
- * Return value: The new svp.
- **/
-ArtSVP *
-art_svp_rewind_uncrossed (ArtSVP *vp, ArtWindRule rule)
-{
- int *active_segs;
- int n_active_segs;
- int *cursor;
- int seg_idx;
- double y;
- int tmp1, tmp2;
- int asi;
- int i, j;
-
- ArtSVP *new_vp;
- int n_segs_max;
- int *winding;
- int left_wind;
- int wind;
- int keep, invert;
-
-#ifdef VERBOSE
- print_svp (vp);
-#endif
- n_segs_max = 16;
- new_vp = (ArtSVP *)art_alloc (sizeof(ArtSVP) +
- (n_segs_max - 1) * sizeof(ArtSVPSeg));
- new_vp->n_segs = 0;
-
- if (vp->n_segs == 0)
- return new_vp;
-
- winding = art_new (int, vp->n_segs);
-
- active_segs = art_new (int, vp->n_segs);
- cursor = art_new (int, vp->n_segs);
-
- n_active_segs = 0;
- seg_idx = 0;
- y = vp->segs[0].points[0].y;
- while (seg_idx < vp->n_segs || n_active_segs > 0)
- {
-#ifdef VERBOSE
- printf ("y = %g\n", y);
-#endif
- /* delete segments ending at y from active list */
- for (i = 0; i < n_active_segs; i++)
- {
- asi = active_segs[i];
- if (vp->segs[asi].n_points - 1 == cursor[asi] &&
- vp->segs[asi].points[cursor[asi]].y == y)
- {
-#ifdef VERBOSE
- printf ("deleting %d\n", asi);
-#endif
- n_active_segs--;
- for (j = i; j < n_active_segs; j++)
- active_segs[j] = active_segs[j + 1];
- i--;
- }
- }
-
- /* insert new segments into the active list */
- while (seg_idx < vp->n_segs && y == vp->segs[seg_idx].points[0].y)
- {
-#ifdef VERBOSE
- printf ("inserting %d\n", seg_idx);
-#endif
- cursor[seg_idx] = 0;
- for (i = 0; i < n_active_segs; i++)
- {
- asi = active_segs[i];
- if (x_order_2 (vp->segs[seg_idx].points[0],
- vp->segs[seg_idx].points[1],
- vp->segs[asi].points[cursor[asi]],
- vp->segs[asi].points[cursor[asi] + 1]) == -1)
- break;
- }
-
- /* Determine winding number for this segment */
- if (i == 0)
- left_wind = 0;
- else if (vp->segs[active_segs[i - 1]].dir)
- left_wind = winding[active_segs[i - 1]];
- else
- left_wind = winding[active_segs[i - 1]] - 1;
-
- if (vp->segs[seg_idx].dir)
- wind = left_wind + 1;
- else
- wind = left_wind;
-
- winding[seg_idx] = wind;
-
- switch (rule)
- {
- case ART_WIND_RULE_NONZERO:
- keep = (wind == 1 || wind == 0);
- invert = (wind == 0);
- break;
- case ART_WIND_RULE_INTERSECT:
- keep = (wind == 2);
- invert = 0;
- break;
- case ART_WIND_RULE_ODDEVEN:
- keep = 1;
- invert = !(wind & 1);
- break;
- case ART_WIND_RULE_POSITIVE:
- keep = (wind == 1);
- invert = 0;
- break;
- default:
- keep = 0;
- invert = 0;
- break;
- }
-
- if (keep)
- {
- ArtPoint *points, *new_points;
- int n_points;
- int new_dir;
-
-#ifdef VERBOSE
- printf ("keeping segment %d\n", seg_idx);
-#endif
- n_points = vp->segs[seg_idx].n_points;
- points = vp->segs[seg_idx].points;
- new_points = art_new (ArtPoint, n_points);
- memcpy (new_points, points, n_points * sizeof (ArtPoint));
- new_dir = vp->segs[seg_idx].dir ^ invert;
- art_svp_add_segment (&new_vp, &n_segs_max,
- NULL,
- n_points, new_dir, new_points,
- &vp->segs[seg_idx].bbox);
- }
-
- tmp1 = seg_idx;
- for (j = i; j < n_active_segs; j++)
- {
- tmp2 = active_segs[j];
- active_segs[j] = tmp1;
- tmp1 = tmp2;
- }
- active_segs[n_active_segs] = tmp1;
- n_active_segs++;
- seg_idx++;
- }
-
-#ifdef VERBOSE
- /* all active segs cross the y scanline (considering segs to be
- closed on top and open on bottom) */
- for (i = 0; i < n_active_segs; i++)
- {
- asi = active_segs[i];
- printf ("%d:%d (%g, %g) - (%g, %g) %s %d\n", asi,
- cursor[asi],
- vp->segs[asi].points[cursor[asi]].x,
- vp->segs[asi].points[cursor[asi]].y,
- vp->segs[asi].points[cursor[asi] + 1].x,
- vp->segs[asi].points[cursor[asi] + 1].y,
- vp->segs[asi].dir ? "v" : "^",
- winding[asi]);
- }
-#endif
-
- /* advance y to the next event */
- if (n_active_segs == 0)
- {
- if (seg_idx < vp->n_segs)
- y = vp->segs[seg_idx].points[0].y;
- /* else we're done */
- }
- else
- {
- asi = active_segs[0];
- y = vp->segs[asi].points[cursor[asi] + 1].y;
- for (i = 1; i < n_active_segs; i++)
- {
- asi = active_segs[i];
- if (y > vp->segs[asi].points[cursor[asi] + 1].y)
- y = vp->segs[asi].points[cursor[asi] + 1].y;
- }
- if (seg_idx < vp->n_segs && y > vp->segs[seg_idx].points[0].y)
- y = vp->segs[seg_idx].points[0].y;
- }
-
- /* advance cursors to reach new y */
- for (i = 0; i < n_active_segs; i++)
- {
- asi = active_segs[i];
- while (cursor[asi] < vp->segs[asi].n_points - 1 &&
- y >= vp->segs[asi].points[cursor[asi] + 1].y)
- cursor[asi]++;
- }
-#ifdef VERBOSE
- printf ("\n");
-#endif
- }
- art_free (cursor);
- art_free (active_segs);
- art_free (winding);
-
- return new_vp;
-}
diff --git a/libart_lgpl/art_svp_wind.h b/libart_lgpl/art_svp_wind.h
index 0e9d5e70d4..fd999b4bb9 100644
--- a/libart_lgpl/art_svp_wind.h
+++ b/libart_lgpl/art_svp_wind.h
@@ -39,13 +39,6 @@ typedef enum {
} ArtWindRule;
#endif
-ArtSVP *
-art_svp_uncross (ArtSVP *vp);
-
-ArtSVP *
-art_svp_rewind_uncrossed (ArtSVP *vp, ArtWindRule rule);
-
-
#ifdef __cplusplus
}
#endif /* __cplusplus */
diff --git a/libart_lgpl/art_uta_ops.c b/libart_lgpl/art_uta_ops.c
deleted file mode 100644
index 1b4251607b..0000000000
--- a/libart_lgpl/art_uta_ops.c
+++ /dev/null
@@ -1,112 +0,0 @@
-/* Libart_LGPL - library of basic graphic primitives
- * Copyright (C) 1998-2000 Raph Levien
- *
- * This library 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 library 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 library; if not, write to the
- * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- */
-
-#include "config.h"
-#include "art_uta_ops.h"
-
-#include <string.h>
-#include "art_misc.h"
-#include "art_uta.h"
-
-#ifndef MIN
-#define MIN(a,b) ((a) < (b) ? (a) : (b))
-#endif
-
-#ifndef MAX
-#define MAX(a,b) ((a) > (b) ? (a) : (b))
-#endif
-
-/**
- * art_uta_union: Compute union of two uta's.
- * @uta1: One uta.
- * @uta2: The other uta.
- *
- * Computes the union of @uta1 and @uta2. The union is approximate,
- * but coverage is guaranteed over all pixels included in either of
- * the arguments, ie more pixels may be covered than the "exact"
- * union.
- *
- * Note: this routine is used in the Gnome Canvas to accumulate the
- * region that needs to be repainted. However, since it copies over
- * the entire uta (which might be largish) even when the update may be
- * small, it can be a performance bottleneck. There are two approaches
- * to this problem, both of which are probably worthwhile. First, the
- * generated uta's should always be limited to the visible window,
- * thus guaranteeing that uta's never become large. Second, there
- * should be a new, destructive union operation that only touches a
- * small part of the uta when the update is small.
- *
- * Return value: The new union uta.
- **/
-ArtUta *
-art_uta_union (ArtUta *uta1, ArtUta *uta2)
-{
- ArtUta *uta;
- int x0, y0, x1, y1;
- int x, y;
- int ix, ix1, ix2;
- ArtUtaBbox bb, bb1, bb2;
-
- x0 = MIN(uta1->x0, uta2->x0);
- y0 = MIN(uta1->y0, uta2->y0);
- x1 = MAX(uta1->x0 + uta1->width, uta2->x0 + uta2->width);
- y1 = MAX(uta1->y0 + uta1->height, uta2->y0 + uta2->height);
- uta = art_uta_new (x0, y0, x1, y1);
-
- /* could move the first two if/else statements out of the loop */
- ix = 0;
- for (y = y0; y < y1; y++)
- {
- ix1 = (y - uta1->y0) * uta1->width + x0 - uta1->x0;
- ix2 = (y - uta2->y0) * uta2->width + x0 - uta2->x0;
- for (x = x0; x < x1; x++)
- {
- if (x < uta1->x0 || y < uta1->y0 ||
- x >= uta1->x0 + uta1->width || y >= uta1->y0 + uta1->height)
- bb1 = 0;
- else
- bb1 = uta1->utiles[ix1];
-
- if (x < uta2->x0 || y < uta2->y0 ||
- x >= uta2->x0 + uta2->width || y >= uta2->y0 + uta2->height)
- bb2 = 0;
- else
- bb2 = uta2->utiles[ix2];
-
- if (bb1 == 0)
- bb = bb2;
- else if (bb2 == 0)
- bb = bb1;
- else
- bb = ART_UTA_BBOX_CONS(MIN(ART_UTA_BBOX_X0(bb1),
- ART_UTA_BBOX_X0(bb2)),
- MIN(ART_UTA_BBOX_Y0(bb1),
- ART_UTA_BBOX_Y0(bb2)),
- MAX(ART_UTA_BBOX_X1(bb1),
- ART_UTA_BBOX_X1(bb2)),
- MAX(ART_UTA_BBOX_Y1(bb1),
- ART_UTA_BBOX_Y1(bb2)));
- uta->utiles[ix] = bb;
- ix++;
- ix1++;
- ix2++;
- }
- }
- return uta;
-}
diff --git a/libart_lgpl/art_uta_ops.h b/libart_lgpl/art_uta_ops.h
deleted file mode 100644
index fc19d012ee..0000000000
--- a/libart_lgpl/art_uta_ops.h
+++ /dev/null
@@ -1,38 +0,0 @@
-/* Libart_LGPL - library of basic graphic primitives
- * Copyright (C) 1998 Raph Levien
- *
- * This library 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 library 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 library; if not, write to the
- * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- */
-
-#ifndef __ART_UTA_OPS_H__
-#define __ART_UTA_OPS_H__
-
-/* Basic operations on microtile arrays */
-
-#include <libart_lgpl/art_uta.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif /* __cplusplus */
-
-ArtUta *
-art_uta_union (ArtUta *uta1, ArtUta *uta2);
-
-#ifdef __cplusplus
-}
-#endif /* __cplusplus */
-
-#endif /* __ART_UTA_OPS_H__ */
diff --git a/libart_lgpl/art_vpath.c b/libart_lgpl/art_vpath.c
index fa7b903d11..5152188b1b 100644
--- a/libart_lgpl/art_vpath.c
+++ b/libart_lgpl/art_vpath.c
@@ -63,77 +63,6 @@ art_vpath_add_point (ArtVpath **p_vpath, int *pn_points, int *pn_points_max,
#define CIRCLE_STEPS 128
/**
- * art_vpath_new_circle: Create a new circle.
- * @x: X coordinate of center.
- * @y: Y coordinate of center.
- * @r: radius.
- *
- * Creates a new polygon closely approximating a circle with center
- * (@x, @y) and radius @r. Currently, the number of points used in the
- * approximation is fixed, but that will probably change.
- *
- * Return value: The newly created #ArtVpath.
- **/
-ArtVpath *
-art_vpath_new_circle (double x, double y, double r)
-{
- int i;
- ArtVpath *vec;
- double theta;
-
- vec = art_new (ArtVpath, CIRCLE_STEPS + 2);
-
- for (i = 0; i < CIRCLE_STEPS + 1; i++)
- {
- vec[i].code = i ? ART_LINETO : ART_MOVETO;
- theta = (i & (CIRCLE_STEPS - 1)) * (M_PI * 2.0 / CIRCLE_STEPS);
- vec[i].x = x + r * cos (theta);
- vec[i].y = y - r * sin (theta);
- }
- vec[i].code = ART_END;
-
- return vec;
-}
-
-/**
- * art_vpath_affine_transform: Affine transform a vpath.
- * @src: Source vpath to transform.
- * @matrix: Affine transform.
- *
- * Computes the affine transform of the vpath, using @matrix as the
- * transform. @matrix is stored in the same format as PostScript, ie.
- * x' = @matrix[0] * x + @matrix[2] * y + @matrix[4]
- * y' = @matrix[1] * x + @matrix[3] * y + @matrix[5]
- *
- * Return value: the newly allocated vpath resulting from the transform.
-**/
-ArtVpath *
-art_vpath_affine_transform (const ArtVpath *src, const double matrix[6])
-{
- int i;
- int size;
- ArtVpath *new;
- double x, y;
-
- for (i = 0; src[i].code != ART_END; i++);
- size = i;
-
- new = art_new (ArtVpath, size + 1);
-
- for (i = 0; i < size; i++)
- {
- new[i].code = src[i].code;
- x = src[i].x;
- y = src[i].y;
- new[i].x = matrix[0] * x + matrix[2] * y + matrix[4];
- new[i].y = matrix[1] * x + matrix[3] * y + matrix[5];
- }
- new[i].code = ART_END;
-
- return new;
-}
-
-/**
* art_vpath_bbox_drect: Determine bounding box of vpath.
* @vec: Source vpath.
* @drect: Where to store bounding box.
@@ -184,58 +113,3 @@ art_vpath_bbox_irect (const ArtVpath *vec, ArtIRect *irect)
art_drect_to_irect (irect, &drect);
}
-#define PERTURBATION 2e-3
-
-/**
- * art_vpath_perturb: Perturb each point in vpath by small random amount.
- * @src: Source vpath.
- *
- * Perturbs each of the points by a small random amount. This is
- * helpful for cheating in cases when algorithms haven't attained
- * numerical stability yet.
- *
- * Return value: Newly allocated vpath containing perturbed @src.
- **/
-ArtVpath *
-art_vpath_perturb (ArtVpath *src)
-{
- int i;
- int size;
- ArtVpath *new;
- double x, y;
- double x_start, y_start;
- int open;
-
- for (i = 0; src[i].code != ART_END; i++);
- size = i;
-
- new = art_new (ArtVpath, size + 1);
-
- x_start = 0;
- y_start = 0;
- open = 0;
- for (i = 0; i < size; i++)
- {
- new[i].code = src[i].code;
- x = src[i].x + (PERTURBATION * rand ()) / RAND_MAX - PERTURBATION * 0.5;
- y = src[i].y + (PERTURBATION * rand ()) / RAND_MAX - PERTURBATION * 0.5;
- if (src[i].code == ART_MOVETO)
- {
- x_start = x;
- y_start = y;
- open = 0;
- }
- else if (src[i].code == ART_MOVETO_OPEN)
- open = 1;
- if (!open && (i + 1 == size || src[i + 1].code != ART_LINETO))
- {
- x = x_start;
- y = y_start;
- }
- new[i].x = x;
- new[i].y = y;
- }
- new[i].code = ART_END;
-
- return new;
-}
diff --git a/libart_lgpl/art_vpath.h b/libart_lgpl/art_vpath.h
index 4102d28908..f5557f6005 100644
--- a/libart_lgpl/art_vpath.h
+++ b/libart_lgpl/art_vpath.h
@@ -44,21 +44,12 @@ void
art_vpath_add_point (ArtVpath **p_vpath, int *pn_points, int *pn_points_max,
ArtPathcode code, double x, double y);
-ArtVpath *
-art_vpath_new_circle (double x, double y, double r);
-
-ArtVpath *
-art_vpath_affine_transform (const ArtVpath *src, const double matrix[6]);
-
void
art_vpath_bbox_drect (const ArtVpath *vec, ArtDRect *drect);
void
art_vpath_bbox_irect (const ArtVpath *vec, ArtIRect *irect);
-ArtVpath *
-art_vpath_perturb (ArtVpath *src);
-
#ifdef __cplusplus
}
#endif /* __cplusplus */
diff --git a/libart_lgpl/libart.h b/libart_lgpl/libart.h
index 4a9eeea60a..6d93588bf5 100644
--- a/libart_lgpl/libart.h
+++ b/libart_lgpl/libart.h
@@ -27,7 +27,6 @@
#include <libart_lgpl/art_svp_vpath_stroke.h>
#include <libart_lgpl/art_svp_wind.h>
#include <libart_lgpl/art_uta.h>
-#include <libart_lgpl/art_uta_ops.h>
#include <libart_lgpl/art_uta_rect.h>
#include <libart_lgpl/art_uta_svp.h>
#include <libart_lgpl/art_uta_vpath.h>
diff --git a/libgnomecanvas/gnome-canvas-text.c b/libgnomecanvas/gnome-canvas-text.c
index c7e58aef0d..93a7aad917 100644
--- a/libgnomecanvas/gnome-canvas-text.c
+++ b/libgnomecanvas/gnome-canvas-text.c
@@ -42,9 +42,7 @@
#include <pango/pangoft2.h>
#include <libart_lgpl/art_affine.h>
-#include <libart_lgpl/art_rgb_a_affine.h>
#include <libart_lgpl/art_rgb.h>
-#include <libart_lgpl/art_rgb_bitmap_affine.h>
#include "gnome-canvas-util.h"
#include "gnome-canvas-i18n.h"
diff --git a/libgnomecanvas/gnome-canvas.c b/libgnomecanvas/gnome-canvas.c
index 3241283719..d89eb19fa7 100644
--- a/libgnomecanvas/gnome-canvas.c
+++ b/libgnomecanvas/gnome-canvas.c
@@ -86,7 +86,6 @@
#include <libart_lgpl/art_rect.h>
#include <libart_lgpl/art_rect_uta.h>
#include <libart_lgpl/art_uta_rect.h>
-#include <libart_lgpl/art_uta_ops.h>
#include "gnome-canvas-marshal.h"
#include "gnome-canvas-marshal.c"