~ml-launchpad/ubuntu/natty/gcompris/fix-for-777349

« back to all changes in this revision

Viewing changes to src/libart_lgpl/art_svp.c

  • Committer: Bazaar Package Importer
  • Author(s): Marc Gariepy, Marc Gariepy, Stephane Graber
  • Date: 2010-01-04 17:42:49 UTC
  • mfrom: (1.1.14 upstream)
  • Revision ID: james.westby@ubuntu.com-20100104174249-7bupatd9dtxyhvs4
Tags: 9.0-0ubuntu1
[Marc Gariepy]
* New upstream release (9.0).
* Remove cache.c from POTFILES to avoid FTBFS
* Remove unneeded rm in debian/rules (file no longer exists upstream)

[Stephane Graber]
* Bump Debian standards to 3.8.3
* Add patch system (dpatch)

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/* Libart_LGPL - library of basic graphic primitives
2
 
 * Copyright (C) 1998 Raph Levien
3
 
 *
4
 
 * This library is free software; you can redistribute it and/or
5
 
 * modify it under the terms of the GNU Library General Public
6
 
 * License as published by the Free Software Foundation; either
7
 
 * version 3 of the License, or (at your option) any later version.
8
 
 *
9
 
 * This library is distributed in the hope that it will be useful,
10
 
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11
 
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12
 
 * Library General Public License for more details.
13
 
 *
14
 
 * You should have received a copy of the GNU Library General Public
15
 
 * License along with this library; if not, see <http://www.gnu.org/licenses/>.
16
 
 * Boston, MA 02111-1307, USA.
17
 
 */
18
 
 
19
 
/* Basic constructors and operations for sorted vector paths */
20
 
 
21
 
#include "config.h"
22
 
#include "art_svp.h"
23
 
 
24
 
#include "art_misc.h"
25
 
 
26
 
/* Add a new segment. The arguments can be zero and NULL if the caller
27
 
   would rather fill them in later.
28
 
 
29
 
   We also realloc one auxiliary array of ints of size n_segs if
30
 
   desired.
31
 
*/
32
 
/**
33
 
 * art_svp_add_segment: Add a segment to an #ArtSVP structure.
34
 
 * @p_vp: Pointer to where the #ArtSVP structure is stored.
35
 
 * @pn_segs_max: Pointer to the allocated size of *@p_vp.
36
 
 * @pn_points_max: Pointer to where auxiliary array is stored.
37
 
 * @n_points: Number of points for new segment.
38
 
 * @dir: Direction for new segment; 0 is up, 1 is down.
39
 
 * @points: Points for new segment.
40
 
 * @bbox: Bounding box for new segment.
41
 
 *
42
 
 * Adds a new segment to an ArtSVP structure. This routine reallocates
43
 
 * the structure if necessary, updating *@p_vp and *@pn_segs_max as
44
 
 * necessary.
45
 
 *
46
 
 * The new segment is simply added after all other segments. Thus,
47
 
 * this routine should be called in order consistent with the #ArtSVP
48
 
 * sorting rules.
49
 
 *
50
 
 * If the @bbox argument is given, it is simply stored in the new
51
 
 * segment. Otherwise (if it is NULL), the bounding box is computed
52
 
 * from the @points given.
53
 
 **/
54
 
int
55
 
art_svp_add_segment (ArtSVP **p_vp, int *pn_segs_max,
56
 
                     int **pn_points_max,
57
 
                     int n_points, int dir, ArtPoint *points,
58
 
                     ArtDRect *bbox)
59
 
{
60
 
  int seg_num;
61
 
  ArtSVP *svp;
62
 
  ArtSVPSeg *seg;
63
 
 
64
 
  svp = *p_vp;
65
 
  seg_num = svp->n_segs++;
66
 
  if (*pn_segs_max == seg_num)
67
 
    {
68
 
      *pn_segs_max <<= 1;
69
 
      svp = (ArtSVP *)art_realloc (svp, sizeof(ArtSVP) +
70
 
                                   (*pn_segs_max - 1) * sizeof(ArtSVPSeg));
71
 
      *p_vp = svp;
72
 
      if (pn_points_max != NULL)
73
 
        *pn_points_max = art_renew (*pn_points_max, int, *pn_segs_max);
74
 
    }
75
 
  seg = &svp->segs[seg_num];
76
 
  seg->n_points = n_points;
77
 
  seg->dir = dir;
78
 
  seg->points = points;
79
 
  if (bbox)
80
 
    seg->bbox = *bbox;
81
 
  else if (points)
82
 
    {
83
 
      double x_min, x_max;
84
 
      int i;
85
 
 
86
 
      x_min = x_max = points[0].x;
87
 
      for (i = 1; i < n_points; i++)
88
 
        {
89
 
          if (x_min > points[i].x)
90
 
            x_min = points[i].x;
91
 
          if (x_max < points[i].x)
92
 
            x_max = points[i].x;
93
 
        }
94
 
      seg->bbox.x0 = x_min;
95
 
      seg->bbox.y0 = points[0].y;
96
 
 
97
 
      seg->bbox.x1 = x_max;
98
 
      seg->bbox.y1 = points[n_points - 1].y;
99
 
    }
100
 
  return seg_num;
101
 
}
102
 
 
103
 
 
104
 
/**
105
 
 * art_svp_free: Free an #ArtSVP structure.
106
 
 * @svp: #ArtSVP to free.
107
 
 *
108
 
 * Frees an #ArtSVP structure and all the segments in it.
109
 
 **/
110
 
void
111
 
art_svp_free (ArtSVP *svp)
112
 
{
113
 
  int n_segs = svp->n_segs;
114
 
  int i;
115
 
 
116
 
  for (i = 0; i < n_segs; i++)
117
 
    art_free (svp->segs[i].points);
118
 
  art_free (svp);
119
 
}
120
 
 
121
 
#ifdef ART_USE_NEW_INTERSECTOR
122
 
#define EPSILON 0
123
 
#else
124
 
#define EPSILON 1e-6
125
 
#endif
126
 
 
127
 
/**
128
 
 * art_svp_seg_compare: Compare two segments of an svp.
129
 
 * @seg1: First segment to compare.
130
 
 * @seg2: Second segment to compare.
131
 
 *
132
 
 * Compares two segments of an svp. Return 1 if @seg2 is below or to the
133
 
 * right of @seg1, -1 otherwise.
134
 
 **/
135
 
int
136
 
art_svp_seg_compare (const void *s1, const void *s2)
137
 
{
138
 
  const ArtSVPSeg *seg1 = s1;
139
 
  const ArtSVPSeg *seg2 = s2;
140
 
 
141
 
  if (seg1->points[0].y - EPSILON > seg2->points[0].y) return 1;
142
 
  else if (seg1->points[0].y + EPSILON < seg2->points[0].y) return -1;
143
 
  else if (seg1->points[0].x - EPSILON > seg2->points[0].x) return 1;
144
 
  else if (seg1->points[0].x + EPSILON < seg2->points[0].x) return -1;
145
 
  else if ((seg1->points[1].x - seg1->points[0].x) *
146
 
           (seg2->points[1].y - seg2->points[0].y) -
147
 
           (seg1->points[1].y - seg1->points[0].y) *
148
 
           (seg2->points[1].x - seg2->points[0].x) > 0) return 1;
149
 
  else return -1;
150
 
}
151