Skip to content
GitLab
Explore
Sign in
Register
Primary navigation
Search or go to…
Project
pike
Manage
Activity
Members
Labels
Plan
Issues
Issue boards
Milestones
Wiki
Code
Merge requests
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Snippets
Build
Pipelines
Jobs
Pipeline schedules
Artifacts
Deploy
Releases
Container registry
Model registry
Operate
Environments
Monitor
Incidents
Analyze
Value stream analytics
Contributor analytics
CI/CD analytics
Repository analytics
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
GitLab community forum
Contribute to GitLab
Provide feedback
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
pikelang
pike
Commits
f9f602bc
Commit
f9f602bc
authored
28 years ago
by
Mirar (Pontus Hagland)
Browse files
Options
Downloads
Patches
Plain Diff
polyfill
Rev: src/modules/Image/polyfill.c:1.1
parent
068c0609
No related branches found
No related tags found
No related merge requests found
Changes
1
Show whitespace changes
Inline
Side-by-side
Showing
1 changed file
src/modules/Image/polyfill.c
+667
-0
667 additions, 0 deletions
src/modules/Image/polyfill.c
with
667 additions
and
0 deletions
src/modules/Image/polyfill.c
0 → 100644
+
667
−
0
View file @
f9f602bc
#include
"global.h"
#include
<unistd.h>
#include
<math.h>
#include
"config.h"
#include
"stralloc.h"
#include
"types.h"
#include
"pike_macros.h"
#include
"object.h"
#include
"constants.h"
#include
"interpret.h"
#include
"svalue.h"
#include
"array.h"
#include
"threads.h"
#include
"builtin_functions.h"
#include
"image.h"
#define THIS ((struct image *)(fp->current_storage))
#define THISOBJ (fp->current_object)
#undef POLYDEBUG
/*
**! module Image
**! class image
*/
/*
**! method object polygone(array(int|float) ... curve)
**! fills an area with the current color
**!
**! returns the current object
**! arg array(int|float) curve
**! curve(s), <tt>({x1,y1,x2,y2,...,xn,yn})</tt>,
**! automatically closed.
**!
**! If any given curve is inside another, it
**! will make a hole.
**!
**! NOTE
**! This function is new (april-97) and rather untested.
**! see also: box, setcolor
*/
struct
vertex_list
{
struct
vertex
*
above
,
*
below
;
float
dx
,
dy
;
struct
vertex_list
*
next
;
float
xmin
,
xmax
,
yxmin
,
yxmax
;
/* temporary storage */
};
struct
vertex
{
float
x
,
y
;
struct
vertex
*
next
;
/* total list, sorted downwards */
struct
vertex_list
*
below
,
*
above
;
/* childs */
int
done
;
};
#define VY(V,X) ((V)->above->y+(V)->dy*((X)-(V)->above->x))
struct
vertex
*
vertex_new
(
float
x
,
float
y
,
struct
vertex
**
top
)
{
struct
vertex
*
c
;
while
(
*
top
&&
(
*
top
)
->
y
<
y
)
top
=&
((
*
top
)
->
next
);
if
(
*
top
&&
(
*
top
)
->
x
==
x
&&
(
*
top
)
->
y
==
y
)
return
*
top
;
/* found one */
c
=
malloc
(
sizeof
(
struct
vertex
));
c
->
x
=
x
;
c
->
y
=
y
;
c
->
next
=*
top
;
c
->
above
=
c
->
below
=
NULL
;
c
->
done
=
0
;
*
top
=
c
;
return
c
;
}
static
void
vertex_connect
(
struct
vertex
*
above
,
struct
vertex
*
below
)
{
struct
vertex_list
*
c
,
*
d
;
if
(
below
==
above
)
return
;
c
=
malloc
(
sizeof
(
struct
vertex_list
));
c
->
above
=
above
;
c
->
below
=
below
;
c
->
next
=
above
->
below
;
if
(
below
->
y
!=
above
->
y
)
c
->
dx
=
(
below
->
x
-
above
->
x
)
/
(
below
->
y
-
above
->
y
);
else
c
->
dx
=
1e10
;
if
(
below
->
x
!=
above
->
x
)
c
->
dy
=
(
below
->
y
-
above
->
y
)
/
(
below
->
x
-
above
->
x
);
else
c
->
dy
=
1e10
;
above
->
below
=
c
;
d
=
malloc
(
sizeof
(
struct
vertex_list
));
d
->
above
=
above
;
d
->
below
=
below
;
d
->
next
=
below
->
above
;
d
->
dx
=
c
->
dx
;
d
->
dy
=
c
->
dy
;
below
->
above
=
d
;
}
static
INLINE
float
vertex_xmax
(
struct
vertex_list
*
v
,
float
yp
,
float
*
ydest
)
{
if
(
v
->
dx
>
0
.
0
)
if
(
v
->
below
->
y
>
yp
+
1
.
0
)
return
v
->
above
->
x
+
v
->
dx
*
((
*
ydest
=
(
yp
+
1
.
0
))
-
v
->
above
->
y
);
else
return
(
*
ydest
=
v
->
below
->
y
),
v
->
below
->
x
;
else
if
(
v
->
dx
<
0
.
0
)
if
(
v
->
above
->
y
<
yp
)
return
v
->
above
->
x
+
v
->
dx
*
((
*
ydest
=
yp
)
-
v
->
above
->
y
);
else
return
(
*
ydest
=
v
->
above
->
y
),
v
->
above
->
x
;
else
if
(
v
->
below
->
y
>
yp
+
1
.
0
)
return
(
*
ydest
=
yp
+
1
.
0
),
v
->
above
->
x
;
else
return
(
*
ydest
=
v
->
below
->
y
),
v
->
below
->
x
;
}
static
INLINE
float
vertex_xmin
(
struct
vertex_list
*
v
,
float
yp
,
float
*
ydest
)
{
if
(
v
->
dx
<
0
.
0
)
if
(
v
->
below
->
y
>
yp
+
1
.
0
)
return
v
->
above
->
x
+
v
->
dx
*
((
*
ydest
=
(
yp
+
1
.
0
))
-
v
->
above
->
y
);
else
return
(
*
ydest
=
v
->
below
->
y
),
v
->
below
->
x
;
else
if
(
v
->
dx
>
0
.
0
)
if
(
v
->
above
->
y
<
yp
)
return
v
->
above
->
x
+
v
->
dx
*
((
*
ydest
=
yp
)
-
v
->
above
->
y
);
else
return
(
*
ydest
=
v
->
above
->
y
),
v
->
above
->
x
;
else
if
(
v
->
above
->
y
<
yp
)
return
(
*
ydest
=
yp
),
v
->
above
->
x
;
else
return
(
*
ydest
=
v
->
above
->
y
),
v
->
above
->
x
;
}
static
void
add_vertices
(
struct
vertex_list
**
first
,
struct
vertex_list
*
what
,
float
yp
)
{
struct
vertex_list
**
ins
,
*
c
;
while
(
what
)
{
float
xi
,
yi
;
float
xw
=
what
->
above
->
x
;
float
yw
=
what
->
above
->
y
;
ins
=
first
;
#ifdef POLYDEBUG
fprintf
(
stderr
,
"insert %g,%g - %g,%g %g xw==%g
\n
"
,
what
->
above
->
x
,
what
->
above
->
y
,
what
->
below
->
x
,
what
->
below
->
y
,
what
->
dx
,
xw
);
#endif
while
(
*
ins
)
{
if
((
*
ins
)
->
dy
==
0
||
what
->
dy
==
0
)
xi
=
xw
;
else
xi
=
(
*
ins
)
->
above
->
x
+
(
*
ins
)
->
dx
*
(
yw
-
(
*
ins
)
->
above
->
y
);
yi
=
yw
;
if
(
xw
<
xi
&&
what
->
dx
<
0
)
break
;
if
(
xw
>
xi
&&
what
->
dx
>
0
)
break
;
if
(
xw
==
xi
&&
/* ((*ins)->below->x>xw || (*ins)->above->x>xw) &&*/
(
*
ins
)
->
dx
>
what
->
dx
)
break
;
#ifdef POLYDEBUG
fprintf
(
stderr
,
" after %g,%g - %g,%g %g i=%g,%g w=%g,%g
\n
"
,
(
*
ins
)
->
above
->
x
,(
*
ins
)
->
above
->
y
,
(
*
ins
)
->
below
->
x
,(
*
ins
)
->
below
->
y
,(
*
ins
)
->
dx
,
xi
,
yi
,
xw
,
yw
);
#endif
ins
=&
((
*
ins
)
->
next
);
}
#ifdef POLYDEBUG
if
(
*
ins
)
fprintf
(
stderr
,
" before %g,%g - %g,%g %g i=%g,%g w=%g,%g
\n
"
,
(
*
ins
)
->
above
->
x
,(
*
ins
)
->
above
->
y
,
(
*
ins
)
->
below
->
x
,(
*
ins
)
->
below
->
y
,(
*
ins
)
->
dy
,
xi
,
yi
,
xw
,
yw
);
#endif
c
=
malloc
(
sizeof
(
struct
vertex_list
));
*
c
=*
what
;
c
->
next
=*
ins
;
*
ins
=
c
;
what
=
what
->
next
;
}
}
static
void
sub_vertices
(
struct
vertex_list
**
first
,
struct
vertex
*
below
,
float
yp
)
{
struct
vertex_list
**
ins
,
*
c
;
ins
=
first
;
while
(
*
ins
)
if
((
*
ins
)
->
below
==
below
)
{
c
=*
ins
;
*
ins
=
(
*
ins
)
->
next
;
free
(
c
);
}
else
ins
=&
((
*
ins
)
->
next
);
}
static
void
polygone_row_fill
(
float
*
buf
,
float
xmin
,
float
xmax
)
{
int
i
;
int
max
;
if
(
floor
(
xmin
)
==
floor
(
xmax
))
buf
[(
int
)
floor
(
xmin
)]
+=
xmax
-
xmin
;
else
{
buf
[(
int
)
floor
(
xmin
)]
+=
1
-
(
xmin
-
floor
(
xmin
));
max
=
floor
(
xmax
);
for
(
i
=
(
int
)
floor
(
xmin
)
+
1
;
i
<
max
;
i
++
)
buf
[
i
]
=
1
.
0
;
buf
[(
int
)
floor
(
xmax
)]
+=
xmax
-
floor
(
xmax
);
}
}
static
int
polygone_row_vertices
(
float
*
buf
,
struct
vertex_list
*
v1
,
struct
vertex_list
*
v2
,
float
xmin
,
float
xmax
,
float
yp
,
int
fill
)
{
struct
vertex_list
*
v
;
int
xofill
=
1
;
float
x
;
#ifdef POLYDEBUG
int
i
;
fprintf
(
stderr
,
"aa %g..%g fill %d
\n
"
,
xmin
,
xmax
,
fill
);
#endif
fill
=
fill
?-
1
:
1
;
v
=
v1
;
while
(
v
)
{
if
(
v
->
xmin
==
xmin
&&
v
->
yxmin
==
yp
)
{
fill
=-
fill
;
#ifdef POLYDEBUG
fprintf
(
stderr
,
"aa toggle fill: %d
\n
"
,
fill
);
#endif
}
v
=
v
->
next
;
}
if
(
fill
<
0
)
polygone_row_fill
(
buf
,
xmin
,
xmax
);
v
=
v1
;
while
(
v
!=
v2
)
{
#ifdef POLYDEBUG
fprintf
(
stderr
,
"aa << %g,%g-%g,%g %g,%g-%g,%g fill=%d xofill=%d
\n
"
,
v
->
above
->
x
,
v
->
above
->
y
,
v
->
below
->
x
,
v
->
below
->
y
,
v
->
xmin
,
v
->
yxmin
,
v
->
xmax
,
v
->
yxmax
,
fill
,
xofill
);
#endif
if
(
xmin
!=
xmax
&&
v
->
xmin
<
xmax
&&
v
->
xmax
>
xmin
)
{
#define CALC_AREA(FILL,X,Y1,Y2,YP) \
((FILL)*(X)*( 1-0.5*((Y1)+(Y2))+(YP) ))
/* (fprintf(stderr,"area: %d*%g*%g y1=%g y2=%g yp=%g == %g\n", FILL,X,( 1-0.5*(Y1+Y2)+YP ),Y1,Y2,YP,((FILL)*(X)*( 1-0.5*((Y1)+(Y2))+(YP) ))), \*/
if
(
floor
(
xmin
)
==
floor
(
xmax
))
buf
[(
int
)
floor
(
xmin
)]
+=
CALC_AREA
(
fill
*
xofill
,(
xmax
-
xmin
),
VY
(
v
,
xmin
),
VY
(
v
,
xmax
),
yp
);
else
{
buf
[(
int
)
floor
(
xmin
)]
+=
CALC_AREA
(
xofill
*
fill
,
(
1
+
floor
(
xmin
)
-
xmin
),
VY
(
v
,
xmin
),
VY
(
v
,
1
+
floor
(
xmin
)),
yp
);
for
(
x
=
1
+
floor
(
xmin
);
x
<
floor
(
xmax
);
x
+=
1
.
0
)
buf
[(
int
)
x
]
+=
CALC_AREA
(
fill
*
xofill
,
1
.
0
,
VY
(
v
,
x
),
VY
(
v
,
x
+
1
.
0
),
yp
);
buf
[(
int
)
floor
(
xmax
)]
+=
CALC_AREA
(
fill
*
xofill
,
xmax
-
floor
(
xmax
),
VY
(
v
,
xmax
),
VY
(
v
,
floor
(
xmax
)),
yp
);
}
#ifdef POLYDEBUG
fprintf
(
stderr
,
"aa "
);
for
(
i
=
0
;
i
<
10
;
i
++
)
fprintf
(
stderr
,
"%5.3f,"
,
buf
[
i
]);
fprintf
(
stderr
,
"
\n
"
);
#endif
}
if
(
v
->
xmin
<=
xmin
&&
v
->
xmax
>=
xmax
)
xofill
=-
xofill
;
v
=
v
->
next
;
}
#ifdef POLYDEBUG
if
(
fill
<
0
)
fprintf
(
stderr
,
"aa fill is on
\n
"
);
#endif
return
fill
<
0
;
}
static
void
polygone_row
(
struct
image
*
img
,
float
*
buf
,
struct
vertex_list
*
vertices
,
float
yp
,
int
*
pixmin
,
int
*
pixmax
)
{
struct
vertex_list
*
v
,
*
v1
;
float
xmax
,
xmin
,
nxmax
;
int
fill
=
0
,
i
;
int
ixmin
,
ixmax
;
xmin
=
1e10
;
xmax
=-
1e10
;
v
=
vertices
;
while
(
v
)
{
v
->
xmin
=
vertex_xmin
(
v
,
yp
,
&
v
->
yxmin
);
v
->
xmax
=
vertex_xmax
(
v
,
yp
,
&
v
->
yxmax
);
if
(
v
->
xmin
<
xmin
)
xmin
=
v
->
xmin
;
if
(
v
->
xmax
>
xmax
)
xmax
=
v
->
xmax
;
v
=
v
->
next
;
}
*
pixmin
=
ixmin
=
floor
(
xmin
);
*
pixmax
=
ixmax
=
ceil
(
xmax
);
if
(
ixmin
<
0
)
{
*
pixmin
=
ixmin
=
xmin
=
0
;
v
=
vertices
;
while
(
v
)
{
if
(
v
->
xmin
<
0
&&
v
->
yxmin
==
yp
)
fill
=!
fill
;
if
(
v
->
xmax
<
0
&&
v
->
yxmax
==
yp
)
fill
=!
fill
;
v
=
v
->
next
;
}
}
else
if
(
ixmin
>=
img
->
xsize
)
{
*
pixmax
=
ixmin
;
return
;
}
if
(
ixmax
>=
img
->
xsize
)
*
pixmax
=
ixmax
=
img
->
xsize
;
else
if
(
ixmax
<
0
)
{
*
pixmax
=
ixmin
;
return
;
}
for
(
i
=
ixmin
;
i
<
ixmax
;
i
++
)
buf
[
i
]
=
0
.
0
;
v
=
vertices
;
nxmax
=
xmax
=
v
->
xmax
;
v1
=
v
;
v1
=
v
=
vertices
;
#ifdef POLYDEBUG
while
(
v
)
fprintf
(
stderr
,
" >> %g,%g-%g,%g %g,%g-%g,%g
\n
"
,
v
->
above
->
x
,
v
->
above
->
y
,
v
->
below
->
x
,
v
->
below
->
y
,
v
->
xmin
,
v
->
yxmin
,
v
->
xmax
,
v
->
yxmax
),
v
=
v
->
next
;
v
=
vertices
;
#endif
for
(;;)
{
#ifdef POLYDEBUG
fprintf
(
stderr
,
">>>again...xmin=%g xmax=%g nxmax=%g
\n
"
,
xmin
,
xmax
,
nxmax
);
#endif
/* skip uninteresting, ends < v->xmin */
while
(
v1
&&
v1
->
xmax
<
xmin
)
v1
=
v1
->
next
;
if
(
!
v1
)
break
;
/* get next start or end */
v
=
v1
;
nxmax
=
0
;
xmax
=
1e10
;
/* known: v->xmin>=xmin */
while
(
v
)
{
#ifdef POLYDEBUG
fprintf
(
stderr
,
" ++ %g,%g-%g,%g %g,%g-%g,%g xmin=%g xmax=%g nxmax=%g -> "
,
v
->
above
->
x
,
v
->
above
->
y
,
v
->
below
->
x
,
v
->
below
->
y
,
v
->
xmin
,
v
->
yxmin
,
v
->
xmax
,
v
->
yxmax
,
xmin
,
xmax
,
nxmax
);
#endif
if
(
v
->
xmin
>
xmin
&&
v
->
xmin
<
xmax
)
xmax
=
v
->
xmin
;
if
(
v
->
xmax
>
xmin
&&
v
->
xmax
<
xmax
)
xmax
=
v
->
xmax
;
if
(
v
->
xmax
>
nxmax
)
nxmax
=
v
->
xmax
;
#ifdef POLYDEBUG
fprintf
(
stderr
,
"xmin=%g xmax=%g nxmax=%g
\n
"
,
xmin
,
xmax
,
nxmax
);
#endif
v
=
v
->
next
;
}
if
(
xmax
>
nxmax
)
xmax
=
nxmax
;
if
(
xmin
>
xmax
)
xmax
=
xmin
;
if
(
xmax
>
ixmax
)
xmax
=
ixmax
;
if
(
xmin
==
nxmax
)
break
;
fill
=
polygone_row_vertices
(
buf
,
v1
,
v
,
xmin
,
xmax
,
yp
,
fill
);
if
((
xmin
=
xmax
)
>=
ixmax
)
break
;
while
(
v1
&&
v1
->
xmax
<
xmin
)
v1
=
v1
->
next
;
if
(
!
v1
)
break
;
v
=
vertices
;
while
(
v
)
{
if
(
v
->
xmax
==
xmax
&&
v
->
yxmax
==
yp
)
fill
=!
fill
;
v
=
v
->
next
;
}
if
(
v
&&
xmax
==
nxmax
&&
v
->
xmin
>
nxmax
)
/* jump */
{
xmin
=
v
->
xmin
;
if
(
nxmax
>=
ixmax
)
break
;
if
(
fill
)
if
(
v
->
xmin
>
ixmax
)
polygone_row_fill
(
buf
,
nxmax
,
ixmax
);
else
polygone_row_fill
(
buf
,
nxmax
,
v
->
xmin
);
}
}
}
static
void
polygone_some
(
struct
image
*
img
,
struct
vertex
*
top
)
{
struct
vertex
*
tn
;
struct
vertex_list
*
vertices
,
*
v
,
*
vn
,
*
v1
;
struct
vertex
*
next
,
*
nextb
;
float
yp
;
int
i
;
rgb_group
*
dest
=
img
->
img
,
rgb
=
img
->
rgb
;
float
*
buf
=
alloca
(
sizeof
(
float
)
*
img
->
xsize
*
2
);
if
(
!
buf
)
error
(
"out of stack, typ
\n
"
);
for
(
i
=
0
;
i
<
img
->
xsize
;
i
++
)
buf
[
i
]
=
0
.
0
;
nextb
=
next
=
top
;
yp
=
floor
(
top
->
y
);
vertices
=
NULL
;
if
(
yp
>
0
)
dest
+=
((
int
)
yp
)
*
img
->
xsize
;
while
(
next
)
{
#ifdef POLYDEBUG
fprintf
(
stderr
,
"
\n\n
row y=%g..%g
\n
"
,
yp
,
yp
+
1
);
#endif
/* add new vertices if any */
while
(
next
&&
next
->
y
<=
yp
+
1
.
0
)
{
add_vertices
(
&
vertices
,
next
->
below
,
yp
);
next
=
next
->
next
;
}
/* POLYDEBUG */
#ifdef POLYDEBUG
fprintf
(
stderr
,
"vertices:
\n
"
);
v1
=
vertices
;
while
(
v1
)
{
fprintf
(
stderr
,
" (%g,%g)-(%g,%g) at "
,
v1
->
above
->
x
,
v1
->
above
->
y
,
v1
->
below
->
x
,
v1
->
below
->
y
);
if
(
v1
->
above
->
y
>
yp
)
fprintf
(
stderr
,
"(%g,%g), "
,
v1
->
above
->
x
,
v1
->
above
->
y
);
else
fprintf
(
stderr
,
"(%g,%g), "
,
v1
->
above
->
x
+
v1
->
dx
*
(
yp
-
v1
->
above
->
y
),
yp
);
if
(
v1
->
below
->
y
<
yp
+
1
.
0
)
fprintf
(
stderr
,
"(%g,%g)
\n
"
,
v1
->
below
->
x
,
v1
->
below
->
y
);
else
fprintf
(
stderr
,
"(%g,%g)
\n
"
,
v1
->
above
->
x
+
v1
->
dx
*
(
1
+
yp
-
v1
->
above
->
y
),
(
yp
+
1
.
0
));
v1
=
v1
->
next
;
}
#endif
/* find out what to antialias, and what to fill, and if to resort stuff */
if
(
yp
>=
0
&&
yp
<
img
->
ysize
)
{
int
xmin
,
xmax
;
polygone_row
(
img
,
buf
,
vertices
,
yp
,
&
xmin
,
&
xmax
);
#if POLYDEBUG
fprintf
(
stderr
,
"yp=%g dest=&%lx (&%lx..&%lx) xmin=%d xmax=%d; "
,
yp
,(
int
)
dest
,(
int
)
img
->
img
,
(
int
)
img
->
img
+
img
->
xsize
*
img
->
ysize
,
xmin
,
xmax
);
for
(
i
=
xmin
;
i
<
xmax
;
i
++
)
fprintf
(
stderr
,
"%5.3f,"
,
buf
[
i
]);
fprintf
(
stderr
,
"
\n
"
);
#endif
for
(;
xmin
<
xmax
;
xmin
++
)
dest
[
xmin
].
r
=
(
unsigned
char
)(
dest
[
xmin
].
r
*
(
1
.
0
-
buf
[
xmin
])
+
rgb
.
r
*
buf
[
xmin
]),
dest
[
xmin
].
g
=
(
unsigned
char
)(
dest
[
xmin
].
g
*
(
1
.
0
-
buf
[
xmin
])
+
rgb
.
g
*
buf
[
xmin
]),
dest
[
xmin
].
b
=
(
unsigned
char
)(
dest
[
xmin
].
b
*
(
1
.
0
-
buf
[
xmin
])
+
rgb
.
b
*
buf
[
xmin
]);
dest
+=
img
->
xsize
;
}
/* remove done vertices if any */
yp
+=
1
.
0
;
while
(
nextb
&&
nextb
->
y
<=
yp
)
{
sub_vertices
(
&
vertices
,
nextb
,
yp
);
nextb
=
nextb
->
next
;
}
}
}
static
INLINE
void
polygone_free
(
struct
vertex
*
top
)
{
struct
vertex_list
*
v
,
*
vn
;
struct
vertex
*
tn
;
while
(
top
)
{
v
=
top
->
above
;
while
(
v
)
{
vn
=
v
->
next
;
free
(
v
);
v
=
vn
;
}
v
=
top
->
below
;
while
(
v
)
{
vn
=
v
->
next
;
free
(
v
);
v
=
vn
;
}
tn
=
top
->
next
;
free
(
top
);
top
=
tn
;
}
}
static
INLINE
struct
vertex
*
polygone_begin
()
{
return
NULL
;
}
static
INLINE
struct
vertex
*
polygone_add
(
struct
vertex
*
top
,
struct
array
*
a
,
int
arg
,
char
*
what
)
{
struct
vertex
*
first
,
*
last
,
*
cur
;
int
n
;
for
(
n
=
0
;
n
<
a
->
size
;
n
++
)
if
(
a
->
item
[
n
].
type
!=
T_FLOAT
&&
a
->
item
[
n
].
type
!=
T_INT
)
{
polygone_free
(
top
);
error
(
"Illegal argument %d to %s, array index %d is not int nor float
\n
"
,
arg
,
what
,
n
);
return
NULL
;
}
if
(
a
->
size
<
6
)
return
;
/* no polygon with less then tree corners */
#define POINT(A,N) (((A)->item[N].type==T_FLOAT)?((A)->item[N].u.float_number):((float)((A)->item[N].u.integer)))
last
=
first
=
vertex_new
(
POINT
(
a
,
0
),
POINT
(
a
,
1
),
&
top
);
for
(
n
=
2
;
n
+
1
<
a
->
size
;
n
+=
2
)
{
cur
=
vertex_new
(
POINT
(
a
,
n
),
POINT
(
a
,
n
+
1
),
&
top
);
if
(
cur
->
y
<
last
->
y
)
vertex_connect
(
cur
,
last
);
else
if
(
cur
->
y
>
last
->
y
)
vertex_connect
(
last
,
cur
);
else
if
(
cur
->
x
<
last
->
x
)
vertex_connect
(
cur
,
last
);
else
vertex_connect
(
last
,
cur
);
last
=
cur
;
}
if
(
cur
->
y
<
first
->
y
)
vertex_connect
(
cur
,
first
);
else
if
(
cur
->
y
>
first
->
y
)
vertex_connect
(
first
,
cur
);
else
if
(
cur
->
x
<
first
->
x
)
vertex_connect
(
cur
,
first
);
else
vertex_connect
(
first
,
cur
);
return
top
;
}
void
image_polygone
(
INT32
args
)
{
struct
vertex
*
v
;
int
n
;
if
(
!
THIS
->
img
)
error
(
"No image when calling image::polygone()
\n
"
);
v
=
polygone_begin
();
n
=
args
;
while
(
args
)
{
if
(
sp
[
-
1
].
type
!=
T_ARRAY
)
{
polygone_free
(
v
);
error
(
"Illegal argument %d to image::polygone(), expected array
\n
"
,
n
);
}
v
=
polygone_add
(
v
,
sp
[
-
1
].
u
.
array
,
n
,
"image::polygone()"
);
n
++
;
args
--
;
pop_stack
();
}
if
(
!
v
)
return
;
/* no vertices */
polygone_some
(
THIS
,
v
);
polygone_free
(
v
);
THISOBJ
->
refs
++
;
push_object
(
THISOBJ
);
}
This diff is collapsed.
Click to expand it.
Preview
0%
Loading
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment