summaryrefslogtreecommitdiff
path: root/editors/openoffice.org-1.0/files/gpc-libart-patch
diff options
context:
space:
mode:
Diffstat (limited to 'editors/openoffice.org-1.0/files/gpc-libart-patch')
-rw-r--r--editors/openoffice.org-1.0/files/gpc-libart-patch4380
1 files changed, 0 insertions, 4380 deletions
diff --git a/editors/openoffice.org-1.0/files/gpc-libart-patch b/editors/openoffice.org-1.0/files/gpc-libart-patch
deleted file mode 100644
index 759cbc89249d..000000000000
--- a/editors/openoffice.org-1.0/files/gpc-libart-patch
+++ /dev/null
@@ -1,4380 +0,0 @@
-taken from
-http://cvs.gnome.org/viewcvs/*checkout*/openoffice/patches/OOO_1_0_3/gpc-libart.diff
-
-diff -u -r1.41.2.7 configure.in
---- config_office/configure.in 2002/08/16 09:59:41 1.41.2.7
-+++ config_office/configure.in 2002/10/02 00:57:24
-@@ -1075,25 +1074,20 @@
- fi
-
- dnl ===================================================================
--dnl Test for the presence of the required gpc.{c,h} files
-+dnl Test for the presence of the required libart files
- dnl ===================================================================
-
--AC_MSG_CHECKING([GPC files])
--if test -f ../external/gpc/gpc.h; then
-- HAVE_GPC_H="yes"
-+AC_MSG_CHECKING([libart files])
-+if test -f ../external/gpc/art_svp.h; then
-+ HAVE_LIBART="yes"
- else
-- HAVE_GPC_H="no"
-+ HAVE_LIBART="no"
- fi
--if test -f ../external/gpc/gpc.c; then
-- HAVE_GPC_C="yes"
--else
-- HAVE_GPC_C="no"
--fi
-
--if test "$HAVE_GPC_H" = "yes" -a "$HAVE_GPC_C" = "yes"; then
-- AC_MSG_RESULT([GPC files found])
-+if test "$HAVE_LIBART" = "yes" ; then
-+ AC_MSG_RESULT([libart files found])
- else
-- AC_MSG_ERROR([GPC files not found])
-+ AC_MSG_ERROR([libart files not found -- did you apply the Ximian patch?])
- fi
-
- dnl ===================================================================
-diff -uNr /oocvs/OOO_STABLE_1-backup/external/gpc/art_config.h external/gpc/art_config.h
---- /oocvs/OOO_STABLE_1-backup/external/gpc/art_config.h Wed Dec 31 18:00:00 1969
-+++ external/gpc/art_config.h Fri Sep 20 21:41:27 2002
-@@ -0,0 +1,8 @@
-+#define ART_SIZEOF_CHAR (sizeof char)
-+#define ART_SIZEOF_SHORT (sizeof short)
-+#define ART_SIZEOF_INT (sizeof int)
-+#define ART_SIZEOF_LONG (sizeof long)
-+
-+typedef unsigned char art_u8;
-+typedef unsigned short art_u16;
-+typedef unsigned int art_u32;
-diff -uNr /oocvs/OOO_STABLE_1-backup/external/gpc/art_misc.c external/gpc/art_misc.c
---- /oocvs/OOO_STABLE_1-backup/external/gpc/art_misc.c Wed Dec 31 18:00:00 1969
-+++ external/gpc/art_misc.c Fri Sep 20 16:00:43 2002
-@@ -0,0 +1,78 @@
-+/* 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.
-+ */
-+
-+/* Various utility functions RLL finds useful. */
-+
-+#include "art_misc.h"
-+
-+#ifdef HAVE_UINSTD_H
-+#include <unistd.h>
-+#endif
-+#include <stdio.h>
-+#include <stdarg.h>
-+
-+/**
-+ * art_die: Print the error message to stderr and exit with a return code of 1.
-+ * @fmt: The printf-style format for the error message.
-+ *
-+ * Used for dealing with severe errors.
-+ **/
-+void
-+art_die (const char *fmt, ...)
-+{
-+ va_list ap;
-+
-+ va_start (ap, fmt);
-+ vfprintf (stderr, fmt, ap);
-+ va_end (ap);
-+ exit (1);
-+}
-+
-+/**
-+ * art_warn: Print the warning message to stderr.
-+ * @fmt: The printf-style format for the warning message.
-+ *
-+ * Used for generating warnings.
-+ **/
-+void
-+art_warn (const char *fmt, ...)
-+{
-+ va_list ap;
-+
-+ va_start (ap, fmt);
-+ vfprintf (stderr, fmt, ap);
-+ va_end (ap);
-+}
-+
-+/**
-+ * art_dprint: Print the debug message to stderr.
-+ * @fmt: The printf-style format for the debug message.
-+ *
-+ * Used for generating debug output.
-+ **/
-+void
-+art_dprint (const char *fmt, ...)
-+{
-+ va_list ap;
-+
-+ va_start (ap, fmt);
-+ vfprintf (stderr, fmt, ap);
-+ va_end (ap);
-+}
-+
-diff -uNr /oocvs/OOO_STABLE_1-backup/external/gpc/art_misc.h external/gpc/art_misc.h
---- /oocvs/OOO_STABLE_1-backup/external/gpc/art_misc.h Wed Dec 31 18:00:00 1969
-+++ external/gpc/art_misc.h Fri Sep 20 21:36:13 2002
-@@ -0,0 +1,89 @@
-+/* 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.
-+ */
-+
-+/* Simple macros to set up storage allocation and basic types for libart
-+ functions. */
-+
-+#ifndef __ART_MISC_H__
-+#define __ART_MISC_H__
-+
-+#include <stdlib.h> /* for malloc, etc. */
-+
-+#include "art_config.h"
-+
-+#define art_alloc malloc
-+#define art_free free
-+#define art_realloc realloc
-+
-+/* These aren't, strictly speaking, configuration macros, but they're
-+ damn handy to have around, and may be worth playing with for
-+ debugging. */
-+#define art_new(type, n) ((type *)art_alloc ((n) * sizeof(type)))
-+
-+#define art_renew(p, type, n) ((type *)art_realloc (p, (n) * sizeof(type)))
-+
-+/* This one must be used carefully - in particular, p and max should
-+ be variables. They can also be pstruct->el lvalues. */
-+#define art_expand(p, type, max) do { if(max) { p = art_renew (p, type, max <<= 1); } else { max = 1; p = art_new(type, 1); } } while (0)
-+
-+typedef int art_boolean;
-+#define ART_FALSE 0
-+#define ART_TRUE 1
-+
-+/* define pi */
-+#ifndef M_PI
-+#define M_PI 3.14159265358979323846
-+#endif /* M_PI */
-+
-+#ifndef M_SQRT2
-+#define M_SQRT2 1.41421356237309504880 /* sqrt(2) */
-+#endif /* M_SQRT2 */
-+
-+/* Provide macros to feature the GCC function attribute.
-+ */
-+#if defined(__GNUC__) && (__GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ > 4))
-+#define ART_GNUC_PRINTF( format_idx, arg_idx ) \
-+ __attribute__((format (printf, format_idx, arg_idx)))
-+#define ART_GNUC_NORETURN \
-+ __attribute__((noreturn))
-+#else /* !__GNUC__ */
-+#define ART_GNUC_PRINTF( format_idx, arg_idx )
-+#define ART_GNUC_NORETURN
-+#endif /* !__GNUC__ */
-+
-+#ifdef __cplusplus
-+extern "C" {
-+#endif
-+
-+void ART_GNUC_NORETURN
-+art_die (const char *fmt, ...) ART_GNUC_PRINTF (1, 2);
-+
-+void
-+art_warn (const char *fmt, ...) ART_GNUC_PRINTF (1, 2);
-+
-+void
-+art_dprint (const char *fmt, ...) ART_GNUC_PRINTF (1, 2);
-+
-+#ifdef __cplusplus
-+}
-+#endif
-+
-+#define ART_USE_NEW_INTERSECTOR
-+
-+#endif /* __ART_MISC_H__ */
-diff -uNr /oocvs/OOO_STABLE_1-backup/external/gpc/art_pathcode.h external/gpc/art_pathcode.h
---- /oocvs/OOO_STABLE_1-backup/external/gpc/art_pathcode.h Wed Dec 31 18:00:00 1969
-+++ external/gpc/art_pathcode.h Fri Sep 20 15:30:03 2002
-@@ -0,0 +1,39 @@
-+/* 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_PATHCODE_H__
-+#define __ART_PATHCODE_H__
-+
-+#ifdef __cplusplus
-+extern "C" {
-+#endif /* __cplusplus */
-+
-+typedef enum {
-+ ART_MOVETO,
-+ ART_MOVETO_OPEN,
-+ ART_CURVETO,
-+ ART_LINETO,
-+ ART_END
-+} ArtPathcode;
-+
-+#ifdef __cplusplus
-+}
-+#endif /* __cplusplus */
-+
-+#endif /* __ART_PATHCODE_H__ */
-diff -uNr /oocvs/OOO_STABLE_1-backup/external/gpc/art_point.h external/gpc/art_point.h
---- /oocvs/OOO_STABLE_1-backup/external/gpc/art_point.h Wed Dec 31 18:00:00 1969
-+++ external/gpc/art_point.h Fri Sep 20 16:02:16 2002
-@@ -0,0 +1,38 @@
-+/* 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_POINT_H__
-+#define __ART_POINT_H__
-+
-+#ifdef __cplusplus
-+extern "C" {
-+#endif /* __cplusplus */
-+
-+typedef struct _ArtPoint ArtPoint;
-+
-+struct _ArtPoint {
-+ /*< public >*/
-+ double x, y;
-+};
-+
-+#ifdef __cplusplus
-+}
-+#endif /* __cplusplus */
-+
-+#endif /* __ART_POINT_H__ */
-diff -uNr /oocvs/OOO_STABLE_1-backup/external/gpc/art_rect.c external/gpc/art_rect.c
---- /oocvs/OOO_STABLE_1-backup/external/gpc/art_rect.c Wed Dec 31 18:00:00 1969
-+++ external/gpc/art_rect.c Fri Sep 20 16:01:29 2002
-@@ -0,0 +1,214 @@
-+/* 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 "art_rect.h"
-+
-+#include <math.h>
-+
-+#ifndef MAX
-+#define MAX(a, b) (((a) > (b)) ? (a) : (b))
-+#endif /* MAX */
-+
-+#ifndef MIN
-+#define MIN(a, b) (((a) < (b)) ? (a) : (b))
-+#endif /* MIN */
-+
-+/* rectangle primitives stolen from gzilla */
-+
-+/**
-+ * art_irect_copy: Make a copy of an integer rectangle.
-+ * @dest: Where the copy is stored.
-+ * @src: The source rectangle.
-+ *
-+ * Copies the rectangle.
-+ **/
-+void
-+art_irect_copy (ArtIRect *dest, const ArtIRect *src) {
-+ dest->x0 = src->x0;
-+ dest->y0 = src->y0;
-+ dest->x1 = src->x1;
-+ dest->y1 = src->y1;
-+}
-+
-+/**
-+ * 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.
-+ * @src2: Another source rectangle.
-+ *
-+ * Finds the intersection of @src1 and @src2.
-+ **/
-+void
-+art_irect_intersect (ArtIRect *dest, const ArtIRect *src1, const ArtIRect *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 integer rectangle is empty.
-+ * @src: The source rectangle.
-+ *
-+ * Return value: TRUE if @src is an empty rectangle, FALSE otherwise.
-+ **/
-+int
-+art_irect_empty (const ArtIRect *src) {
-+ return (src->x1 <= src->x0 || src->y1 <= src->y0);
-+}
-+
-+#if 0
-+gboolean irect_point_inside (ArtIRect *rect, GzwPoint *point) {
-+ return (point->x >= rect->x0 && point->y >= rect->y0 &&
-+ point->x < rect->x1 && point->y < rect->y1);
-+}
-+#endif
-+
-+/**
-+ * art_drect_copy: Make a copy of a rectangle.
-+ * @dest: Where the copy is stored.
-+ * @src: The source rectangle.
-+ *
-+ * Copies the rectangle.
-+ **/
-+void
-+art_drect_copy (ArtDRect *dest, const ArtDRect *src) {
-+ dest->x0 = src->x0;
-+ dest->y0 = src->y0;
-+ dest->x1 = src->x1;
-+ dest->y1 = src->y1;
-+}
-+
-+/**
-+ * art_drect_union: Find union of two 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_drect_union (ArtDRect *dest, const ArtDRect *src1, const ArtDRect *src2) {
-+ if (art_drect_empty (src1)) {
-+ art_drect_copy (dest, src2);
-+ } else if (art_drect_empty (src2)) {
-+ art_drect_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_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.
-+ *
-+ * Return value: TRUE if @src is an empty rectangle, FALSE otherwise.
-+ **/
-+int
-+art_drect_empty (const ArtDRect *src) {
-+ return (src->x1 <= src->x0 || src->y1 <= src->y0);
-+}
-+
-+/**
-+ * art_drect_affine_transform: Affine transform rectangle.
-+ * @dst: Where to store the result.
-+ * @src: The source rectangle.
-+ * @matrix: The affine transformation.
-+ *
-+ * Find the smallest rectangle enclosing the affine transformed @src.
-+ * The result is exactly the affine transformation of @src when
-+ * @matrix specifies a rectilinear affine transformation, otherwise it
-+ * is a conservative approximation.
-+ **/
-+void
-+art_drect_affine_transform (ArtDRect *dst, const ArtDRect *src, const double matrix[6])
-+{
-+ double x00, y00, x10, y10;
-+ double x01, y01, x11, y11;
-+
-+ x00 = src->x0 * matrix[0] + src->y0 * matrix[2] + matrix[4];
-+ y00 = src->x0 * matrix[1] + src->y0 * matrix[3] + matrix[5];
-+ x10 = src->x1 * matrix[0] + src->y0 * matrix[2] + matrix[4];
-+ y10 = src->x1 * matrix[1] + src->y0 * matrix[3] + matrix[5];
-+ x01 = src->x0 * matrix[0] + src->y1 * matrix[2] + matrix[4];
-+ y01 = src->x0 * matrix[1] + src->y1 * matrix[3] + matrix[5];
-+ x11 = src->x1 * matrix[0] + src->y1 * matrix[2] + matrix[4];
-+ y11 = src->x1 * matrix[1] + src->y1 * matrix[3] + matrix[5];
-+ dst->x0 = MIN (MIN (x00, x10), MIN (x01, x11));
-+ dst->y0 = MIN (MIN (y00, y10), MIN (y01, y11));
-+ dst->x1 = MAX (MAX (x00, x10), MAX (x01, x11));
-+ dst->y1 = MAX (MAX (y00, y10), MAX (y01, y11));
-+}
-+
-+/**
-+ * art_drect_to_irect: Convert rectangle to integer rectangle.
-+ * @dst: Where to store resulting integer rectangle.
-+ * @src: The source rectangle.
-+ *
-+ * Find the smallest integer rectangle that encloses @src.
-+ **/
-+void
-+art_drect_to_irect (ArtIRect *dst, ArtDRect *src)
-+{
-+ dst->x0 = floor (src->x0);
-+ dst->y0 = floor (src->y0);
-+ dst->x1 = ceil (src->x1);
-+ dst->y1 = ceil (src->y1);
-+}
-diff -uNr /oocvs/OOO_STABLE_1-backup/external/gpc/art_rect.h external/gpc/art_rect.h
---- /oocvs/OOO_STABLE_1-backup/external/gpc/art_rect.h Wed Dec 31 18:00:00 1969
-+++ external/gpc/art_rect.h Fri Sep 20 15:31:32 2002
-@@ -0,0 +1,78 @@
-+/* 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_RECT_H__
-+#define __ART_RECT_H__
-+
-+#ifdef __cplusplus
-+extern "C" {
-+#endif
-+
-+typedef struct _ArtDRect ArtDRect;
-+typedef struct _ArtIRect ArtIRect;
-+
-+struct _ArtDRect {
-+ /*< public >*/
-+ double x0, y0, x1, y1;
-+};
-+
-+struct _ArtIRect {
-+ /*< public >*/
-+ int x0, y0, x1, y1;
-+};
-+
-+/* 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);
-+
-+/* Return true if the rectangle is empty. */
-+int art_irect_empty (const ArtIRect *src);
-+
-+/* Make a copy of the rectangle. */
-+void art_drect_copy (ArtDRect *dest, const ArtDRect *src);
-+
-+/* Find the smallest rectangle that includes both source rectangles. */
-+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);
-+
-+void
-+art_drect_affine_transform (ArtDRect *dst, const ArtDRect *src,
-+ const double matrix[6]);
-+
-+void art_drect_to_irect (ArtIRect *dst, ArtDRect *src);
-+
-+#ifdef __cplusplus
-+}
-+#endif
-+
-+#endif
-diff -uNr /oocvs/OOO_STABLE_1-backup/external/gpc/art_svp.c external/gpc/art_svp.c
---- /oocvs/OOO_STABLE_1-backup/external/gpc/art_svp.c Wed Dec 31 18:00:00 1969
-+++ external/gpc/art_svp.c Fri Sep 20 16:01:49 2002
-@@ -0,0 +1,150 @@
-+/* 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.
-+ */
-+
-+/* Basic constructors and operations for sorted vector paths */
-+
-+#include "art_svp.h"
-+#include "art_misc.h"
-+
-+/* Add a new segment. The arguments can be zero and NULL if the caller
-+ would rather fill them in later.
-+
-+ We also realloc one auxiliary array of ints of size n_segs if
-+ desired.
-+*/
-+/**
-+ * art_svp_add_segment: Add a segment to an #ArtSVP structure.
-+ * @p_vp: Pointer to where the #ArtSVP structure is stored.
-+ * @pn_segs_max: Pointer to the allocated size of *@p_vp.
-+ * @pn_points_max: Pointer to where auxiliary array is stored.
-+ * @n_points: Number of points for new segment.
-+ * @dir: Direction for new segment; 0 is up, 1 is down.
-+ * @points: Points for new segment.
-+ * @bbox: Bounding box for new segment.
-+ *
-+ * Adds a new segment to an ArtSVP structure. This routine reallocates
-+ * the structure if necessary, updating *@p_vp and *@pn_segs_max as
-+ * necessary.
-+ *
-+ * The new segment is simply added after all other segments. Thus,
-+ * this routine should be called in order consistent with the #ArtSVP
-+ * sorting rules.
-+ *
-+ * If the @bbox argument is given, it is simply stored in the new
-+ * segment. Otherwise (if it is NULL), the bounding box is computed
-+ * from the @points given.
-+ **/
-+int
-+art_svp_add_segment (ArtSVP **p_vp, int *pn_segs_max,
-+ int **pn_points_max,
-+ int n_points, int dir, ArtPoint *points,
-+ ArtDRect *bbox)
-+{
-+ int seg_num;
-+ ArtSVP *svp;
-+ ArtSVPSeg *seg;
-+
-+ svp = *p_vp;
-+ seg_num = svp->n_segs++;
-+ if (*pn_segs_max == seg_num)
-+ {
-+ *pn_segs_max <<= 1;
-+ svp = (ArtSVP *)art_realloc (svp, sizeof(ArtSVP) +
-+ (*pn_segs_max - 1) * sizeof(ArtSVPSeg));
-+ *p_vp = svp;
-+ if (pn_points_max != NULL)
-+ *pn_points_max = art_renew (*pn_points_max, int, *pn_segs_max);
-+ }
-+ seg = &svp->segs[seg_num];
-+ seg->n_points = n_points;
-+ seg->dir = dir;
-+ seg->points = points;
-+ if (bbox)
-+ seg->bbox = *bbox;
-+ else if (points)
-+ {
-+ double x_min, x_max;
-+ int i;
-+
-+ x_min = x_max = points[0].x;
-+ for (i = 1; i < n_points; i++)
-+ {
-+ if (x_min > points[i].x)
-+ x_min = points[i].x;
-+ if (x_max < points[i].x)
-+ x_max = points[i].x;
-+ }
-+ seg->bbox.x0 = x_min;
-+ seg->bbox.y0 = points[0].y;
-+
-+ seg->bbox.x1 = x_max;
-+ seg->bbox.y1 = points[n_points - 1].y;
-+ }
-+ return seg_num;
-+}
-+
-+
-+/**
-+ * art_svp_free: Free an #ArtSVP structure.
-+ * @svp: #ArtSVP to free.
-+ *
-+ * Frees an #ArtSVP structure and all the segments in it.
-+ **/
-+void
-+art_svp_free (ArtSVP *svp)
-+{
-+ int n_segs = svp->n_segs;
-+ int i;
-+
-+ for (i = 0; i < n_segs; i++)
-+ art_free (svp->segs[i].points);
-+ art_free (svp);
-+}
-+
-+#ifdef ART_USE_NEW_INTERSECTOR
-+#define EPSILON 0
-+#else
-+#define EPSILON 1e-6
-+#endif
-+
-+/**
-+ * art_svp_seg_compare: Compare two segments of an svp.
-+ * @seg1: First segment to compare.
-+ * @seg2: Second segment to compare.
-+ *
-+ * Compares two segments of an svp. Return 1 if @seg2 is below or to the
-+ * right of @seg1, -1 otherwise.
-+ **/
-+int
-+art_svp_seg_compare (const void *s1, const void *s2)
-+{
-+ const ArtSVPSeg *seg1 = s1;
-+ const ArtSVPSeg *seg2 = s2;
-+
-+ if (seg1->points[0].y - EPSILON > seg2->points[0].y) return 1;
-+ else if (seg1->points[0].y + EPSILON < seg2->points[0].y) return -1;
-+ else if (seg1->points[0].x - EPSILON > seg2->points[0].x) return 1;
-+ else if (seg1->points[0].x + EPSILON < seg2->points[0].x) return -1;
-+ else if ((seg1->points[1].x - seg1->points[0].x) *
-+ (seg2->points[1].y - seg2->points[0].y) -
-+ (seg1->points[1].y - seg1->points[0].y) *
-+ (seg2->points[1].x - seg2->points[0].x) > 0) return 1;
-+ else return -1;
-+}
-+
-diff -uNr /oocvs/OOO_STABLE_1-backup/external/gpc/art_svp.h external/gpc/art_svp.h
---- /oocvs/OOO_STABLE_1-backup/external/gpc/art_svp.h Wed Dec 31 18:00:00 1969
-+++ external/gpc/art_svp.h Fri Sep 20 21:36:42 2002
-@@ -0,0 +1,63 @@
-+/* 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_SVP_H__
-+#define __ART_SVP_H__
-+
-+/* Basic data structures and constructors for sorted vector paths */
-+
-+#include "art_rect.h"
-+#include "art_point.h"
-+
-+#ifdef __cplusplus
-+extern "C" {
-+#endif /* __cplusplus */
-+
-+typedef struct _ArtSVP ArtSVP;
-+typedef struct _ArtSVPSeg ArtSVPSeg;
-+
-+struct _ArtSVPSeg {
-+ int n_points;
-+ int dir; /* == 0 for "up", 1 for "down" */
-+ ArtDRect bbox;
-+ ArtPoint *points;
-+};
-+
-+struct _ArtSVP {
-+ int n_segs;
-+ ArtSVPSeg segs[1];
-+};
-+
-+int
-+art_svp_add_segment (ArtSVP **p_vp, int *pn_segs_max,
-+ int **pn_points_max,
-+ int n_points, int dir, ArtPoint *points,
-+ ArtDRect *bbox);
-+
-+void
-+art_svp_free (ArtSVP *svp);
-+
-+int
-+art_svp_seg_compare (const void *s1, const void *s2);
-+
-+#ifdef __cplusplus
-+}
-+#endif /* __cplusplus */
-+
-+#endif /* __ART_SVP_H__ */
-diff -uNr /oocvs/OOO_STABLE_1-backup/external/gpc/art_svp_intersect.c external/gpc/art_svp_intersect.c
---- /oocvs/OOO_STABLE_1-backup/external/gpc/art_svp_intersect.c Wed Dec 31 18:00:00 1969
-+++ external/gpc/art_svp_intersect.c Fri Sep 20 21:42:30 2002
-@@ -0,0 +1,1802 @@
-+/* Libart_LGPL - library of basic graphic primitives
-+ * Copyright (C) 2001 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.
-+ */
-+
-+/* This file contains a testbed implementation of the new intersection
-+ code.
-+*/
-+
-+#include "art_svp_intersect.h"
-+
-+#include <math.h> /* for sqrt */
-+
-+/* Sanitychecking verifies the main invariant on every priority queue
-+ point. Do not use in production, as it slows things down way too
-+ much. */
-+#define noSANITYCHECK
-+
-+/* This can be used in production, to prevent hangs. Eventually, it
-+ should not be necessary. */
-+#define CHEAP_SANITYCHECK
-+
-+#define noVERBOSE
-+
-+#include "art_misc.h"
-+
-+/* A priority queue - perhaps move to a separate file if it becomes
-+ needed somewhere else */
-+
-+#define ART_PRIQ_USE_HEAP
-+
-+typedef struct _ArtPriQ ArtPriQ;
-+typedef struct _ArtPriPoint ArtPriPoint;
-+
-+struct _ArtPriQ {
-+ int n_items;
-+ int n_items_max;
-+ ArtPriPoint **items;
-+};
-+
-+struct _ArtPriPoint {
-+ double x;
-+ double y;
-+ void *user_data;
-+};
-+
-+static ArtPriQ *
-+art_pri_new (void)
-+{
-+ ArtPriQ *result = art_new (ArtPriQ, 1);
-+
-+ result->n_items = 0;
-+ result->n_items_max = 16;
-+ result->items = art_new (ArtPriPoint *, result->n_items_max);
-+ return result;
-+}
-+
-+static void
-+art_pri_free (ArtPriQ *pq)
-+{
-+ art_free (pq->items);
-+ art_free (pq);
-+}
-+
-+static art_boolean
-+art_pri_empty (ArtPriQ *pq)
-+{
-+ return pq->n_items == 0;
-+}
-+
-+#ifdef ART_PRIQ_USE_HEAP
-+
-+/* This heap implementation is based on Vasek Chvatal's course notes:
-+ http://www.cs.rutgers.edu/~chvatal/notes/pq.html#heap */
-+
-+static void
-+art_pri_bubble_up (ArtPriQ *pq, int vacant, ArtPriPoint *missing)
-+{
-+ ArtPriPoint **items = pq->items;
-+ int parent;
-+
-+ parent = (vacant - 1) >> 1;
-+ while (vacant > 0 && (missing->y < items[parent]->y ||
-+ (missing->y == items[parent]->y &&
-+ missing->x < items[parent]->x)))
-+ {
-+ items[vacant] = items[parent];
-+ vacant = parent;
-+ parent = (vacant - 1) >> 1;
-+ }
-+
-+ items[vacant] = missing;
-+}
-+
-+static void
-+art_pri_insert (ArtPriQ *pq, ArtPriPoint *point)
-+{
-+ if (pq->n_items == pq->n_items_max)
-+ art_expand (pq->items, ArtPriPoint *, pq->n_items_max);
-+
-+ art_pri_bubble_up (pq, pq->n_items++, point);
-+}
-+
-+static void
-+art_pri_sift_down_from_root (ArtPriQ *pq, ArtPriPoint *missing)
-+{
-+ ArtPriPoint **items = pq->items;
-+ int vacant = 0, child = 2;
-+ int n = pq->n_items;
-+
-+ while (child < n)
-+ {
-+ if (items[child - 1]->y < items[child]->y ||
-+ (items[child - 1]->y == items[child]->y &&
-+ items[child - 1]->x < items[child]->x))
-+ child--;
-+ items[vacant] = items[child];
-+ vacant = child;
-+ child = (vacant + 1) << 1;
-+ }
-+ if (child == n)
-+ {
-+ items[vacant] = items[n - 1];
-+ vacant = n - 1;
-+ }
-+
-+ art_pri_bubble_up (pq, vacant, missing);
-+}
-+
-+static ArtPriPoint *
-+art_pri_choose (ArtPriQ *pq)
-+{
-+ ArtPriPoint *result = pq->items[0];
-+
-+ art_pri_sift_down_from_root (pq, pq->items[--pq->n_items]);
-+ return result;
-+}
-+
-+#else
-+
-+/* Choose least point in queue */
-+static ArtPriPoint *
-+art_pri_choose (ArtPriQ *pq)
-+{
-+ int i;
-+ int best = 0;
-+ double best_x, best_y;
-+ double y;
-+ ArtPriPoint *result;
-+
-+ if (pq->n_items == 0)
-+ return NULL;
-+
-+ best_x = pq->items[best]->x;
-+ best_y = pq->items[best]->y;
-+
-+ for (i = 1; i < pq->n_items; i++)
-+ {
-+ y = pq->items[i]->y;
-+ if (y < best_y || (y == best_y && pq->items[i]->x < best_x))
-+ {
-+ best = i;
-+ best_x = pq->items[best]->x;
-+ best_y = y;
-+ }
-+ }
-+ result = pq->items[best];
-+ pq->items[best] = pq->items[--pq->n_items];
-+ return result;
-+}
-+
-+static void
-+art_pri_insert (ArtPriQ *pq, ArtPriPoint *point)
-+{
-+ if (pq->n_items == pq->n_items_max)
-+ art_expand (pq->items, ArtPriPoint *, pq->n_items_max);
-+
-+ pq->items[pq->n_items++] = point;
-+}
-+
-+#endif
-+
-+#ifdef TEST_PRIQ
-+
-+#include <stdlib.h> /* for rand() */
-+#include <stdio.h>
-+
-+static double
-+double_rand (double lo, double hi, int quant)
-+{
-+ int tmp = rand () / (RAND_MAX * (1.0 / quant)) + 0.5;
-+ return lo + tmp * ((hi - lo) / quant);
-+}
-+
-+/*
-+ * This custom allocator for priority queue points is here so I can
-+ * test speed. It doesn't look like it will be that significant, but
-+ * if I want a small improvement later, it's something.
-+ */
-+
-+typedef ArtPriPoint *ArtPriPtPool;
-+
-+static ArtPriPtPool *
-+art_pri_pt_pool_new (void)
-+{
-+ ArtPriPtPool *result = art_new (ArtPriPtPool, 1);
-+ *result = NULL;
-+ return result;
-+}
-+
-+static ArtPriPoint *
-+art_pri_pt_alloc (ArtPriPtPool *pool)
-+{
-+ ArtPriPoint *result = *pool;
-+ if (result == NULL)
-+ return art_new (ArtPriPoint, 1);
-+ else
-+ {
-+ *pool = result->user_data;
-+ return result;
-+ }
-+}
-+
-+static void
-+art_pri_pt_free (ArtPriPtPool *pool, ArtPriPoint *pt)
-+{
-+ pt->user_data = *pool;
-+ *pool = pt;
-+}
-+
-+static void
-+art_pri_pt_pool_free (ArtPriPtPool *pool)
-+{
-+ ArtPriPoint *pt = *pool;
-+ while (pt != NULL)
-+ {
-+ ArtPriPoint *next = pt->user_data;
-+ art_free (pt);
-+ pt = next;
-+ }
-+ art_free (pool);
-+}
-+
-+int
-+main (int argc, char **argv)
-+{
-+ ArtPriPtPool *pool = art_pri_pt_pool_new ();
-+ ArtPriQ *pq;
-+ int i, j;
-+ const int n_iter = 1;
-+ const int pq_size = 100;
-+
-+ for (j = 0; j < n_iter; j++)
-+ {
-+ pq = art_pri_new ();
-+
-+ for (i = 0; i < pq_size; i++)
-+ {
-+ ArtPriPoint *pt = art_pri_pt_alloc (pool);
-+ pt->x = double_rand (0, 1, 100);
-+ pt->y = double_rand (0, 1, 100);
-+ pt->user_data = (void *)i;
-+ art_pri_insert (pq, pt);
-+ }
-+
-+ while (!art_pri_empty (pq))
-+ {
-+ ArtPriPoint *pt = art_pri_choose (pq);
-+ if (n_iter == 1)
-+ printf ("(%g, %g), %d\n", pt->x, pt->y, (int)pt->user_data);
-+ art_pri_pt_free (pool, pt);
-+ }
-+
-+ art_pri_free (pq);
-+ }
-+ art_pri_pt_pool_free (pool);
-+ return 0;
-+}
-+
-+#else /* TEST_PRIQ */
-+
-+/* A virtual class for an "svp writer". A client of this object creates an
-+ SVP by repeatedly calling "add segment" and "add point" methods on it.
-+*/
-+
-+typedef struct _ArtSvpWriterRewind ArtSvpWriterRewind;
-+
-+/* An implementation of the svp writer virtual class that applies the
-+ winding rule. */
-+
-+struct _ArtSvpWriterRewind {
-+ ArtSvpWriter super;
-+ ArtWindRule rule;
-+ ArtSVP *svp;
-+ int n_segs_max;
-+ int *n_points_max;
-+};
-+
-+static int
-+art_svp_writer_rewind_add_segment (ArtSvpWriter *self, int wind_left,
-+ int delta_wind, double x, double y)
-+{
-+ ArtSvpWriterRewind *swr = (ArtSvpWriterRewind *)self;
-+ ArtSVP *svp;
-+ ArtSVPSeg *seg;
-+ art_boolean left_filled, right_filled;
-+ int wind_right = wind_left + delta_wind;
-+ int seg_num;
-+ const int init_n_points_max = 4;
-+
-+ switch (swr->rule)
-+ {
-+ case ART_WIND_RULE_NONZERO:
-+ left_filled = (wind_left != 0);
-+ right_filled = (wind_right != 0);
-+ break;
-+ case ART_WIND_RULE_INTERSECT:
-+ left_filled = (wind_left > 1);
-+ right_filled = (wind_right > 1);
-+ break;
-+ case ART_WIND_RULE_ODDEVEN:
-+ left_filled = (wind_left & 1);
-+ right_filled = (wind_right & 1);
-+ break;
-+ case ART_WIND_RULE_POSITIVE:
-+ left_filled = (wind_left > 0);
-+ right_filled = (wind_right > 0);
-+ break;
-+ default:
-+ art_die ("Unknown wind rule %d\n", swr->rule);
-+ }
-+ if (left_filled == right_filled)
-+ {
-+ /* discard segment now */
-+#ifdef VERBOSE
-+ art_dprint ("swr add_segment: %d += %d (%g, %g) --> -1\n",
-+ wind_left, delta_wind, x, y);
-+#endif
-+ return -1;
-+ }
-+
-+ svp = swr->svp;
-+ seg_num = svp->n_segs++;
-+ if (swr->n_segs_max == seg_num)
-+ {
-+ swr->n_segs_max <<= 1;
-+ svp = (ArtSVP *)art_realloc (svp, sizeof(ArtSVP) +
-+ (swr->n_segs_max - 1) *
-+ sizeof(ArtSVPSeg));
-+ swr->svp = svp;
-+ swr->n_points_max = art_renew (swr->n_points_max, int,
-+ swr->n_segs_max);
-+ }
-+ seg = &svp->segs[seg_num];
-+ seg->n_points = 1;
-+ seg->dir = right_filled;
-+ swr->n_points_max[seg_num] = init_n_points_max;
-+ seg->bbox.x0 = x;
-+ seg->bbox.y0 = y;
-+ seg->bbox.x1 = x;
-+ seg->bbox.y1 = y;
-+ seg->points = art_new (ArtPoint, init_n_points_max);
-+ seg->points[0].x = x;
-+ seg->points[0].y = y;
-+#ifdef VERBOSE
-+ art_dprint ("swr add_segment: %d += %d (%g, %g) --> %d(%s)\n",
-+ wind_left, delta_wind, x, y, seg_num,
-+ seg->dir ? "v" : "^");
-+#endif
-+ return seg_num;
-+}
-+
-+static void
-+art_svp_writer_rewind_add_point (ArtSvpWriter *self, int seg_id,
-+ double x, double y)
-+{
-+ ArtSvpWriterRewind *swr = (ArtSvpWriterRewind *)self;
-+ ArtSVPSeg *seg;
-+ int n_points;
-+
-+#ifdef VERBOSE
-+ art_dprint ("swr add_point: %d (%g, %g)\n", seg_id, x, y);
-+#endif
-+ if (seg_id < 0)
-+ /* omitted segment */
-+ return;
-+
-+ seg = &swr->svp->segs[seg_id];
-+ n_points = seg->n_points++;
-+ if (swr->n_points_max[seg_id] == n_points)
-+ art_expand (seg->points, ArtPoint, swr->n_points_max[seg_id]);
-+ seg->points[n_points].x = x;
-+ seg->points[n_points].y = y;
-+ if (x < seg->bbox.x0)
-+ seg->bbox.x0 = x;
-+ if (x > seg->bbox.x1)
-+ seg->bbox.x1 = x;
-+ seg->bbox.y1 = y;
-+}
-+
-+static void
-+art_svp_writer_rewind_close_segment (ArtSvpWriter *self, int seg_id)
-+{
-+ /* Not needed for this simple implementation. A potential future
-+ optimization is to merge segments that can be merged safely. */
-+#ifdef SANITYCHECK
-+ ArtSvpWriterRewind *swr = (ArtSvpWriterRewind *)self;
-+ ArtSVPSeg *seg;
-+
-+ if (seg_id >= 0)
-+ {
-+ seg = &swr->svp->segs[seg_id];
-+ if (seg->n_points < 2)
-+ art_warn ("*** closing segment %d with only %d point%s\n",
-+ seg_id, seg->n_points, seg->n_points == 1 ? "" : "s");
-+ }
-+#endif
-+
-+#ifdef VERBOSE
-+ art_dprint ("swr close_segment: %d\n", seg_id);
-+#endif
-+}
-+
-+ArtSVP *
-+art_svp_writer_rewind_reap (ArtSvpWriter *self)
-+{
-+ ArtSvpWriterRewind *swr = (ArtSvpWriterRewind *)self;
-+ ArtSVP *result = swr->svp;
-+
-+ art_free (swr->n_points_max);
-+ art_free (swr);
-+ return result;
-+}
-+
-+ArtSvpWriter *
-+art_svp_writer_rewind_new (ArtWindRule rule)
-+{
-+ ArtSvpWriterRewind *result = art_new (ArtSvpWriterRewind, 1);
-+
-+ result->super.add_segment = art_svp_writer_rewind_add_segment;
-+ result->super.add_point = art_svp_writer_rewind_add_point;
-+ result->super.close_segment = art_svp_writer_rewind_close_segment;
-+
-+ result->rule = rule;
-+ result->n_segs_max = 16;
-+ result->svp = art_alloc (sizeof(ArtSVP) +
-+ (result->n_segs_max - 1) * sizeof(ArtSVPSeg));
-+ result->svp->n_segs = 0;
-+ result->n_points_max = art_new (int, result->n_segs_max);
-+
-+ return &result->super;
-+}
-+
-+/* Now, data structures for the active list */
-+
-+typedef struct _ArtActiveSeg ArtActiveSeg;
-+
-+/* Note: BNEG is 1 for \ lines, and 0 for /. Thus,
-+ x[(flags & BNEG) ^ 1] <= x[flags & BNEG] */
-+#define ART_ACTIVE_FLAGS_BNEG 1
-+
-+/* This flag is set if the segment has been inserted into the active
-+ list. */
-+#define ART_ACTIVE_FLAGS_IN_ACTIVE 2
-+
-+/* This flag is set when the segment is to be deleted in the
-+ horiz commit process. */
-+#define ART_ACTIVE_FLAGS_DEL 4
-+
-+/* This flag is set if the seg_id is a valid output segment. */
-+#define ART_ACTIVE_FLAGS_OUT 8
-+
-+/* This flag is set if the segment is in the horiz list. */
-+#define ART_ACTIVE_FLAGS_IN_HORIZ 16
-+
-+struct _ArtActiveSeg {
-+ int flags;
-+ int wind_left, delta_wind;
-+ ArtActiveSeg *left, *right; /* doubly linked list structure */
-+
-+ const ArtSVPSeg *in_seg;
-+ int in_curs;
-+
-+ double x[2];
-+ double y0, y1;
-+ double a, b, c; /* line equation; ax+by+c = 0 for the line, a^2 + b^2 = 1,
-+ and a>0 */
-+
-+ /* bottom point and intersection point stack */
-+ int n_stack;
-+ int n_stack_max;
-+ ArtPoint *stack;
-+
-+ /* horiz commit list */
-+ ArtActiveSeg *horiz_left, *horiz_right;
-+ double horiz_x;
-+ int horiz_delta_wind;
-+ int seg_id;
-+};
-+
-+typedef struct _ArtIntersectCtx ArtIntersectCtx;
-+
-+struct _ArtIntersectCtx {
-+ const ArtSVP *in;
-+ ArtSvpWriter *out;
-+
-+ ArtPriQ *pq;
-+
-+ ArtActiveSeg *active_head;
-+
-+ double y;
-+ ArtActiveSeg *horiz_first;
-+ ArtActiveSeg *horiz_last;
-+
-+ /* segment index of next input segment to be added to pri q */
-+ int in_curs;
-+};
-+
-+#define EPSILON_A 1e-5 /* Threshold for breaking lines at point insertions */
-+
-+/**
-+ * art_svp_intersect_setup_seg: Set up an active segment from input segment.
-+ * @seg: Active segment.
-+ * @pri_pt: Priority queue point to initialize.
-+ *
-+ * Sets the x[], a, b, c, flags, and stack fields according to the
-+ * line from the current cursor value. Sets the priority queue point
-+ * to the bottom point of this line. Also advances the input segment
-+ * cursor.
-+ **/
-+static void
-+art_svp_intersect_setup_seg (ArtActiveSeg *seg, ArtPriPoint *pri_pt)
-+{
-+ const ArtSVPSeg *in_seg = seg->in_seg;
-+ int in_curs = seg->in_curs++;
-+ double x0, y0, x1, y1;
-+ double dx, dy, s;
-+ double a, b, r2;
-+
-+ x0 = in_seg->points[in_curs].x;
-+ y0 = in_seg->points[in_curs].y;
-+ x1 = in_seg->points[in_curs + 1].x;
-+ y1 = in_seg->points[in_curs + 1].y;
-+ pri_pt->x = x1;
-+ pri_pt->y = y1;
-+ dx = x1 - x0;
-+ dy = y1 - y0;
-+ r2 = dx * dx + dy * dy;
-+ s = r2 == 0 ? 1 : 1 / sqrt (r2);
-+ seg->a = a = dy * s;
-+ seg->b = b = -dx * s;
-+ seg->c = -(a * x0 + b * y0);
-+ seg->flags = (seg->flags & ~ART_ACTIVE_FLAGS_BNEG) | (dx > 0);
-+ seg->x[0] = x0;
-+ seg->x[1] = x1;
-+ seg->y0 = y0;
-+ seg->y1 = y1;
-+ seg->n_stack = 1;
-+ seg->stack[0].x = x1;
-+ seg->stack[0].y = y1;
-+}
-+
-+/**
-+ * art_svp_intersect_add_horiz: Add point to horizontal list.
-+ * @ctx: Intersector context.
-+ * @seg: Segment with point to insert into horizontal list.
-+ *
-+ * Inserts @seg into horizontal list, keeping it in ascending horiz_x
-+ * order.
-+ *
-+ * Note: the horiz_commit routine processes "clusters" of segs in the
-+ * horiz list, all sharing the same horiz_x value. The cluster is
-+ * processed in active list order, rather than horiz list order. Thus,
-+ * the order of segs in the horiz list sharing the same horiz_x
-+ * _should_ be irrelevant. Even so, we use b as a secondary sorting key,
-+ * as a "belt and suspenders" defensive coding tactic.
-+ **/
-+static void
-+art_svp_intersect_add_horiz (ArtIntersectCtx *ctx, ArtActiveSeg *seg)
-+{
-+ ArtActiveSeg **pp = &ctx->horiz_last;
-+ ArtActiveSeg *place;
-+ ArtActiveSeg *place_right = NULL;
-+
-+
-+#ifdef CHEAP_SANITYCHECK
-+ if (seg->flags & ART_ACTIVE_FLAGS_IN_HORIZ)
-+ {
-+ art_warn ("*** attempt to put segment in horiz list twice\n");
-+ return;
-+ }
-+ seg->flags |= ART_ACTIVE_FLAGS_IN_HORIZ;
-+#endif
-+
-+#ifdef VERBOSE
-+ art_dprint ("add_horiz %lx, x = %g\n", (unsigned long) seg, seg->horiz_x);
-+#endif
-+ for (place = *pp; place != NULL && (place->horiz_x > seg->horiz_x ||
-+ (place->horiz_x == seg->horiz_x &&
-+ place->b < seg->b));
-+ place = *pp)
-+ {
-+ place_right = place;
-+ pp = &place->horiz_left;
-+ }
-+ *pp = seg;
-+ seg->horiz_left = place;
-+ seg->horiz_right = place_right;
-+ if (place == NULL)
-+ ctx->horiz_first = seg;
-+ else
-+ place->horiz_right = seg;
-+}
-+
-+static void
-+art_svp_intersect_push_pt (ArtIntersectCtx *ctx, ArtActiveSeg *seg,
-+ double x, double y)
-+{
-+ ArtPriPoint *pri_pt;
-+ int n_stack = seg->n_stack;
-+
-+ if (n_stack == seg->n_stack_max)
-+ art_expand (seg->stack, ArtPoint, seg->n_stack_max);
-+ seg->stack[n_stack].x = x;
-+ seg->stack[n_stack].y = y;
-+ seg->n_stack++;
-+
-+ seg->x[1] = x;
-+ seg->y1 = y;
-+
-+ pri_pt = art_new (ArtPriPoint, 1);
-+ pri_pt->x = x;
-+ pri_pt->y = y;
-+ pri_pt->user_data = seg;
-+ art_pri_insert (ctx->pq, pri_pt);
-+}
-+
-+typedef enum {
-+ ART_BREAK_LEFT = 1,
-+ ART_BREAK_RIGHT = 2
-+} ArtBreakFlags;
-+
-+/**
-+ * art_svp_intersect_break: Break an active segment.
-+ *
-+ * Note: y must be greater than the top point's y, and less than
-+ * the bottom's.
-+ *
-+ * Return value: x coordinate of break point.
-+ */
-+static double
-+art_svp_intersect_break (ArtIntersectCtx *ctx, ArtActiveSeg *seg,
-+ double x_ref, double y, ArtBreakFlags break_flags)
-+{
-+ double x0, y0, x1, y1;
-+ const ArtSVPSeg *in_seg = seg->in_seg;
-+ int in_curs = seg->in_curs;
-+ double x;
-+
-+ x0 = in_seg->points[in_curs - 1].x;
-+ y0 = in_seg->points[in_curs - 1].y;
-+ x1 = in_seg->points[in_curs].x;
-+ y1 = in_seg->points[in_curs].y;
-+ x = x0 + (x1 - x0) * ((y - y0) / (y1 - y0));
-+ if ((break_flags == ART_BREAK_LEFT && x > x_ref) ||
-+ (break_flags == ART_BREAK_RIGHT && x < x_ref))
-+ {
-+#ifdef VERBOSE
-+ art_dprint ("art_svp_intersect_break: limiting x to %f, was %f, %s\n",
-+ x_ref, x, break_flags == ART_BREAK_LEFT ? "left" : "right");
-+ x = x_ref;
-+#endif
-+ }
-+
-+ /* I think we can count on min(x0, x1) <= x <= max(x0, x1) with sane
-+ arithmetic, but it might be worthwhile to check just in case. */
-+
-+ if (y > ctx->y)
-+ art_svp_intersect_push_pt (ctx, seg, x, y);
-+ else
-+ {
-+ seg->x[0] = x;
-+ seg->y0 = y;
-+ seg->horiz_x = x;
-+ art_svp_intersect_add_horiz (ctx, seg);
-+ }
-+
-+ return x;
-+}
-+
-+/**
-+ * art_svp_intersect_add_point: Add a point, breaking nearby neighbors.
-+ * @ctx: Intersector context.
-+ * @x: X coordinate of point to add.
-+ * @y: Y coordinate of point to add.
-+ * @seg: "nearby" segment, or NULL if leftmost.
-+ *
-+ * Return value: Segment immediately to the left of the new point, or
-+ * NULL if the new point is leftmost.
-+ **/
-+static ArtActiveSeg *
-+art_svp_intersect_add_point (ArtIntersectCtx *ctx, double x, double y,
-+ ArtActiveSeg *seg, ArtBreakFlags break_flags)
-+{
-+ ArtActiveSeg *left, *right;
-+ double x_min = x, x_max = x;
-+ art_boolean left_live, right_live;
-+ double d;
-+ double new_x;
-+ ArtActiveSeg *test, *result = NULL;
-+ double x_test;
-+
-+ left = seg;
-+ if (left == NULL)
-+ right = ctx->active_head;
-+ else
-+ right = left->right;
-+ left_live = (break_flags & ART_BREAK_LEFT) && (left != NULL);
-+ right_live = (break_flags & ART_BREAK_RIGHT) && (right != NULL);
-+ while (left_live || right_live)
-+ {
-+ if (left_live)
-+ {
-+ if (x <= left->x[left->flags & ART_ACTIVE_FLAGS_BNEG] &&
-+ /* It may be that one of these conjuncts turns out to be always
-+ true. We test both anyway, to be defensive. */
-+ y != left->y0 && y < left->y1)
-+ {
-+ d = x_min * left->a + y * left->b + left->c;
-+ if (d < EPSILON_A)
-+ {
-+ new_x = art_svp_intersect_break (ctx, left, x_min, y,
-+ ART_BREAK_LEFT);
-+ if (new_x > x_max)
-+ {
-+ x_max = new_x;
-+ right_live = (right != NULL);
-+ }
-+ else if (new_x < x_min)
-+ x_min = new_x;
-+ left = left->left;
-+ left_live = (left != NULL);
-+ }
-+ else
-+ left_live = ART_FALSE;
-+ }
-+ else
-+ left_live = ART_FALSE;
-+ }
-+ else if (right_live)
-+ {
-+ if (x >= right->x[(right->flags & ART_ACTIVE_FLAGS_BNEG) ^ 1] &&
-+ /* It may be that one of these conjuncts turns out to be always
-+ true. We test both anyway, to be defensive. */
-+ y != right->y0 && y < right->y1)
-+ {
-+ d = x_max * right->a + y * right->b + right->c;
-+ if (d > -EPSILON_A)
-+ {
-+ new_x = art_svp_intersect_break (ctx, right, x_max, y,
-+ ART_BREAK_RIGHT);
-+ if (new_x < x_min)
-+ {
-+ x_min = new_x;
-+ left_live = (left != NULL);
-+ }
-+ else if (new_x >= x_max)
-+ x_max = new_x;
-+ right = right->right;
-+ right_live = (right != NULL);
-+ }
-+ else
-+ right_live = ART_FALSE;
-+ }
-+ else
-+ right_live = ART_FALSE;
-+ }
-+ }
-+
-+ /* Ascending order is guaranteed by break_flags. Thus, we don't need
-+ to actually fix up non-ascending pairs. */
-+
-+ /* Now, (left, right) defines an interval of segments broken. Sort
-+ into ascending x order. */
-+ test = left == NULL ? ctx->active_head : left->right;
-+ result = left;
-+ if (test != NULL && test != right)
-+ {
-+ if (y == test->y0)
-+ x_test = test->x[0];
-+ else /* assert y == test->y1, I think */
-+ x_test = test->x[1];
-+ for (;;)
-+ {
-+ if (x_test <= x)
-+ result = test;
-+ test = test->right;
-+ if (test == right)
-+ break;
-+ new_x = x_test;
-+ if (new_x < x_test)
-+ {
-+ art_warn ("art_svp_intersect_add_point: non-ascending x\n");
-+ }
-+ x_test = new_x;
-+ }
-+ }
-+ return result;
-+}
-+
-+static void
-+art_svp_intersect_swap_active (ArtIntersectCtx *ctx,
-+ ArtActiveSeg *left_seg, ArtActiveSeg *right_seg)
-+{
-+ right_seg->left = left_seg->left;
-+ if (right_seg->left != NULL)
-+ right_seg->left->right = right_seg;
-+ else
-+ ctx->active_head = right_seg;
-+ left_seg->right = right_seg->right;
-+ if (left_seg->right != NULL)
-+ left_seg->right->left = left_seg;
-+ left_seg->left = right_seg;
-+ right_seg->right = left_seg;
-+}
-+
-+/**
-+ * art_svp_intersect_test_cross: Test crossing of a pair of active segments.
-+ * @ctx: Intersector context.
-+ * @left_seg: Left segment of the pair.
-+ * @right_seg: Right segment of the pair.
-+ * @break_flags: Flags indicating whether to break neighbors.
-+ *
-+ * Tests crossing of @left_seg and @right_seg. If there is a crossing,
-+ * inserts the intersection point into both segments.
-+ *
-+ * Return value: True if the intersection took place at the current
-+ * scan line, indicating further iteration is needed.
-+ **/
-+static art_boolean
-+art_svp_intersect_test_cross (ArtIntersectCtx *ctx,
-+ ArtActiveSeg *left_seg, ArtActiveSeg *right_seg,
-+ ArtBreakFlags break_flags)
-+{
-+ double left_x0, left_y0, left_x1;
-+ double left_y1 = left_seg->y1;
-+ double right_y1 = right_seg->y1;
-+ double d;
-+
-+ const ArtSVPSeg *in_seg;
-+ int in_curs;
-+ double d0, d1, t;
-+ double x, y; /* intersection point */
-+
-+#ifdef VERBOSE
-+ static int count = 0;
-+
-+ art_dprint ("art_svp_intersect_test_cross %lx <-> %lx: count=%d\n",
-+ (unsigned long)left_seg, (unsigned long)right_seg, count++);
-+#endif
-+
-+ if (left_seg->y0 == right_seg->y0 && left_seg->x[0] == right_seg->x[0])
-+ {
-+ /* Top points of left and right segments coincide. This case
-+ feels like a bit of duplication - we may want to merge it
-+ with the cases below. However, this way, we're sure that this
-+ logic makes only localized changes. */
-+
-+ if (left_y1 < right_y1)
-+ {
-+ /* Test left (x1, y1) against right segment */
-+ double left_x1 = left_seg->x[1];
-+
-+ if (left_x1 <
-+ right_seg->x[(right_seg->flags & ART_ACTIVE_FLAGS_BNEG) ^ 1] ||
-+ left_y1 == right_seg->y0)
-+ return ART_FALSE;
-+ d = left_x1 * right_seg->a + left_y1 * right_seg->b + right_seg->c;
-+ if (d < -EPSILON_A)
-+ return ART_FALSE;
-+ else if (d < EPSILON_A)
-+ {
-+ /* I'm unsure about the break flags here. */
-+ double right_x1 = art_svp_intersect_break (ctx, right_seg,
-+ left_x1, left_y1,
-+ ART_BREAK_RIGHT);
-+ if (left_x1 <= right_x1)
-+ return ART_FALSE;
-+ }
-+ }
-+ else if (left_y1 > right_y1)
-+ {
-+ /* Test right (x1, y1) against left segment */
-+ double right_x1 = right_seg->x[1];
-+
-+ if (right_x1 > left_seg->x[left_seg->flags & ART_ACTIVE_FLAGS_BNEG] ||
-+ right_y1 == left_seg->y0)
-+ return ART_FALSE;
-+ d = right_x1 * left_seg->a + right_y1 * left_seg->b + left_seg->c;
-+ if (d > EPSILON_A)
-+ return ART_FALSE;
-+ else if (d > -EPSILON_A)
-+ {
-+ /* See above regarding break flags. */
-+ double left_x1 = art_svp_intersect_break (ctx, left_seg,
-+ right_x1, right_y1,
-+ ART_BREAK_LEFT);
-+ if (left_x1 <= right_x1)
-+ return ART_FALSE;
-+ }
-+ }
-+ else /* left_y1 == right_y1 */
-+ {
-+ double left_x1 = left_seg->x[1];
-+ double right_x1 = right_seg->x[1];
-+
-+ if (left_x1 <= right_x1)
-+ return ART_FALSE;
-+ }
-+ art_svp_intersect_swap_active (ctx, left_seg, right_seg);
-+ return ART_TRUE;
-+ }
-+
-+ if (left_y1 < right_y1)
-+ {
-+ /* Test left (x1, y1) against right segment */
-+ double left_x1 = left_seg->x[1];
-+
-+ if (left_x1 <
-+ right_seg->x[(right_seg->flags & ART_ACTIVE_FLAGS_BNEG) ^ 1] ||
-+ left_y1 == right_seg->y0)
-+ return ART_FALSE;
-+ d = left_x1 * right_seg->a + left_y1 * right_seg->b + right_seg->c;
-+ if (d < -EPSILON_A)
-+ return ART_FALSE;
-+ else if (d < EPSILON_A)
-+ {
-+ double right_x1 = art_svp_intersect_break (ctx, right_seg,
-+ left_x1, left_y1,
-+ ART_BREAK_RIGHT);
-+ if (left_x1 <= right_x1)
-+ return ART_FALSE;
-+ }
-+ }
-+ else if (left_y1 > right_y1)
-+ {
-+ /* Test right (x1, y1) against left segment */
-+ double right_x1 = right_seg->x[1];
-+
-+ if (right_x1 > left_seg->x[left_seg->flags & ART_ACTIVE_FLAGS_BNEG] ||
-+ right_y1 == left_seg->y0)
-+ return ART_FALSE;
-+ d = right_x1 * left_seg->a + right_y1 * left_seg->b + left_seg->c;
-+ if (d > EPSILON_A)
-+ return ART_FALSE;
-+ else if (d > -EPSILON_A)
-+ {
-+ double left_x1 = art_svp_intersect_break (ctx, left_seg,
-+ right_x1, right_y1,
-+ ART_BREAK_LEFT);
-+ if (left_x1 <= right_x1)
-+ return ART_FALSE;
-+ }
-+ }
-+ else /* left_y1 == right_y1 */
-+ {
-+ double left_x1 = left_seg->x[1];
-+ double right_x1 = right_seg->x[1];
-+
-+ if (left_x1 <= right_x1)
-+ return ART_FALSE;
-+ }
-+
-+ /* The segments cross. Find the intersection point. */
-+
-+ in_seg = left_seg->in_seg;
-+ in_curs = left_seg->in_curs;
-+ left_x0 = in_seg->points[in_curs - 1].x;
-+ left_y0 = in_seg->points[in_curs - 1].y;
-+ left_x1 = in_seg->points[in_curs].x;
-+ left_y1 = in_seg->points[in_curs].y;
-+ d0 = left_x0 * right_seg->a + left_y0 * right_seg->b + right_seg->c;
-+ d1 = left_x1 * right_seg->a + left_y1 * right_seg->b + right_seg->c;
-+ if (d0 == d1)
-+ {
-+ x = left_x0;
-+ y = left_y0;
-+ }
-+ else
-+ {
-+ /* Is this division always safe? It could possibly overflow. */
-+ t = d0 / (d0 - d1);
-+ if (t <= 0)
-+ {
-+ x = left_x0;
-+ y = left_y0;
-+ }
-+ else if (t >= 1)
-+ {
-+ x = left_x1;
-+ y = left_y1;
-+ }
-+ else
-+ {
-+ x = left_x0 + t * (left_x1 - left_x0);
-+ y = left_y0 + t * (left_y1 - left_y0);
-+ }
-+ }
-+
-+ /* Make sure intersection point is within bounds of right seg. */
-+ if (y < right_seg->y0)
-+ {
-+ x = right_seg->x[0];
-+ y = right_seg->y0;
-+ }
-+ else if (y > right_seg->y1)
-+ {
-+ x = right_seg->x[1];
-+ y = right_seg->y1;
-+ }
-+ else if (x < right_seg->x[(right_seg->flags & ART_ACTIVE_FLAGS_BNEG) ^ 1])
-+ x = right_seg->x[(right_seg->flags & ART_ACTIVE_FLAGS_BNEG) ^ 1];
-+ else if (x > right_seg->x[right_seg->flags & ART_ACTIVE_FLAGS_BNEG])
-+ x = right_seg->x[right_seg->flags & ART_ACTIVE_FLAGS_BNEG];
-+
-+ if (y == left_seg->y0)
-+ {
-+ if (y != right_seg->y0)
-+ {
-+#ifdef VERBOSE
-+ art_dprint ("art_svp_intersect_test_cross: intersection (%g, %g) matches former y0 of %lx, %lx\n",
-+ x, y, (unsigned long)left_seg, (unsigned long)right_seg);
-+#endif
-+ art_svp_intersect_push_pt (ctx, right_seg, x, y);
-+ if ((break_flags & ART_BREAK_RIGHT) && right_seg->right != NULL)
-+ art_svp_intersect_add_point (ctx, x, y, right_seg->right,
-+ break_flags);
-+ }
-+ else
-+ {
-+ /* Intersection takes place at current scan line; process
-+ immediately rather than queueing intersection point into
-+ priq. */
-+ ArtActiveSeg *winner, *loser;
-+
-+ /* Choose "most vertical" segement */
-+ if (left_seg->a > right_seg->a)
-+ {
-+ winner = left_seg;
-+ loser = right_seg;
-+ }
-+ else
-+ {
-+ winner = right_seg;
-+ loser = left_seg;
-+ }
-+
-+ loser->x[0] = winner->x[0];
-+ loser->horiz_x = loser->x[0];
-+ loser->horiz_delta_wind += loser->delta_wind;
-+ winner->horiz_delta_wind -= loser->delta_wind;
-+
-+ art_svp_intersect_swap_active (ctx, left_seg, right_seg);
-+ return ART_TRUE;
-+ }
-+ }
-+ else if (y == right_seg->y0)
-+ {
-+#ifdef VERBOSE
-+ art_dprint ("*** art_svp_intersect_test_cross: intersection (%g, %g) matches latter y0 of %lx, %lx\n",
-+ x, y, (unsigned long)left_seg, (unsigned long)right_seg);
-+#endif
-+ art_svp_intersect_push_pt (ctx, left_seg, x, y);
-+ if ((break_flags & ART_BREAK_LEFT) && left_seg->left != NULL)
-+ art_svp_intersect_add_point (ctx, x, y, left_seg->left,
-+ break_flags);
-+ }
-+ else
-+ {
-+#ifdef VERBOSE
-+ art_dprint ("Inserting (%g, %g) into %lx, %lx\n",
-+ x, y, (unsigned long)left_seg, (unsigned long)right_seg);
-+#endif
-+ /* Insert the intersection point into both segments. */
-+ art_svp_intersect_push_pt (ctx, left_seg, x, y);
-+ art_svp_intersect_push_pt (ctx, right_seg, x, y);
-+ if ((break_flags & ART_BREAK_LEFT) && left_seg->left != NULL)
-+ art_svp_intersect_add_point (ctx, x, y, left_seg->left, break_flags);
-+ if ((break_flags & ART_BREAK_RIGHT) && right_seg->right != NULL)
-+ art_svp_intersect_add_point (ctx, x, y, right_seg->right, break_flags);
-+ }
-+ return ART_FALSE;
-+}
-+
-+/**
-+ * art_svp_intersect_active_delete: Delete segment from active list.
-+ * @ctx: Intersection context.
-+ * @seg: Segment to delete.
-+ *
-+ * Deletes @seg from the active list.
-+ **/
-+static /* todo inline */ void
-+art_svp_intersect_active_delete (ArtIntersectCtx *ctx, ArtActiveSeg *seg)
-+{
-+ ArtActiveSeg *left = seg->left, *right = seg->right;
-+
-+ if (left != NULL)
-+ left->right = right;
-+ else
-+ ctx->active_head = right;
-+ if (right != NULL)
-+ right->left = left;
-+}
-+
-+/**
-+ * art_svp_intersect_active_free: Free an active segment.
-+ * @seg: Segment to delete.
-+ *
-+ * Frees @seg.
-+ **/
-+static /* todo inline */ void
-+art_svp_intersect_active_free (ArtActiveSeg *seg)
-+{
-+ art_free (seg->stack);
-+#ifdef VERBOSE
-+ art_dprint ("Freeing %lx\n", (unsigned long) seg);
-+#endif
-+ art_free (seg);
-+}
-+
-+/**
-+ * art_svp_intersect_insert_cross: Test crossings of newly inserted line.
-+ *
-+ * Tests @seg against its left and right neighbors for intersections.
-+ * Precondition: the line in @seg is not purely horizontal.
-+ **/
-+static void
-+art_svp_intersect_insert_cross (ArtIntersectCtx *ctx,
-+ ArtActiveSeg *seg)
-+{
-+ ArtActiveSeg *left = seg, *right = seg;
-+
-+ for (;;)
-+ {
-+ if (left != NULL)
-+ {
-+ ArtActiveSeg *leftc;
-+
-+ for (leftc = left->left; leftc != NULL; leftc = leftc->left)
-+ if (!(leftc->flags & ART_ACTIVE_FLAGS_DEL))
-+ break;
-+ if (leftc != NULL &&
-+ art_svp_intersect_test_cross (ctx, leftc, left,
-+ ART_BREAK_LEFT))
-+ {
-+ if (left == right || right == NULL)
-+ right = left->right;
-+ }
-+ else
-+ {
-+ left = NULL;
-+ }
-+ }
-+ else if (right != NULL && right->right != NULL)
-+ {
-+ ArtActiveSeg *rightc;
-+
-+ for (rightc = right->right; rightc != NULL; rightc = rightc->right)
-+ if (!(rightc->flags & ART_ACTIVE_FLAGS_DEL))
-+ break;
-+ if (rightc != NULL &&
-+ art_svp_intersect_test_cross (ctx, right, rightc,
-+ ART_BREAK_RIGHT))
-+ {
-+ if (left == right || left == NULL)
-+ left = right->left;
-+ }
-+ else
-+ {
-+ right = NULL;
-+ }
-+ }
-+ else
-+ break;
-+ }
-+}
-+
-+/**
-+ * art_svp_intersect_horiz: Add horizontal line segment.
-+ * @ctx: Intersector context.
-+ * @seg: Segment on which to add horizontal line.
-+ * @x0: Old x position.
-+ * @x1: New x position.
-+ *
-+ * Adds a horizontal line from @x0 to @x1, and updates the current
-+ * location of @seg to @x1.
-+ **/
-+static void
-+art_svp_intersect_horiz (ArtIntersectCtx *ctx, ArtActiveSeg *seg,
-+ double x0, double x1)
-+{
-+ ArtActiveSeg *hs;
-+
-+ if (x0 == x1)
-+ return;
-+
-+ hs = art_new (ArtActiveSeg, 1);
-+
-+ hs->flags = ART_ACTIVE_FLAGS_DEL | (seg->flags & ART_ACTIVE_FLAGS_OUT);
-+ if (seg->flags & ART_ACTIVE_FLAGS_OUT)
-+ {
-+ ArtSvpWriter *swr = ctx->out;
-+
-+ swr->add_point (swr, seg->seg_id, x0, ctx->y);
-+ }
-+ hs->seg_id = seg->seg_id;
-+ hs->horiz_x = x0;
-+ hs->horiz_delta_wind = seg->delta_wind;
-+ hs->stack = NULL;
-+
-+ /* Ideally, the (a, b, c) values will never be read. However, there
-+ are probably some tests remaining that don't check for _DEL
-+ before evaluating the line equation. For those, these
-+ initializations will at least prevent a UMR of the values, which
-+ can crash on some platforms. */
-+ hs->a = 0.0;
-+ hs->b = 0.0;
-+ hs->c = 0.0;
-+
-+ seg->horiz_delta_wind -= seg->delta_wind;
-+
-+ art_svp_intersect_add_horiz (ctx, hs);
-+
-+ if (x0 > x1)
-+ {
-+ ArtActiveSeg *left;
-+ art_boolean first = ART_TRUE;
-+
-+ for (left = seg->left; left != NULL; left = seg->left)
-+ {
-+ int left_bneg = left->flags & ART_ACTIVE_FLAGS_BNEG;
-+
-+ if (left->x[left_bneg] <= x1)
-+ break;
-+ if (left->x[left_bneg ^ 1] <= x1 &&
-+ x1 * left->a + ctx->y * left->b + left->c >= 0)
-+ break;
-+ if (left->y0 != ctx->y && left->y1 != ctx->y)
-+ {
-+ art_svp_intersect_break (ctx, left, x1, ctx->y, ART_BREAK_LEFT);
-+ }
-+#ifdef VERBOSE
-+ art_dprint ("x0=%g > x1=%g, swapping %lx, %lx\n",
-+ x0, x1, (unsigned long)left, (unsigned long)seg);
-+#endif
-+ art_svp_intersect_swap_active (ctx, left, seg);
-+ if (first && left->right != NULL)
-+ {
-+ art_svp_intersect_test_cross (ctx, left, left->right,
-+ ART_BREAK_RIGHT);
-+ first = ART_FALSE;
-+ }
-+ }
-+ }
-+ else
-+ {
-+ ArtActiveSeg *right;
-+ art_boolean first = ART_TRUE;
-+
-+ for (right = seg->right; right != NULL; right = seg->right)
-+ {
-+ int right_bneg = right->flags & ART_ACTIVE_FLAGS_BNEG;
-+
-+ if (right->x[right_bneg ^ 1] >= x1)
-+ break;
-+ if (right->x[right_bneg] >= x1 &&
-+ x1 * right->a + ctx->y * right->b + right->c <= 0)
-+ break;
-+ if (right->y0 != ctx->y && right->y1 != ctx->y)
-+ {
-+ art_svp_intersect_break (ctx, right, x1, ctx->y,
-+ ART_BREAK_LEFT);
-+ }
-+#ifdef VERBOSE
-+ art_dprint ("[right]x0=%g < x1=%g, swapping %lx, %lx\n",
-+ x0, x1, (unsigned long)seg, (unsigned long)right);
-+#endif
-+ art_svp_intersect_swap_active (ctx, seg, right);
-+ if (first && right->left != NULL)
-+ {
-+ art_svp_intersect_test_cross (ctx, right->left, right,
-+ ART_BREAK_RIGHT);
-+ first = ART_FALSE;
-+ }
-+ }
-+ }
-+
-+ seg->x[0] = x1;
-+ seg->x[1] = x1;
-+ seg->horiz_x = x1;
-+ seg->flags &= ~ART_ACTIVE_FLAGS_OUT;
-+}
-+
-+/**
-+ * art_svp_intersect_insert_line: Insert a line into the active list.
-+ * @ctx: Intersector context.
-+ * @seg: Segment containing line to insert.
-+ *
-+ * Inserts the line into the intersector context, taking care of any
-+ * intersections, and adding the appropriate horizontal points to the
-+ * active list.
-+ **/
-+static void
-+art_svp_intersect_insert_line (ArtIntersectCtx *ctx, ArtActiveSeg *seg)
-+{
-+ if (seg->y1 == seg->y0)
-+ {
-+#ifdef VERBOSE
-+ art_dprint ("art_svp_intersect_insert_line: %lx is horizontal\n",
-+ (unsigned long)seg);
-+#endif
-+ art_svp_intersect_horiz (ctx, seg, seg->x[0], seg->x[1]);
-+ }
-+ else
-+ {
-+ art_svp_intersect_insert_cross (ctx, seg);
-+ art_svp_intersect_add_horiz (ctx, seg);
-+ }
-+}
-+
-+static void
-+art_svp_intersect_process_intersection (ArtIntersectCtx *ctx,
-+ ArtActiveSeg *seg)
-+{
-+ int n_stack = --seg->n_stack;
-+ seg->x[1] = seg->stack[n_stack - 1].x;
-+ seg->y1 = seg->stack[n_stack - 1].y;
-+ seg->x[0] = seg->stack[n_stack].x;
-+ seg->y0 = seg->stack[n_stack].y;
-+ seg->horiz_x = seg->x[0];
-+ art_svp_intersect_insert_line (ctx, seg);
-+}
-+
-+static void
-+art_svp_intersect_advance_cursor (ArtIntersectCtx *ctx, ArtActiveSeg *seg,
-+ ArtPriPoint *pri_pt)
-+{
-+ const ArtSVPSeg *in_seg = seg->in_seg;
-+ int in_curs = seg->in_curs;
-+ ArtSvpWriter *swr = seg->flags & ART_ACTIVE_FLAGS_OUT ? ctx->out : NULL;
-+
-+ if (swr != NULL)
-+ swr->add_point (swr, seg->seg_id, seg->x[1], seg->y1);
-+ if (in_curs + 1 == in_seg->n_points)
-+ {
-+ ArtActiveSeg *left = seg->left, *right = seg->right;
-+
-+#if 0
-+ if (swr != NULL)
-+ swr->close_segment (swr, seg->seg_id);
-+ seg->flags &= ~ART_ACTIVE_FLAGS_OUT;
-+#endif
-+ seg->flags |= ART_ACTIVE_FLAGS_DEL;
-+ art_svp_intersect_add_horiz (ctx, seg);
-+ art_svp_intersect_active_delete (ctx, seg);
-+ if (left != NULL && right != NULL)
-+ art_svp_intersect_test_cross (ctx, left, right,
-+ ART_BREAK_LEFT | ART_BREAK_RIGHT);
-+ art_free (pri_pt);
-+ }
-+ else
-+ {
-+ seg->horiz_x = seg->x[1];
-+
-+ art_svp_intersect_setup_seg (seg, pri_pt);
-+ art_pri_insert (ctx->pq, pri_pt);
-+ art_svp_intersect_insert_line (ctx, seg);
-+ }
-+}
-+
-+static void
-+art_svp_intersect_add_seg (ArtIntersectCtx *ctx, const ArtSVPSeg *in_seg)
-+{
-+ ArtActiveSeg *seg = art_new (ArtActiveSeg, 1);
-+ ArtActiveSeg *test;
-+ double x0, y0;
-+ ArtActiveSeg *beg_range;
-+ ArtActiveSeg *last = NULL;
-+ ArtActiveSeg *left, *right;
-+ ArtPriPoint *pri_pt = art_new (ArtPriPoint, 1);
-+
-+ seg->flags = 0;
-+ seg->in_seg = in_seg;
-+ seg->in_curs = 0;
-+
-+ seg->n_stack_max = 4;
-+ seg->stack = art_new (ArtPoint, seg->n_stack_max);
-+
-+ seg->horiz_delta_wind = 0;
-+
-+ seg->wind_left = 0;
-+
-+ pri_pt->user_data = seg;
-+ art_svp_intersect_setup_seg (seg, pri_pt);
-+ art_pri_insert (ctx->pq, pri_pt);
-+
-+ /* Find insertion place for new segment */
-+ /* This is currently a left-to-right scan, but should be replaced
-+ with a binary search as soon as it's validated. */
-+
-+ x0 = in_seg->points[0].x;
-+ y0 = in_seg->points[0].y;
-+ beg_range = NULL;
-+ for (test = ctx->active_head; test != NULL; test = test->right)
-+ {
-+ double d;
-+ int test_bneg = test->flags & ART_ACTIVE_FLAGS_BNEG;
-+
-+ if (x0 < test->x[test_bneg])
-+ {
-+ if (x0 < test->x[test_bneg ^ 1])
-+ break;
-+ d = x0 * test->a + y0 * test->b + test->c;
-+ if (d < 0)
-+ break;
-+ }
-+ last = test;
-+ }
-+
-+ left = art_svp_intersect_add_point (ctx, x0, y0, last, ART_BREAK_LEFT | ART_BREAK_RIGHT);
-+ seg->left = left;
-+ if (left == NULL)
-+ {
-+ right = ctx->active_head;
-+ ctx->active_head = seg;
-+ }
-+ else
-+ {
-+ right = left->right;
-+ left->right = seg;
-+ }
-+ seg->right = right;
-+ if (right != NULL)
-+ right->left = seg;
-+
-+ seg->delta_wind = in_seg->dir ? 1 : -1;
-+ seg->horiz_x = x0;
-+
-+ art_svp_intersect_insert_line (ctx, seg);
-+}
-+
-+#ifdef SANITYCHECK
-+static void
-+art_svp_intersect_sanitycheck_winding (ArtIntersectCtx *ctx)
-+{
-+#if 0
-+ /* At this point, we seem to be getting false positives, so it's
-+ turned off for now. */
-+
-+ ArtActiveSeg *seg;
-+ int winding_number = 0;
-+
-+ for (seg = ctx->active_head; seg != NULL; seg = seg->right)
-+ {
-+ /* Check winding number consistency. */
-+ if (seg->flags & ART_ACTIVE_FLAGS_OUT)
-+ {
-+ if (winding_number != seg->wind_left)
-+ art_warn ("*** art_svp_intersect_sanitycheck_winding: seg %lx has wind_left of %d, expected %d\n",
-+ (unsigned long) seg, seg->wind_left, winding_number);
-+ winding_number = seg->wind_left + seg->delta_wind;
-+ }
-+ }
-+ if (winding_number != 0)
-+ art_warn ("*** art_svp_intersect_sanitycheck_winding: non-balanced winding number %d\n",
-+ winding_number);
-+#endif
-+}
-+#endif
-+
-+/**
-+ * art_svp_intersect_horiz_commit: Commit points in horiz list to output.
-+ * @ctx: Intersection context.
-+ *
-+ * The main function of the horizontal commit is to output new
-+ * points to the output writer.
-+ *
-+ * This "commit" pass is also where winding numbers are assigned,
-+ * because doing it here provides much greater tolerance for inputs
-+ * which are not in strict SVP order.
-+ *
-+ * Each cluster in the horiz_list contains both segments that are in
-+ * the active list (ART_ACTIVE_FLAGS_DEL is false) and that are not,
-+ * and are scheduled to be deleted (ART_ACTIVE_FLAGS_DEL is true). We
-+ * need to deal with both.
-+ **/
-+static void
-+art_svp_intersect_horiz_commit (ArtIntersectCtx *ctx)
-+{
-+ ArtActiveSeg *seg;
-+ int winding_number = 0; /* initialization just to avoid warning */
-+ int horiz_wind = 0;
-+ double last_x = 0; /* initialization just to avoid warning */
-+
-+#ifdef VERBOSE
-+ art_dprint ("art_svp_intersect_horiz_commit: y=%g\n", ctx->y);
-+ for (seg = ctx->horiz_first; seg != NULL; seg = seg->horiz_right)
-+ art_dprint (" %lx: %g %+d\n",
-+ (unsigned long)seg, seg->horiz_x, seg->horiz_delta_wind);
-+#endif
-+
-+ /* Output points to svp writer. */
-+ for (seg = ctx->horiz_first; seg != NULL;)
-+ {
-+ /* Find a cluster with common horiz_x, */
-+ ArtActiveSeg *curs;
-+ double x = seg->horiz_x;
-+
-+ /* Generate any horizontal segments. */
-+ if (horiz_wind != 0)
-+ {
-+ ArtSvpWriter *swr = ctx->out;
-+ int seg_id;
-+
-+ seg_id = swr->add_segment (swr, winding_number, horiz_wind,
-+ last_x, ctx->y);
-+ swr->add_point (swr, seg_id, x, ctx->y);
-+ swr->close_segment (swr, seg_id);
-+ }
-+
-+ /* Find first active segment in cluster. */
-+
-+ for (curs = seg; curs != NULL && curs->horiz_x == x;
-+ curs = curs->horiz_right)
-+ if (!(curs->flags & ART_ACTIVE_FLAGS_DEL))
-+ break;
-+
-+ if (curs != NULL && curs->horiz_x == x)
-+ {
-+ /* There exists at least one active segment in this cluster. */
-+
-+ /* Find beginning of cluster. */
-+ for (; curs->left != NULL; curs = curs->left)
-+ if (curs->left->horiz_x != x)
-+ break;
-+
-+ if (curs->left != NULL)
-+ winding_number = curs->left->wind_left + curs->left->delta_wind;
-+ else
-+ winding_number = 0;
-+
-+ do
-+ {
-+#ifdef VERBOSE
-+ art_dprint (" curs %lx: winding_number = %d += %d\n",
-+ (unsigned long)curs, winding_number, curs->delta_wind);
-+#endif
-+ if (!(curs->flags & ART_ACTIVE_FLAGS_OUT) ||
-+ curs->wind_left != winding_number)
-+ {
-+ ArtSvpWriter *swr = ctx->out;
-+
-+ if (curs->flags & ART_ACTIVE_FLAGS_OUT)
-+ {
-+ swr->add_point (swr, curs->seg_id,
-+ curs->horiz_x, ctx->y);
-+ swr->close_segment (swr, curs->seg_id);
-+ }
-+
-+ curs->seg_id = swr->add_segment (swr, winding_number,
-+ curs->delta_wind,
-+ x, ctx->y);
-+ curs->flags |= ART_ACTIVE_FLAGS_OUT;
-+ }
-+ curs->wind_left = winding_number;
-+ winding_number += curs->delta_wind;
-+ curs = curs->right;
-+ }
-+ while (curs != NULL && curs->horiz_x == x);
-+ }
-+
-+ /* Skip past cluster. */
-+ do
-+ {
-+ ArtActiveSeg *next = seg->horiz_right;
-+
-+ seg->flags &= ~ART_ACTIVE_FLAGS_IN_HORIZ;
-+ horiz_wind += seg->horiz_delta_wind;
-+ seg->horiz_delta_wind = 0;
-+ if (seg->flags & ART_ACTIVE_FLAGS_DEL)
-+ {
-+ if (seg->flags & ART_ACTIVE_FLAGS_OUT)
-+ {
-+ ArtSvpWriter *swr = ctx->out;
-+ swr->close_segment (swr, seg->seg_id);
-+ }
-+ art_svp_intersect_active_free (seg);
-+ }
-+ seg = next;
-+ }
-+ while (seg != NULL && seg->horiz_x == x);
-+
-+ last_x = x;
-+ }
-+ ctx->horiz_first = NULL;
-+ ctx->horiz_last = NULL;
-+#ifdef SANITYCHECK
-+ art_svp_intersect_sanitycheck_winding (ctx);
-+#endif
-+}
-+
-+#ifdef VERBOSE
-+static void
-+art_svp_intersect_print_active (ArtIntersectCtx *ctx)
-+{
-+ ArtActiveSeg *seg;
-+
-+ art_dprint ("Active list (y = %g):\n", ctx->y);
-+ for (seg = ctx->active_head; seg != NULL; seg = seg->right)
-+ {
-+ art_dprint (" %lx: (%g, %g)-(%g, %g), (a, b, c) = (%g, %g, %g)\n",
-+ (unsigned long)seg,
-+ seg->x[0], seg->y0, seg->x[1], seg->y1,
-+ seg->a, seg->b, seg->c);
-+ }
-+}
-+#endif
-+
-+#ifdef SANITYCHECK
-+static void
-+art_svp_intersect_sanitycheck (ArtIntersectCtx *ctx)
-+{
-+ ArtActiveSeg *seg;
-+ ArtActiveSeg *last = NULL;
-+ double d;
-+
-+ for (seg = ctx->active_head; seg != NULL; seg = seg->right)
-+ {
-+ if (seg->left != last)
-+ {
-+ art_warn ("*** art_svp_intersect_sanitycheck: last=%lx, seg->left=%lx\n",
-+ (unsigned long)last, (unsigned long)seg->left);
-+ }
-+ if (last != NULL)
-+ {
-+ /* pairwise compare with previous seg */
-+
-+ /* First the top. */
-+ if (last->y0 < seg->y0)
-+ {
-+ }
-+ else
-+ {
-+ }
-+
-+ /* Then the bottom. */
-+ if (last->y1 < seg->y1)
-+ {
-+ if (!((last->x[1] <
-+ seg->x[(seg->flags & ART_ACTIVE_FLAGS_BNEG) ^ 1]) ||
-+ last->y1 == seg->y0))
-+ {
-+ d = last->x[1] * seg->a + last->y1 * seg->b + seg->c;
-+ if (d >= -EPSILON_A)
-+ art_warn ("*** bottom (%g, %g) of %lx is not clear of %lx to right (d = %g)\n",
-+ last->x[1], last->y1, (unsigned long) last,
-+ (unsigned long) seg, d);
-+ }
-+ }
-+ else if (last->y1 > seg->y1)
-+
-+ {
-+ if (!((seg->x[1] >
-+ last->x[last->flags & ART_ACTIVE_FLAGS_BNEG]) ||
-+ seg->y1 == last->y0))
-+ {
-+ d = seg->x[1] * last->a + seg->y1 * last->b + last->c;
-+ if (d <= EPSILON_A)
-+ art_warn ("*** bottom (%g, %g) of %lx is not clear of %lx to left (d = %g)\n",
-+ seg->x[1], seg->y1, (unsigned long) seg,
-+ (unsigned long) last, d);
-+ }
-+ }
-+ else
-+ {
-+ if (last->x[1] > seg->x[1])
-+ art_warn ("*** bottoms (%g, %g) of %lx and (%g, %g) of %lx out of order\n",
-+ last->x[1], last->y1, (unsigned long)last,
-+ seg->x[1], seg->y1, (unsigned long)seg);
-+ }
-+ }
-+ last = seg;
-+ }
-+}
-+#endif
-+
-+void
-+art_svp_intersector (const ArtSVP *in, ArtSvpWriter *out)
-+{
-+ ArtIntersectCtx *ctx;
-+ ArtPriQ *pq;
-+ ArtPriPoint *first_point;
-+#ifdef VERBOSE
-+ int count = 0;
-+#endif
-+
-+ if (in->n_segs == 0)
-+ return;
-+
-+ ctx = art_new (ArtIntersectCtx, 1);
-+ ctx->in = in;
-+ ctx->out = out;
-+ pq = art_pri_new ();
-+ ctx->pq = pq;
-+
-+ ctx->active_head = NULL;
-+
-+ ctx->horiz_first = NULL;
-+ ctx->horiz_last = NULL;
-+
-+ ctx->in_curs = 0;
-+ first_point = art_new (ArtPriPoint, 1);
-+ first_point->x = in->segs[0].points[0].x;
-+ first_point->y = in->segs[0].points[0].y;
-+ first_point->user_data = NULL;
-+ ctx->y = first_point->y;
-+ art_pri_insert (pq, first_point);
-+
-+ while (!art_pri_empty (pq))
-+ {
-+ ArtPriPoint *pri_point = art_pri_choose (pq);
-+ ArtActiveSeg *seg = (ArtActiveSeg *)pri_point->user_data;
-+
-+#ifdef VERBOSE
-+ art_dprint ("\nIntersector step %d\n", count++);
-+ art_svp_intersect_print_active (ctx);
-+ art_dprint ("priq choose (%g, %g) %lx\n", pri_point->x, pri_point->y,
-+ (unsigned long)pri_point->user_data);
-+#endif
-+#ifdef SANITYCHECK
-+ art_svp_intersect_sanitycheck(ctx);
-+#endif
-+
-+ if (ctx->y != pri_point->y)
-+ {
-+ art_svp_intersect_horiz_commit (ctx);
-+ ctx->y = pri_point->y;
-+ }
-+
-+ if (seg == NULL)
-+ {
-+ /* Insert new segment from input */
-+ const ArtSVPSeg *in_seg = &in->segs[ctx->in_curs++];
-+ art_svp_intersect_add_seg (ctx, in_seg);
-+ if (ctx->in_curs < in->n_segs)
-+ {
-+ const ArtSVPSeg *next_seg = &in->segs[ctx->in_curs];
-+ pri_point->x = next_seg->points[0].x;
-+ pri_point->y = next_seg->points[0].y;
-+ /* user_data is already NULL */
-+ art_pri_insert (pq, pri_point);
-+ }
-+ else
-+ art_free (pri_point);
-+ }
-+ else
-+ {
-+ int n_stack = seg->n_stack;
-+
-+ if (n_stack > 1)
-+ {
-+ art_svp_intersect_process_intersection (ctx, seg);
-+ art_free (pri_point);
-+ }
-+ else
-+ {
-+ art_svp_intersect_advance_cursor (ctx, seg, pri_point);
-+ }
-+ }
-+ }
-+
-+ art_svp_intersect_horiz_commit (ctx);
-+
-+ art_pri_free (pq);
-+ art_free (ctx);
-+}
-+
-+#endif /* not TEST_PRIQ */
-diff -uNr /oocvs/OOO_STABLE_1-backup/external/gpc/art_svp_intersect.h external/gpc/art_svp_intersect.h
---- /oocvs/OOO_STABLE_1-backup/external/gpc/art_svp_intersect.h Wed Dec 31 18:00:00 1969
-+++ external/gpc/art_svp_intersect.h Fri Sep 20 21:42:19 2002
-@@ -0,0 +1,66 @@
-+/* Libart_LGPL - library of basic graphic primitives
-+ * Copyright (C) 2001 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_SVP_INTERSECT_H__
-+#define __ART_SVP_INTERSECT_H__
-+
-+/* The funky new SVP intersector. */
-+
-+#include "art_svp.h"
-+
-+#ifdef __cplusplus
-+extern "C" {
-+#endif /* __cplusplus */
-+
-+#ifndef ART_WIND_RULE_DEFINED
-+#define ART_WIND_RULE_DEFINED
-+typedef enum {
-+ ART_WIND_RULE_NONZERO,
-+ ART_WIND_RULE_INTERSECT,
-+ ART_WIND_RULE_ODDEVEN,
-+ ART_WIND_RULE_POSITIVE
-+} ArtWindRule;
-+#endif
-+
-+typedef struct _ArtSvpWriter ArtSvpWriter;
-+
-+struct _ArtSvpWriter {
-+ int (*add_segment) (ArtSvpWriter *self, int wind_left, int delta_wind,
-+ double x, double y);
-+ void (*add_point) (ArtSvpWriter *self, int seg_id, double x, double y);
-+ void (*close_segment) (ArtSvpWriter *self, int seg_id);
-+};
-+
-+ArtSvpWriter *
-+art_svp_writer_rewind_new (ArtWindRule rule);
-+
-+ArtSVP *
-+art_svp_writer_rewind_reap (ArtSvpWriter *self);
-+
-+int
-+art_svp_seg_compare (const void *s1, const void *s2);
-+
-+void
-+art_svp_intersector (const ArtSVP *in, ArtSvpWriter *out);
-+
-+#ifdef __cplusplus
-+}
-+#endif /* __cplusplus */
-+
-+#endif /* __ART_SVP_INTERSECT_H__ */
-diff -uNr /oocvs/OOO_STABLE_1-backup/external/gpc/art_svp_ops.c external/gpc/art_svp_ops.c
---- /oocvs/OOO_STABLE_1-backup/external/gpc/art_svp_ops.c Wed Dec 31 18:00:00 1969
-+++ external/gpc/art_svp_ops.c Wed Oct 9 20:16:52 2002
-@@ -0,0 +1,398 @@
-+/* 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.
-+ */
-+
-+#define noVERBOSE
-+
-+/* Vector path set operations, over sorted vpaths. */
-+
-+#include "art_svp_ops.h"
-+#include "art_misc.h"
-+#include "art_svp.h"
-+#include "art_vpath.h"
-+#include "art_svp_vpath.h"
-+#include "art_svp.h"
-+#ifdef ART_USE_NEW_INTERSECTOR
-+#include "art_svp_intersect.h"
-+#else
-+#include "art_svp_wind.h"
-+#endif
-+#include "art_vpath_svp.h"
-+
-+/* Merge the segments of the two svp's. The resulting svp will share
-+ segments with args passed in, so be super-careful with the
-+ allocation. */
-+/**
-+ * art_svp_merge: Merge the segments of two svp's.
-+ * @svp1: One svp to merge.
-+ * @svp2: The other svp to merge.
-+ *
-+ * Merges the segments of two SVP's into a new one. The resulting
-+ * #ArtSVP data structure will share the segments of the argument
-+ * svp's, so it is probably a good idea to free it shallowly,
-+ * especially if the arguments will be freed with art_svp_free().
-+ *
-+ * Return value: The merged #ArtSVP.
-+ **/
-+static ArtSVP *
-+art_svp_merge (const ArtSVP *svp1, const ArtSVP *svp2)
-+{
-+ ArtSVP *svp_new;
-+ int ix;
-+ int ix1, ix2;
-+
-+ svp_new = (ArtSVP *)art_alloc (sizeof(ArtSVP) +
-+ (svp1->n_segs + svp2->n_segs - 1) *
-+ sizeof(ArtSVPSeg));
-+ ix1 = 0;
-+ ix2 = 0;
-+ for (ix = 0; ix < svp1->n_segs + svp2->n_segs; ix++)
-+ {
-+ if (ix1 < svp1->n_segs &&
-+ (ix2 == svp2->n_segs ||
-+ art_svp_seg_compare (&svp1->segs[ix1], &svp2->segs[ix2]) < 1))
-+ svp_new->segs[ix] = svp1->segs[ix1++];
-+ else
-+ svp_new->segs[ix] = svp2->segs[ix2++];
-+ }
-+
-+ svp_new->n_segs = ix;
-+ return svp_new;
-+}
-+
-+#ifdef VERBOSE
-+
-+#define XOFF 50
-+#define YOFF 700
-+
-+static void
-+print_ps_vpath (ArtVpath *vpath)
-+{
-+ int i;
-+
-+ printf ("gsave %d %d translate 1 -1 scale\n", XOFF, YOFF);
-+ for (i = 0; vpath[i].code != ART_END; i++)
-+ {
-+ switch (vpath[i].code)
-+ {
-+ case ART_MOVETO:
-+ printf ("%g %g moveto\n", vpath[i].x, vpath[i].y);
-+ break;
-+ case ART_LINETO:
-+ printf ("%g %g lineto\n", vpath[i].x, vpath[i].y);
-+ break;
-+ default:
-+ break;
-+ }
-+ }
-+ printf ("stroke grestore showpage\n");
-+}
-+
-+#define DELT 4
-+
-+static void
-+print_ps_svp (ArtSVP *vpath)
-+{
-+ int i, j;
-+
-+ printf ("%% begin\n");
-+ for (i = 0; i < vpath->n_segs; i++)
-+ {
-+ printf ("%g setgray\n", vpath->segs[i].dir ? 0.7 : 0);
-+ for (j = 0; j < vpath->segs[i].n_points; j++)
-+ {
-+ printf ("%g %g %s\n",
-+ XOFF + vpath->segs[i].points[j].x,
-+ YOFF - vpath->segs[i].points[j].y,
-+ j ? "lineto" : "moveto");
-+ }
-+ printf ("%g %g moveto %g %g lineto %g %g lineto %g %g lineto stroke\n",
-+ XOFF + vpath->segs[i].points[0].x - DELT,
-+ YOFF - DELT - vpath->segs[i].points[0].y,
-+ XOFF + vpath->segs[i].points[0].x - DELT,
-+ YOFF - vpath->segs[i].points[0].y,
-+ XOFF + vpath->segs[i].points[0].x + DELT,
-+ YOFF - vpath->segs[i].points[0].y,
-+ XOFF + vpath->segs[i].points[0].x + DELT,
-+ YOFF - DELT - vpath->segs[i].points[0].y);
-+ printf ("%g %g moveto %g %g lineto %g %g lineto %g %g lineto stroke\n",
-+ XOFF + vpath->segs[i].points[j - 1].x - DELT,
-+ YOFF + DELT - vpath->segs[i].points[j - 1].y,
-+ XOFF + vpath->segs[i].points[j - 1].x - DELT,
-+ YOFF - vpath->segs[i].points[j - 1].y,
-+ XOFF + vpath->segs[i].points[j - 1].x + DELT,
-+ YOFF - vpath->segs[i].points[j - 1].y,
-+ XOFF + vpath->segs[i].points[j - 1].x + DELT,
-+ YOFF + DELT - vpath->segs[i].points[j - 1].y);
-+ printf ("stroke\n");
-+ }
-+
-+ printf ("showpage\n");
-+}
-+#endif
-+
-+#ifndef ART_USE_NEW_INTERSECTOR
-+static ArtSVP *
-+art_svp_merge_perturbed (const ArtSVP *svp1, const ArtSVP *svp2)
-+{
-+ ArtVpath *vpath1, *vpath2;
-+ ArtVpath *vpath1_p, *vpath2_p;
-+ ArtSVP *svp1_p, *svp2_p;
-+ ArtSVP *svp_new;
-+
-+ vpath1 = art_vpath_from_svp (svp1);
-+ vpath1_p = art_vpath_perturb (vpath1);
-+ art_free (vpath1);
-+ svp1_p = art_svp_from_vpath (vpath1_p);
-+ art_free (vpath1_p);
-+
-+ vpath2 = art_vpath_from_svp (svp2);
-+ vpath2_p = art_vpath_perturb (vpath2);
-+ art_free (vpath2);
-+ svp2_p = art_svp_from_vpath (vpath2_p);
-+ art_free (vpath2_p);
-+
-+ svp_new = art_svp_merge (svp1_p, svp2_p);
-+#ifdef VERBOSE
-+ print_ps_svp (svp1_p);
-+ print_ps_svp (svp2_p);
-+ print_ps_svp (svp_new);
-+#endif
-+ art_free (svp1_p);
-+ art_free (svp2_p);
-+
-+ return svp_new;
-+}
-+#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:
-+
-+ 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 isolated segments may
-+ appear.
-+
-+*/
-+
-+/**
-+ * art_svp_intersect: Compute the intersection of two sorted vector paths.
-+ * @svp1: One sorted vector path.
-+ * @svp2: The other sorted vector path.
-+ *
-+ * Computes the intersection 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 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 intersection of @svp1 and @svp2.
-+ **/
-+ArtSVP *
-+art_svp_intersect (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_INTERSECT);
-+ 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_INTERSECT);
-+ art_svp_free (svp4);
-+ return svp_new;
-+#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
-diff -uNr /oocvs/OOO_STABLE_1-backup/external/gpc/art_svp_ops.h external/gpc/art_svp_ops.h
---- /oocvs/OOO_STABLE_1-backup/external/gpc/art_svp_ops.h Wed Dec 31 18:00:00 1969
-+++ external/gpc/art_svp_ops.h Fri Sep 20 21:36:53 2002
-@@ -0,0 +1,40 @@
-+/* 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_SVP_OPS_H__
-+#define __ART_SVP_OPS_H__
-+
-+#include "art_svp.h"
-+
-+#ifdef __cplusplus
-+extern "C" {
-+#endif /* __cplusplus */
-+
-+/* 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
-+}
-+#endif /* __cplusplus */
-+
-+#endif /* __ART_SVP_OPS_H__ */
-diff -uNr /oocvs/OOO_STABLE_1-backup/external/gpc/art_svp_vpath.c external/gpc/art_svp_vpath.c
---- /oocvs/OOO_STABLE_1-backup/external/gpc/art_svp_vpath.c Wed Dec 31 18:00:00 1969
-+++ external/gpc/art_svp_vpath.c Fri Sep 20 20:33:09 2002
-@@ -0,0 +1,213 @@
-+/* 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.
-+ */
-+
-+/* Sort vector paths into sorted vector paths */
-+
-+#include "art_svp_vpath.h"
-+
-+#include <stdlib.h>
-+#include <math.h>
-+
-+#include "art_misc.h"
-+#include "art_vpath.h"
-+#include "art_svp.h"
-+
-+
-+/* reverse a list of points in place */
-+static void
-+reverse_points (ArtPoint *points, int n_points)
-+{
-+ int i;
-+ ArtPoint tmp_p;
-+
-+ for (i = 0; i < (n_points >> 1); i++)
-+ {
-+ tmp_p = points[i];
-+ points[i] = points[n_points - (i + 1)];
-+ points[n_points - (i + 1)] = tmp_p;
-+ }
-+}
-+
-+/**
-+ * art_svp_from_vpath: Convert a vpath to a sorted vector path.
-+ * @vpath: #ArtVPath to convert.
-+ *
-+ * Converts a vector path into sorted vector path form. The svp form is
-+ * more efficient for rendering and other vector operations.
-+ *
-+ * Basically, the implementation is to traverse the vector path,
-+ * generating a new segment for each "run" of points in the vector
-+ * path with monotonically increasing Y values. All the resulting
-+ * values are then sorted.
-+ *
-+ * Note: I'm not sure that the sorting rule is correct with respect
-+ * to numerical stability issues.
-+ *
-+ * Return value: Resulting sorted vector path.
-+ **/
-+ArtSVP *
-+art_svp_from_vpath (ArtVpath *vpath)
-+{
-+ int n_segs, n_segs_max;
-+ ArtSVP *svp;
-+ int dir;
-+ int new_dir;
-+ int i;
-+ ArtPoint *points;
-+ int n_points, n_points_max;
-+ double x, y;
-+ double x_min, x_max;
-+
-+ n_segs = 0;
-+ n_segs_max = 16;
-+ svp = (ArtSVP *)art_alloc (sizeof(ArtSVP) +
-+ (n_segs_max - 1) * sizeof(ArtSVPSeg));
-+
-+ dir = 0;
-+ n_points = 0;
-+ n_points_max = 0;
-+ points = NULL;
-+ i = 0;
-+
-+ x = y = 0; /* unnecessary, given "first code must not be LINETO" invariant,
-+ but it makes gcc -Wall -ansi -pedantic happier */
-+ x_min = x_max = 0; /* same */
-+
-+ while (vpath[i].code != ART_END) {
-+ if (vpath[i].code == ART_MOVETO || vpath[i].code == ART_MOVETO_OPEN)
-+ {
-+ if (points != NULL && n_points >= 2)
-+ {
-+ if (n_segs == n_segs_max)
-+ {
-+ n_segs_max <<= 1;
-+ svp = (ArtSVP *)art_realloc (svp, sizeof(ArtSVP) +
-+ (n_segs_max - 1) *
-+ sizeof(ArtSVPSeg));
-+ }
-+ svp->segs[n_segs].n_points = n_points;
-+ svp->segs[n_segs].dir = (dir > 0);
-+ if (dir < 0)
-+ reverse_points (points, n_points);
-+ svp->segs[n_segs].points = points;
-+ svp->segs[n_segs].bbox.x0 = x_min;
-+ svp->segs[n_segs].bbox.x1 = x_max;
-+ svp->segs[n_segs].bbox.y0 = points[0].y;
-+ svp->segs[n_segs].bbox.y1 = points[n_points - 1].y;
-+ n_segs++;
-+ points = NULL;
-+ }
-+
-+ if (points == NULL)
-+ {
-+ n_points_max = 4;
-+ points = art_new (ArtPoint, n_points_max);
-+ }
-+
-+ n_points = 1;
-+ points[0].x = x = vpath[i].x;
-+ points[0].y = y = vpath[i].y;
-+ x_min = x;
-+ x_max = x;
-+ dir = 0;
-+ }
-+ else /* must be LINETO */
-+ {
-+ new_dir = (vpath[i].y > y ||
-+ (vpath[i].y == y && vpath[i].x > x)) ? 1 : -1;
-+ if (dir && dir != new_dir)
-+ {
-+ /* new segment */
-+ x = points[n_points - 1].x;
-+ y = points[n_points - 1].y;
-+ if (n_segs == n_segs_max)
-+ {
-+ n_segs_max <<= 1;
-+ svp = (ArtSVP *)art_realloc (svp, sizeof(ArtSVP) +
-+ (n_segs_max - 1) *
-+ sizeof(ArtSVPSeg));
-+ }
-+ svp->segs[n_segs].n_points = n_points;
-+ svp->segs[n_segs].dir = (dir > 0);
-+ if (dir < 0)
-+ reverse_points (points, n_points);
-+ svp->segs[n_segs].points = points;
-+ svp->segs[n_segs].bbox.x0 = x_min;
-+ svp->segs[n_segs].bbox.x1 = x_max;
-+ svp->segs[n_segs].bbox.y0 = points[0].y;
-+ svp->segs[n_segs].bbox.y1 = points[n_points - 1].y;
-+ n_segs++;
-+
-+ n_points = 1;
-+ n_points_max = 4;
-+ points = art_new (ArtPoint, n_points_max);
-+ points[0].x = x;
-+ points[0].y = y;
-+ x_min = x;
-+ x_max = x;
-+ }
-+
-+ if (points != NULL)
-+ {
-+ if (n_points == n_points_max)
-+ art_expand (points, ArtPoint, n_points_max);
-+ points[n_points].x = x = vpath[i].x;
-+ points[n_points].y = y = vpath[i].y;
-+ if (x < x_min) x_min = x;
-+ else if (x > x_max) x_max = x;
-+ n_points++;
-+ }
-+ dir = new_dir;
-+ }
-+ i++;
-+ }
-+
-+ if (points != NULL)
-+ {
-+ if (n_points >= 2)
-+ {
-+ if (n_segs == n_segs_max)
-+ {
-+ n_segs_max <<= 1;
-+ svp = (ArtSVP *)art_realloc (svp, sizeof(ArtSVP) +
-+ (n_segs_max - 1) *
-+ sizeof(ArtSVPSeg));
-+ }
-+ svp->segs[n_segs].n_points = n_points;
-+ svp->segs[n_segs].dir = (dir > 0);
-+ if (dir < 0)
-+ reverse_points (points, n_points);
-+ svp->segs[n_segs].points = points;
-+ svp->segs[n_segs].bbox.x0 = x_min;
-+ svp->segs[n_segs].bbox.x1 = x_max;
-+ svp->segs[n_segs].bbox.y0 = points[0].y;
-+ svp->segs[n_segs].bbox.y1 = points[n_points - 1].y;
-+ n_segs++;
-+ }
-+ else
-+ art_free (points);
-+ }
-+
-+ svp->n_segs = n_segs;
-+
-+ qsort (&svp->segs, n_segs, sizeof (ArtSVPSeg), art_svp_seg_compare);
-+
-+ return svp;
-+}
-+
-diff -uNr /oocvs/OOO_STABLE_1-backup/external/gpc/art_svp_vpath.h external/gpc/art_svp_vpath.h
---- /oocvs/OOO_STABLE_1-backup/external/gpc/art_svp_vpath.h Wed Dec 31 18:00:00 1969
-+++ external/gpc/art_svp_vpath.h Fri Sep 20 21:37:06 2002
-@@ -0,0 +1,39 @@
-+/* 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_SVP_VPATH_H__
-+#define __ART_SVP_VPATH_H__
-+
-+#include "art_svp.h"
-+#include "art_vpath.h"
-+
-+/* Sort vector paths into sorted vector paths. */
-+
-+#ifdef __cplusplus
-+extern "C" {
-+#endif /* __cplusplus */
-+
-+ArtSVP *
-+art_svp_from_vpath (ArtVpath *vpath);
-+
-+#ifdef __cplusplus
-+}
-+#endif /* __cplusplus */
-+
-+#endif /* __ART_SVP_VPATH_H__ */
-diff -uNr /oocvs/OOO_STABLE_1-backup/external/gpc/art_vpath.c external/gpc/art_vpath.c
---- /oocvs/OOO_STABLE_1-backup/external/gpc/art_vpath.c Wed Dec 31 18:00:00 1969
-+++ external/gpc/art_vpath.c Fri Sep 20 20:33:38 2002
-@@ -0,0 +1,239 @@
-+/* 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.
-+ */
-+
-+/* Basic constructors and operations for vector paths */
-+
-+#include "art_vpath.h"
-+
-+#include <math.h>
-+#include <stdlib.h>
-+
-+#include "art_misc.h"
-+#include "art_rect.h"
-+
-+/**
-+ * art_vpath_add_point: Add point to vpath.
-+ * @p_vpath: Where the pointer to the #ArtVpath structure is stored.
-+ * @pn_points: Pointer to the number of points in *@p_vpath.
-+ * @pn_points_max: Pointer to the number of points allocated.
-+ * @code: The pathcode for the new point.
-+ * @x: The X coordinate of the new point.
-+ * @y: The Y coordinate of the new point.
-+ *
-+ * Adds a new point to *@p_vpath, reallocating and updating *@p_vpath
-+ * and *@pn_points_max as necessary. *@pn_points is incremented.
-+ *
-+ * This routine always adds the point after all points already in the
-+ * vpath. Thus, it should be called in the order the points are
-+ * desired.
-+ **/
-+void
-+art_vpath_add_point (ArtVpath **p_vpath, int *pn_points, int *pn_points_max,
-+ ArtPathcode code, double x, double y)
-+{
-+ int i;
-+
-+ i = (*pn_points)++;
-+ if (i == *pn_points_max)
-+ art_expand (*p_vpath, ArtVpath, *pn_points_max);
-+ (*p_vpath)[i].code = code;
-+ (*p_vpath)[i].x = x;
-+ (*p_vpath)[i].y = y;
-+}
-+
-+/* number of steps should really depend on radius. */
-+#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.
-+ *
-+ * Determines bounding box of @vec, and stores it in @drect.
-+ **/
-+void
-+art_vpath_bbox_drect (const ArtVpath *vec, ArtDRect *drect)
-+{
-+ int i;
-+ double x0, y0, x1, y1;
-+
-+ if (vec[0].code == ART_END)
-+ {
-+ x0 = y0 = x1 = y1 = 0;
-+ }
-+ else
-+ {
-+ x0 = x1 = vec[0].x;
-+ y0 = y1 = vec[0].y;
-+ for (i = 1; vec[i].code != ART_END; i++)
-+ {
-+ if (vec[i].x < x0) x0 = vec[i].x;
-+ if (vec[i].x > x1) x1 = vec[i].x;
-+ if (vec[i].y < y0) y0 = vec[i].y;
-+ if (vec[i].y > y1) y1 = vec[i].y;
-+ }
-+ }
-+ drect->x0 = x0;
-+ drect->y0 = y0;
-+ drect->x1 = x1;
-+ drect->y1 = y1;
-+}
-+
-+/**
-+ * art_vpath_bbox_irect: Determine integer bounding box of vpath.
-+ * @vec: Source vpath.
-+ * idrect: Where to store bounding box.
-+ *
-+ * Determines integer bounding box of @vec, and stores it in @irect.
-+ **/
-+void
-+art_vpath_bbox_irect (const ArtVpath *vec, ArtIRect *irect)
-+{
-+ ArtDRect drect;
-+
-+ art_vpath_bbox_drect (vec, &drect);
-+ 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 -uNr /oocvs/OOO_STABLE_1-backup/external/gpc/art_vpath.h external/gpc/art_vpath.h
---- /oocvs/OOO_STABLE_1-backup/external/gpc/art_vpath.h Wed Dec 31 18:00:00 1969
-+++ external/gpc/art_vpath.h Fri Sep 20 21:37:17 2002
-@@ -0,0 +1,66 @@
-+/* 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_VPATH_H__
-+#define __ART_VPATH_H__
-+
-+#include "art_rect.h"
-+#include "art_pathcode.h"
-+
-+/* Basic data structures and constructors for simple vector paths */
-+
-+#ifdef __cplusplus
-+extern "C" {
-+#endif /* __cplusplus */
-+
-+typedef struct _ArtVpath ArtVpath;
-+
-+/* CURVETO is not allowed! */
-+struct _ArtVpath {
-+ ArtPathcode code;
-+ double x;
-+ double y;
-+};
-+
-+/* Some of the functions need to go into their own modules */
-+
-+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 */
-+
-+#endif /* __ART_VPATH_H__ */
-diff -uNr /oocvs/OOO_STABLE_1-backup/external/gpc/art_vpath_svp.c external/gpc/art_vpath_svp.c
---- /oocvs/OOO_STABLE_1-backup/external/gpc/art_vpath_svp.c Wed Dec 31 18:00:00 1969
-+++ external/gpc/art_vpath_svp.c Fri Sep 20 20:34:11 2002
-@@ -0,0 +1,195 @@
-+/* 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.
-+ */
-+
-+/* "Unsort" a sorted vector path into an ordinary vector path. */
-+
-+#include "art_vpath_svp.h"
-+
-+#include <stdio.h> /* for printf - debugging */
-+#include "art_misc.h"
-+
-+#include "art_vpath.h"
-+#include "art_svp.h"
-+
-+typedef struct _ArtVpathSVPEnd ArtVpathSVPEnd;
-+
-+struct _ArtVpathSVPEnd {
-+ int seg_num;
-+ int which; /* 0 = top, 1 = bottom */
-+ double x, y;
-+};
-+
-+#define EPSILON 1e-6
-+
-+static int
-+art_vpath_svp_point_compare (double x1, double y1, double x2, double y2)
-+{
-+ if (y1 - EPSILON > y2) return 1;
-+ if (y1 + EPSILON < y2) return -1;
-+ if (x1 - EPSILON > x2) return 1;
-+ if (x1 + EPSILON < x2) return -1;
-+ return 0;
-+}
-+
-+static int
-+art_vpath_svp_compare (const void *s1, const void *s2)
-+{
-+ const ArtVpathSVPEnd *e1 = s1;
-+ const ArtVpathSVPEnd *e2 = s2;
-+
-+ return art_vpath_svp_point_compare (e1->x, e1->y, e2->x, e2->y);
-+}
-+
-+/* Convert from sorted vector path representation into regular
-+ vector path representation.
-+
-+ Status of this routine:
-+
-+ Basic correctness: Only works with closed paths.
-+
-+ Numerical stability: Not known to work when more than two segments
-+ meet at a point.
-+
-+ Speed: Should be pretty good.
-+
-+ Precision: Does not degrade precision.
-+
-+*/
-+/**
-+ * art_vpath_from_svp: Convert from svp to vpath form.
-+ * @svp: Original #ArtSVP.
-+ *
-+ * Converts the sorted vector path @svp into standard vpath form.
-+ *
-+ * Return value: the newly allocated vpath.
-+ **/
-+ArtVpath *
-+art_vpath_from_svp (const ArtSVP *svp)
-+{
-+ int n_segs = svp->n_segs;
-+ ArtVpathSVPEnd *ends;
-+ ArtVpath *new;
-+ int *visited;
-+ int n_new, n_new_max;
-+ int i, k;
-+ int j = 0; /* Quiet compiler */
-+ int seg_num;
-+ int first;
-+ double last_x, last_y;
-+ int n_points;
-+ int pt_num;
-+
-+ last_x = 0; /* to eliminate "uninitialized" warning */
-+ last_y = 0;
-+
-+ ends = art_new (ArtVpathSVPEnd, n_segs * 2);
-+ for (i = 0; i < svp->n_segs; i++)
-+ {
-+ int lastpt;
-+
-+ ends[i * 2].seg_num = i;
-+ ends[i * 2].which = 0;
-+ ends[i * 2].x = svp->segs[i].points[0].x;
-+ ends[i * 2].y = svp->segs[i].points[0].y;
-+
-+ lastpt = svp->segs[i].n_points - 1;
-+ ends[i * 2 + 1].seg_num = i;
-+ ends[i * 2 + 1].which = 1;
-+ ends[i * 2 + 1].x = svp->segs[i].points[lastpt].x;
-+ ends[i * 2 + 1].y = svp->segs[i].points[lastpt].y;
-+ }
-+ qsort (ends, n_segs * 2, sizeof (ArtVpathSVPEnd), art_vpath_svp_compare);
-+
-+ n_new = 0;
-+ n_new_max = 16; /* I suppose we _could_ estimate this from traversing
-+ the svp, so we don't have to reallocate */
-+ new = art_new (ArtVpath, n_new_max);
-+
-+ visited = art_new (int, n_segs);
-+ for (i = 0; i < n_segs; i++)
-+ visited[i] = 0;
-+
-+ first = 1;
-+ for (i = 0; i < n_segs; i++)
-+ {
-+ if (!first)
-+ {
-+ /* search for the continuation of the existing subpath */
-+ /* This could be a binary search (which is why we sorted, above) */
-+ for (j = 0; j < n_segs * 2; j++)
-+ {
-+ if (!visited[ends[j].seg_num] &&
-+ art_vpath_svp_point_compare (last_x, last_y,
-+ ends[j].x, ends[j].y) == 0)
-+ break;
-+ }
-+ if (j == n_segs * 2)
-+ first = 1;
-+ }
-+ if (first)
-+ {
-+ /* start a new subpath */
-+ for (j = 0; j < n_segs * 2; j++)
-+ if (!visited[ends[j].seg_num])
-+ break;
-+ }
-+ if (j == n_segs * 2)
-+ {
-+ printf ("failure\n");
-+ }
-+ seg_num = ends[j].seg_num;
-+ n_points = svp->segs[seg_num].n_points;
-+ for (k = 0; k < n_points; k++)
-+ {
-+ pt_num = svp->segs[seg_num].dir ? k : n_points - (1 + k);
-+ if (k == 0)
-+ {
-+ if (first)
-+ {
-+ art_vpath_add_point (&new, &n_new, &n_new_max,
-+ ART_MOVETO,
-+ svp->segs[seg_num].points[pt_num].x,
-+ svp->segs[seg_num].points[pt_num].y);
-+ }
-+ }
-+ else
-+ {
-+ art_vpath_add_point (&new, &n_new, &n_new_max,
-+ ART_LINETO,
-+ svp->segs[seg_num].points[pt_num].x,
-+ svp->segs[seg_num].points[pt_num].y);
-+ if (k == n_points - 1)
-+ {
-+ last_x = svp->segs[seg_num].points[pt_num].x;
-+ last_y = svp->segs[seg_num].points[pt_num].y;
-+ /* to make more robust, check for meeting first_[xy],
-+ set first if so */
-+ }
-+ }
-+ first = 0;
-+ }
-+ visited[seg_num] = 1;
-+ }
-+
-+ art_vpath_add_point (&new, &n_new, &n_new_max,
-+ ART_END, 0, 0);
-+ art_free (visited);
-+ art_free (ends);
-+ return new;
-+}
-diff -uNr /oocvs/OOO_STABLE_1-backup/external/gpc/art_vpath_svp.h external/gpc/art_vpath_svp.h
---- /oocvs/OOO_STABLE_1-backup/external/gpc/art_vpath_svp.h Wed Dec 31 18:00:00 1969
-+++ external/gpc/art_vpath_svp.h Fri Sep 20 21:37:33 2002
-@@ -0,0 +1,38 @@
-+/* 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_VPATH_SVP_H__
-+#define __ART_VPATH_SVP_H__
-+
-+/* "Unsort" a sorted vector path into an ordinary vector path. */
-+
-+#include "art_svp.h"
-+#include "art_vpath.h"
-+
-+#ifdef __cplusplus
-+extern "C" {
-+#endif /* __cplusplus */
-+
-+ArtVpath *art_vpath_from_svp (const ArtSVP *svp);
-+
-+#ifdef __cplusplus
-+}
-+#endif /* __cplusplus */
-+
-+#endif /* __ART_VPATH_SVP_H__ */
-diff -uNr /oocvs/OOO_STABLE_1-backup/external/gpc/makefile.mk external/gpc/makefile.mk
---- /oocvs/OOO_STABLE_1-backup/external/gpc/makefile.mk Wed Apr 18 08:41:33 2001
-+++ external/gpc/makefile.mk Fri Sep 20 21:42:54 2002
-@@ -73,7 +73,12 @@
-
- # --- Files --------------------------------------------------------
-
--SLOFILES = $(SLO)$/gpc.obj
-+#SLOFILES = $(SLO)$/gpc.obj
-+
-+OBJFILES = $(OBJ)$/art_svp_intersect.obj $(OBJ)$/art_misc.obj $(OBJ)$/art_rect.obj $(OBJ)$/art_svp.obj $(OBJ)$/art_svp_ops.obj $(OBJ)$/art_svp_vpath.obj $(OBJ)$/art_vpath.obj $(OBJ)$/art_vpath_svp.obj
-+
-+SLOFILES = $(SLO)$/art_svp_intersect.obj $(SLO)$/art_misc.obj $(SLO)$/art_rect.obj $(SLO)$/art_svp.obj $(SLO)$/art_svp_ops.obj $(SLO)$/art_svp_vpath.obj $(SLO)$/art_vpath.obj $(SLO)$/art_vpath_svp.obj
-+
-
-
- LIB1TARGET=$(SLB)$/$(TARGET).lib
-diff -uNr /oocvs/OOO_STABLE_1-backup/external/prj/d.lst external/prj/d.lst
---- /oocvs/OOO_STABLE_1-backup/external/prj/d.lst Tue Jun 26 06:07:02 2001
-+++ external/prj/d.lst Fri Sep 20 22:19:37 2002
-@@ -36,7 +36,7 @@
- ..\dt\rtufiles\*.h %_DEST%\inc%_EXT%\external\dt\*.h
- ..\glibc\rtufiles\config.h %_DEST%\inc%_EXT%\external\glibc\config.h
- ..\glibc\rtufiles\getopt.h %_DEST%\inc%_EXT%\external\glibc\getopt.h
--..\gpc\gpc.h %_DEST%\inc%_EXT%\external\gpc\gpc.h
-+..\gpc\*.h %_DEST%\inc%_EXT%\external\gpc\*.h
- ..\npsdk\rtufiles\*.h %_DEST%\inc%_EXT%\external\npsdk\*.h
- ..\odbc\rtufiles\*.h %_DEST%\inc%_EXT%\external\odbc\*.h
- ..\sane\*.h %_DEST%\inc%_EXT%\external\sane\*.h
-diff -u -r1.5 poly.hxx
---- poly.hxx 2001/03/22 13:19:21 1.5
-+++ vcl/inc/poly.hxx 2002/10/02 17:00:08
-@@ -250,13 +250,16 @@
- private:
-
- ImplPolyPolygon* mpImplPolyPolygon;
--
-+#if 0
- #if _SOLAR__PRIVATE
-
- void* ImplCreateGPCPolygon() const;
- void ImplDoOperation( const PolyPolygon& rPolyPoly, PolyPolygon& rResult, ULONG nOperation ) const;
-
- #endif // __PRIVATE
-+#endif
-+ void *ImplCreateArtVpath () const;
-+ void ImplSetFromArtVpath (void *_vpath);
-
- public:
-
-diff -u -r1.4.16.1 poly2.cxx
---- poly2.cxx 2002/06/04 12:56:14 1.4.16.1
-+++ vcl/source/gdi/poly2.cxx 2002/10/10 00:47:04
-@@ -60,13 +60,21 @@
- ************************************************************************/
-
- #define _SV_POLY2_CXX
--
-+#if 0
- #ifndef __gpc_h
--extern "C"
-+extern "C"
- {
-- #include <external/gpc/gpc.h>
-+ #include <external/gpc/gpc.h>
- }
- #endif
-+#endif
-+#include <external/gpc/art_misc.h>
-+#include <external/gpc/art_vpath.h>
-+#include <external/gpc/art_svp.h>
-+#include <external/gpc/art_svp_vpath.h>
-+#include <external/gpc/art_vpath_svp.h>
-+#include <external/gpc/art_svp_ops.h>
-+#include <external/gpc/art_svp_intersect.h>
-
- #ifdef W31
- #include <tools/svwin.h>
-@@ -357,7 +365,7 @@
- if( bEdges )
- {
- const Rectangle aBound( GetBoundRect() );
--
-+
- fArea = ( aBound.GetWidth() + aBound.GetHeight() ) * 0.5;
- nPercent = pData ? pData->GetPercentValue() : 50;
- nOptimizeFlags &= ~POLY_OPTIMIZE_EDGES;
-@@ -402,36 +410,133 @@
- }
- }
-
-+/* Converts an arbitrary SVP to an even-odd SVP */
-+static ArtSVP *
-+svp_to_even_odd (ArtSVP *svp)
-+{
-+ ArtSvpWriter *svw;
-+ ArtSVP *result;
-+
-+ svw = art_svp_writer_rewind_new (ART_WIND_RULE_ODDEVEN);
-+ art_svp_intersector (svp, svw);
-+
-+ result = art_svp_writer_rewind_reap (svw);
-+ art_free (svp); /* Shallow free because the result contains shared segments */
-+
-+ return result;
-+}
-+
-+
- // -----------------------------------------------------------------------
-
- void PolyPolygon::GetIntersection( const PolyPolygon& rPolyPoly, PolyPolygon& rResult ) const
--{
-+{
-+ ArtVpath *a, *b;
-+ ArtSVP *sa, *sb, *s;
-+
-+ a = (ArtVpath *) ImplCreateArtVpath ();
-+ b = (ArtVpath *) rPolyPoly.ImplCreateArtVpath ();
-+
-+ sa = svp_to_even_odd (art_svp_from_vpath (a));
-+ sb = svp_to_even_odd (art_svp_from_vpath (b));
-+
-+ art_free (a);
-+ art_free (b);
-+
-+ s = art_svp_intersect (sa, sb);
-+ a = art_vpath_from_svp (s);
-+ art_svp_free (s);
-+
-+ rResult.ImplSetFromArtVpath (a);
-+ art_free (a);
-+#if 0
- ImplDoOperation( rPolyPoly, rResult, GPC_INT );
-+#endif
- }
-
- // -----------------------------------------------------------------------
-
- void PolyPolygon::GetUnion( const PolyPolygon& rPolyPoly, PolyPolygon& rResult ) const
- {
-+ ArtVpath *a, *b;
-+ ArtSVP *sa, *sb, *s;
-+
-+ a = (ArtVpath *) ImplCreateArtVpath ();
-+ b = (ArtVpath *) rPolyPoly.ImplCreateArtVpath ();
-+
-+ sa = svp_to_even_odd (art_svp_from_vpath (a));
-+ sb = svp_to_even_odd (art_svp_from_vpath (b));
-+
-+ art_free (a);
-+ art_free (b);
-+
-+ s = art_svp_union (sa, sb);
-+ a = art_vpath_from_svp (s);
-+ art_svp_free (s);
-+
-+ rResult.ImplSetFromArtVpath (a);
-+ art_free (a);
-+#if 0
- ImplDoOperation( rPolyPoly, rResult, GPC_UNION );
-+#endif
- }
-
- // -----------------------------------------------------------------------
-
- void PolyPolygon::GetDifference( const PolyPolygon& rPolyPoly, PolyPolygon& rResult ) const
- {
-+ ArtVpath *a, *b;
-+ ArtSVP *sa, *sb, *s;
-+
-+ a = (ArtVpath *) ImplCreateArtVpath ();
-+ b = (ArtVpath *) rPolyPoly.ImplCreateArtVpath ();
-+
-+ sa = svp_to_even_odd (art_svp_from_vpath (a));
-+ sb = svp_to_even_odd (art_svp_from_vpath (b));
-+
-+ art_free (a);
-+ art_free (b);
-+
-+ s = art_svp_minus (sa, sb);
-+ a = art_vpath_from_svp (s);
-+ art_svp_free (s);
-+
-+ rResult.ImplSetFromArtVpath (a);
-+ art_free (a);
-+#if 0
- ImplDoOperation( rPolyPoly, rResult, GPC_DIFF );
-+#endif
- }
-
- // -----------------------------------------------------------------------
-
- void PolyPolygon::GetXOR( const PolyPolygon& rPolyPoly, PolyPolygon& rResult ) const
- {
-+ ArtVpath *a, *b;
-+ ArtSVP *sa, *sb, *s;
-+
-+ a = (ArtVpath *) ImplCreateArtVpath ();
-+ b = (ArtVpath *) rPolyPoly.ImplCreateArtVpath ();
-+
-+ sa = svp_to_even_odd (art_svp_from_vpath (a));
-+ sb = svp_to_even_odd (art_svp_from_vpath (b));
-+
-+ art_free (a);
-+ art_free (b);
-+
-+ s = art_svp_diff (sa, sb); /* symmetric difference, *not* set difference */
-+ a = art_vpath_from_svp (s);
-+ art_svp_free (s);
-+
-+ rResult.ImplSetFromArtVpath (a);
-+ art_free (a);
-+#if 0
- ImplDoOperation( rPolyPoly, rResult, GPC_XOR );
-+#endif
- }
-
- // -----------------------------------------------------------------------
--
-+#if 0
- void* PolyPolygon::ImplCreateGPCPolygon() const
- {
- gpc_polygon* pRet = new gpc_polygon;
-@@ -482,6 +587,8 @@
-
- gpc_polygon_clip( (gpc_op) nOperation, pGPCPoly1, pGPCPoly2, pResult );
-
-+ fprintf (stderr, "PolyPolygon::ImplDoOperation %ld\n", nOperation);
-+
- rResult.Clear();
-
- for( int i = 0; i < pResult->num_contours; i++ )
-@@ -508,6 +615,178 @@
- gpc_free_polygon( pResult );
- delete pResult;
- }
-+#endif
-+
-+/* Finds the index of the upper rightmost vertex of a polygon */
-+static int
-+upper_rightmost_vertex (const Polygon &poly)
-+{
-+ int n;
-+ int i;
-+ double x, y;
-+ int k;
-+
-+ n = poly.GetSize ();
-+
-+ k = 0;
-+ x = poly[0].X ();
-+ y = poly[0].Y ();
-+
-+ for (i = 1; i < n; i++)
-+ if (poly[i].Y () < y || (poly[0].Y () == y && poly[i].X () > x)) {
-+ k = i;
-+ x = poly[i].X ();
-+ y = poly[i].Y ();
-+ }
-+
-+ return k;
-+}
-+
-+/* Returns whether a polygon is specified in counterclockwise order */
-+static BOOL
-+poly_is_ccw (const Polygon &poly)
-+{
-+ int n;
-+ int k;
-+ double cross;
-+
-+ n = poly.GetSize ();
-+
-+ if (n == 0)
-+ return TRUE;
-+
-+ k = upper_rightmost_vertex (poly);
-+
-+ const Point &a = poly[(k + n - 1) % n];
-+ const Point &b = poly[k];
-+ const Point &c = poly[(k + 1) % n];
-+
-+ cross = -(a.X () * b.Y () - a.Y () * b.X () +
-+ a.Y () * c.X () - a.X () * c.Y () +
-+ b.X () * c.Y () - c.X () * b.Y ());
-+
-+ return (cross > 0);
-+}
-+
-+void *
-+PolyPolygon::ImplCreateArtVpath () const
-+{
-+ ArtVpath *vpath;
-+ int n_contours;
-+ int n_vertices;
-+ int i, v;
-+
-+ n_contours = Count ();
-+ n_vertices = 0;
-+ for (i = 0; i < n_contours; i++) {
-+ const Polygon &poly = GetObject (i);
-+ n_vertices += poly.GetSize () + 1; /* plus 1 for if we have to close the path */
-+ }
-+
-+ n_vertices++; /* for the ART_END terminator */
-+
-+ vpath = art_new (ArtVpath, n_vertices);
-+ v = 0;
-+
-+ for (i = 0; i < n_contours; i++) {
-+ int j, k;
-+ int n;
-+ const Polygon &poly = GetObject (i);
-+ BOOL ccw;
-+
-+ n = poly.GetSize ();
-+
-+ ccw = poly_is_ccw (poly);
-+
-+ /* Holes or inside contours need to be listed out in reverse
-+ * clockwise direction to the main outwards contour, but OO.o
-+ * does not seem to handle holes at all. So we'll just list all
-+ * the contours as non-holes, e.g. in normal counterclockwise
-+ * order.
-+ */
-+
-+ if (ccw)
-+ k = 0;
-+ else
-+ k = n - 1;
-+
-+ for (j = 0; j < n; j++) {
-+ const Point &point = poly[k];
-+ vpath[v].code = (j == 0) ? ART_MOVETO : ART_LINETO;
-+ vpath[v].x = point.X ();
-+ vpath[v].y = point.Y ();
-+
-+ if (ccw)
-+ k++;
-+ else
-+ k--;
-+
-+ v++;
-+ }
-+
-+ /* Close the path if needed */
-+ if (n > 0 &&
-+ (vpath[v - 1].x != vpath[v - n].x ||
-+ vpath[v - 1].y != vpath[v - n].y)) {
-+ vpath[v].code = ART_LINETO;
-+ vpath[v].x = vpath[v - n].x;
-+ vpath[v].y = vpath[v - n].y;
-+ v++;
-+ }
-+ }
-+
-+ vpath[v].code = ART_END;
-+
-+ return vpath;
-+}
-+
-+void
-+PolyPolygon::ImplSetFromArtVpath (void *_vpath)
-+{
-+ ArtVpath *vpath;
-+
-+ vpath = (ArtVpath *) _vpath;
-+
-+ Clear ();
-+
-+ while (vpath->code != ART_END) {
-+ ArtVpath *p;
-+ int n, n_vertices;
-+
-+ n = 0;
-+ for (p = vpath; n == 0 || p->code == ART_LINETO; p++)
-+ n++;
-+
-+ /* Remove the last duplicated point from closed subpaths */
-+ if (n > 0 &&
-+ vpath[n - 1].x == vpath[0].x &&
-+ vpath[n - 1].y == vpath[0].y)
-+ n_vertices = n - 1;
-+ else
-+ n_vertices = n;
-+
-+ if (n_vertices != 0) {
-+ int i;
-+
-+ Polygon poly (n_vertices);
-+
-+ p = vpath;
-+ for (i = 0; i < n_vertices; i++) {
-+ Point &point = poly[i];
-+
-+ point.X () = FRound (p->x);
-+ point.Y () = FRound (p->y);
-+
-+ p++;
-+ }
-+
-+ Insert (poly);
-+ }
-+
-+ vpath += n;
-+ }
-+}
-+
-
- // -----------------------------------------------------------------------
-