1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
|
/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* $URL$
* $Id$
*
*/
/*
* This code is based on Libart_LGPL - library of basic graphic primitives
*
* Copyright (c) 1998 Raph Levien
*
* Licensed under GNU LGPL v2
*
*/
/* Various utility functions RLL finds useful. */
#include "art.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_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++)
free(svp->segs[i].points);
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 = (const ArtSVPSeg *)s1;
const ArtSVPSeg *seg2 = (const ArtSVPSeg *)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;
}
/**
* 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;
}
|