1544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin/**************************************************************************
2544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin *
3544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin * Copyright 2009 VMware, Inc.  All Rights Reserved.
4544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin *
5544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin * Permission is hereby granted, free of charge, to any person obtaining a
6544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin * copy of this software and associated documentation files (the
7544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin * "Software"), to deal in the Software without restriction, including
8544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin * without limitation the rights to use, copy, modify, merge, publish,
9544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin * distribute, sub license, and/or sell copies of the Software, and to
10544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin * permit persons to whom the Software is furnished to do so, subject to
11544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin * the following conditions:
12544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin *
13544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin * The above copyright notice and this permission notice (including the
14544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin * next paragraph) shall be included in all copies or substantial portions
15544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin * of the Software.
16544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin *
17544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
18544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
19544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
20544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR
21544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
22544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
23544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
24544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin *
25544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin **************************************************************************/
26544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin
27544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin#include "polygon.h"
28544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin
29544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin#include "matrix.h" /*for floatsEqual*/
30544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin#include "vg_context.h"
31544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin#include "vg_state.h"
32544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin#include "renderer.h"
33544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin#include "util_array.h"
34544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin#include "VG/openvg.h"
35544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin
36544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin#include "pipe/p_context.h"
37544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin#include "pipe/p_defines.h"
38544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin#include "pipe/p_state.h"
3928486880ca3ec39419ccee0cb1a3bedc9ef7117cJosé Fonseca#include "util/u_inlines.h"
40544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin#include "pipe/p_screen.h"
41544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin
42544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin#include "util/u_draw_quad.h"
43544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin#include "util/u_math.h"
44544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin
45544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin#include <string.h>
46544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin#include <stdlib.h>
47544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin
48544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin#define DEBUG_POLYGON 0
49544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin
50544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin#define COMPONENTS 2
51544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin
52544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusinstruct polygon
53544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin{
54544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   VGfloat *data;
55544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   VGint    size;
56544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin
57544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   VGint    num_verts;
58544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin
59544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   VGboolean dirty;
60fa20733a622770eaaa941f64d570d7b63d8f37b6Marek Olšák   void *user_vbuf;
61544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   struct pipe_screen *screen;
62544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin};
63544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin
64544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusinstatic float *ptr_to_vertex(float *data, int idx)
65544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin{
66544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   return data + (idx * COMPONENTS);
67544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin}
68544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin
69544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin#if 0
70544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusinstatic void polygon_print(struct polygon *poly)
71544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin{
72544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   int i;
73544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   float *vert;
74544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   debug_printf("Polygon %p, size = %d\n", poly, poly->num_verts);
75544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   for (i = 0; i < poly->num_verts; ++i) {
76544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin      vert = ptr_to_vertex(poly->data, i);
77544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin      debug_printf("%f, %f,  ", vert[0], vert[1]);
78544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   }
79544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   debug_printf("\nend\n");
80544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin}
81544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin#endif
82544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin
83544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin
84544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusinstruct polygon * polygon_create(int size)
85544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin{
86544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   struct polygon *poly = (struct polygon*)malloc(sizeof(struct polygon));
87544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin
88544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   poly->data = malloc(sizeof(float) * COMPONENTS * size);
89544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   poly->size = size;
90544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   poly->num_verts = 0;
91544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   poly->dirty = VG_TRUE;
92fa20733a622770eaaa941f64d570d7b63d8f37b6Marek Olšák   poly->user_vbuf = NULL;
93544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin
94544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   return poly;
95544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin}
96544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin
97544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusinstruct polygon * polygon_create_from_data(float *data, int size)
98544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin{
99544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   struct polygon *poly = polygon_create(size);
100544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin
101544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   memcpy(poly->data, data, sizeof(float) * COMPONENTS * size);
102544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   poly->num_verts = size;
103544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   poly->dirty = VG_TRUE;
104fa20733a622770eaaa941f64d570d7b63d8f37b6Marek Olšák   poly->user_vbuf = NULL;
105544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin
106544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   return poly;
107544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin}
108544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin
109544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusinvoid polygon_destroy(struct polygon *poly)
110544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin{
111544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   free(poly->data);
112544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   free(poly);
113544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin}
114544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin
115544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusinvoid polygon_resize(struct polygon *poly, int new_size)
116544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin{
117544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   float *data = (float*)malloc(sizeof(float) * COMPONENTS * new_size);
118544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   int size = MIN2(sizeof(float) * COMPONENTS * new_size,
119544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin                   sizeof(float) * COMPONENTS * poly->size);
120544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   memcpy(data, poly->data, size);
121544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   free(poly->data);
122544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   poly->data = data;
123544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   poly->size = new_size;
124544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   poly->dirty = VG_TRUE;
125544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin}
126544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin
127544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusinint polygon_size(struct polygon *poly)
128544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin{
129544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   return poly->size;
130544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin}
131544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin
132544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusinint polygon_vertex_count(struct polygon *poly)
133544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin{
134544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   return poly->num_verts;
135544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin}
136544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin
137544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusinfloat * polygon_data(struct polygon *poly)
138544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin{
139544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   return poly->data;
140544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin}
141544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin
142544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusinvoid polygon_vertex_append(struct polygon *p,
143544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin                           float x, float y)
144544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin{
145544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   float *vert;
146544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin#if DEBUG_POLYGON
147544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   debug_printf("Append vertex [%f, %f]\n", x, y);
148544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin#endif
149544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   if (p->num_verts >= p->size) {
150544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin      polygon_resize(p, p->size * 2);
151544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   }
152544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin
153544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   vert = ptr_to_vertex(p->data, p->num_verts);
154544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   vert[0] = x;
155544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   vert[1] = y;
156544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   ++p->num_verts;
157544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   p->dirty = VG_TRUE;
158544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin}
159544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin
160544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusinvoid polygon_set_vertex(struct polygon *p, int idx,
161544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin                        float x, float y)
162544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin{
163544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   float *vert;
164544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   if (idx >= p->num_verts) {
165544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin      /*fixme: error reporting*/
166544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin      abort();
167544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin      return;
168544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   }
169544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin
170544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   vert = ptr_to_vertex(p->data, idx);
171544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   vert[0] = x;
172544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   vert[1] = y;
173544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   p->dirty = VG_TRUE;
174544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin}
175544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin
176544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusinvoid polygon_vertex(struct polygon *p, int idx,
177544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin                    float *vertex)
178544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin{
179544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   float *vert;
180544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   if (idx >= p->num_verts) {
181544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin      /*fixme: error reporting*/
182544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin      abort();
183544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin      return;
184544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   }
185544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin
186544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   vert = ptr_to_vertex(p->data, idx);
187544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   vertex[0] = vert[0];
188544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   vertex[1] = vert[1];
189544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin}
190544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin
191544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusinvoid polygon_bounding_rect(struct polygon *p,
192544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin                           float *rect)
193544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin{
194544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   int i;
195544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   float minx, miny, maxx, maxy;
196544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   float *vert = ptr_to_vertex(p->data, 0);
197544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   minx = vert[0];
198544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   maxx = vert[0];
199544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   miny = vert[1];
200544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   maxy = vert[1];
201544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin
202544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   for (i = 1; i < p->num_verts; ++i) {
203544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin      vert = ptr_to_vertex(p->data, i);
204544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin      minx = MIN2(vert[0], minx);
205544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin      miny = MIN2(vert[1], miny);
206544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin
207544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin      maxx = MAX2(vert[0], maxx);
208544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin      maxy = MAX2(vert[1], maxy);
209544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   }
210544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin
211544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   rect[0] = minx;
212544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   rect[1] = miny;
213544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   rect[2] = maxx - minx;
214544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   rect[3] = maxy - miny;
215544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin}
216544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin
217544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusinint polygon_contains_point(struct polygon *p,
218544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin                           float x, float y)
219544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin{
220544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   return 0;
221544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin}
222544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin
223544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusinvoid polygon_append_polygon(struct polygon *dst,
224544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin                            struct polygon *src)
225544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin{
226544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   if (dst->num_verts + src->num_verts >= dst->size) {
227544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin      polygon_resize(dst, dst->num_verts + src->num_verts * 1.5);
228544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   }
229544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   memcpy(ptr_to_vertex(dst->data, dst->num_verts),
230544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin          src->data, src->num_verts * COMPONENTS * sizeof(VGfloat));
231544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   dst->num_verts += src->num_verts;
232544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin}
233544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin
234544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack RusinVGboolean polygon_is_closed(struct polygon *p)
235544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin{
236544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   VGfloat start[2], end[2];
237544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin
238544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   polygon_vertex(p, 0, start);
239544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   polygon_vertex(p, p->num_verts - 1, end);
240544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin
241544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   return floatsEqual(start[0], end[0]) && floatsEqual(start[1], end[1]);
242544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin}
243544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin
2443b71cb6ad6dabfefc9363a35872f4e70e1125603Chia-I Wustatic void polygon_prepare_buffer(struct vg_context *ctx,
2453b71cb6ad6dabfefc9363a35872f4e70e1125603Chia-I Wu                                   struct polygon *poly)
246544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin{
247544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   struct pipe_context *pipe;
248544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin
249544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   /*polygon_print(poly);*/
250544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin
251544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   pipe = ctx->pipe;
252544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin
253fa20733a622770eaaa941f64d570d7b63d8f37b6Marek Olšák   if (poly->user_vbuf == NULL || poly->dirty) {
254544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin      poly->screen = pipe->screen;
255fa20733a622770eaaa941f64d570d7b63d8f37b6Marek Olšák      poly->user_vbuf = poly->data;
256544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin      poly->dirty = VG_FALSE;
257544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   }
258544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin}
259544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin
260544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusinvoid polygon_fill(struct polygon *poly, struct vg_context *ctx)
261544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin{
2623b71cb6ad6dabfefc9363a35872f4e70e1125603Chia-I Wu   struct pipe_vertex_element velement;
2633b71cb6ad6dabfefc9363a35872f4e70e1125603Chia-I Wu   struct pipe_vertex_buffer vbuffer;
264544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   VGfloat bounds[4];
265544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   VGfloat min_x, min_y, max_x, max_y;
2663b71cb6ad6dabfefc9363a35872f4e70e1125603Chia-I Wu
267544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   assert(poly);
268544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   polygon_bounding_rect(poly, bounds);
269544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   min_x = bounds[0];
270544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   min_y = bounds[1];
271544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   max_x = bounds[0] + bounds[2];
272544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   max_y = bounds[1] + bounds[3];
273544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin
274544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin#if DEBUG_POLYGON
275544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   debug_printf("Poly bounds are [%f, %f], [%f, %f]\n",
276544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin                min_x, min_y, max_x, max_y);
277544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin#endif
278544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin
2793b71cb6ad6dabfefc9363a35872f4e70e1125603Chia-I Wu   polygon_prepare_buffer(ctx, poly);
2803b71cb6ad6dabfefc9363a35872f4e70e1125603Chia-I Wu
2813b71cb6ad6dabfefc9363a35872f4e70e1125603Chia-I Wu   /* tell renderer about the vertex attributes */
2823b71cb6ad6dabfefc9363a35872f4e70e1125603Chia-I Wu   memset(&velement, 0, sizeof(velement));
2833b71cb6ad6dabfefc9363a35872f4e70e1125603Chia-I Wu   velement.src_offset = 0;
2843b71cb6ad6dabfefc9363a35872f4e70e1125603Chia-I Wu   velement.instance_divisor = 0;
2853b71cb6ad6dabfefc9363a35872f4e70e1125603Chia-I Wu   velement.vertex_buffer_index = 0;
2863b71cb6ad6dabfefc9363a35872f4e70e1125603Chia-I Wu   velement.src_format = PIPE_FORMAT_R32G32_FLOAT;
2873b71cb6ad6dabfefc9363a35872f4e70e1125603Chia-I Wu
2883b71cb6ad6dabfefc9363a35872f4e70e1125603Chia-I Wu   /* tell renderer about the vertex buffer */
2893b71cb6ad6dabfefc9363a35872f4e70e1125603Chia-I Wu   memset(&vbuffer, 0, sizeof(vbuffer));
290fa20733a622770eaaa941f64d570d7b63d8f37b6Marek Olšák   vbuffer.user_buffer = poly->user_vbuf;
2913b71cb6ad6dabfefc9363a35872f4e70e1125603Chia-I Wu   vbuffer.stride = COMPONENTS * sizeof(float);  /* vertex size */
2923b71cb6ad6dabfefc9363a35872f4e70e1125603Chia-I Wu
2933b71cb6ad6dabfefc9363a35872f4e70e1125603Chia-I Wu   renderer_polygon_stencil_begin(ctx->renderer,
2943b71cb6ad6dabfefc9363a35872f4e70e1125603Chia-I Wu         &velement, ctx->state.vg.fill_rule, VG_FALSE);
2953b71cb6ad6dabfefc9363a35872f4e70e1125603Chia-I Wu   renderer_polygon_stencil(ctx->renderer, &vbuffer,
2963b71cb6ad6dabfefc9363a35872f4e70e1125603Chia-I Wu         PIPE_PRIM_TRIANGLE_FAN, 0, (VGuint) poly->num_verts);
2973b71cb6ad6dabfefc9363a35872f4e70e1125603Chia-I Wu   renderer_polygon_stencil_end(ctx->renderer);
298544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin
2993b71cb6ad6dabfefc9363a35872f4e70e1125603Chia-I Wu   renderer_polygon_fill_begin(ctx->renderer, VG_FALSE);
3003b71cb6ad6dabfefc9363a35872f4e70e1125603Chia-I Wu   renderer_polygon_fill(ctx->renderer, min_x, min_y, max_x, max_y);
3013b71cb6ad6dabfefc9363a35872f4e70e1125603Chia-I Wu   renderer_polygon_fill_end(ctx->renderer);
302544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin}
303544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin
304544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusinvoid polygon_array_fill(struct polygon_array *polyarray, struct vg_context *ctx)
305544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin{
306544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   struct array *polys = polyarray->array;
307544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   VGfloat min_x = polyarray->min_x;
308544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   VGfloat min_y = polyarray->min_y;
309544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   VGfloat max_x = polyarray->max_x;
310544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   VGfloat max_y = polyarray->max_y;
3113b71cb6ad6dabfefc9363a35872f4e70e1125603Chia-I Wu   struct pipe_vertex_element velement;
3123b71cb6ad6dabfefc9363a35872f4e70e1125603Chia-I Wu   struct pipe_vertex_buffer vbuffer;
313544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   VGint i;
314544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin
315544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin
316544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin#if DEBUG_POLYGON
317544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   debug_printf("%s: Poly bounds are [%f, %f], [%f, %f]\n",
318544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin                __FUNCTION__,
319544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin                min_x, min_y, max_x, max_y);
320544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin#endif
321544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin
3223b71cb6ad6dabfefc9363a35872f4e70e1125603Chia-I Wu   /* tell renderer about the vertex attributes */
3233b71cb6ad6dabfefc9363a35872f4e70e1125603Chia-I Wu   memset(&velement, 0, sizeof(velement));
3243b71cb6ad6dabfefc9363a35872f4e70e1125603Chia-I Wu   velement.src_offset = 0;
3253b71cb6ad6dabfefc9363a35872f4e70e1125603Chia-I Wu   velement.instance_divisor = 0;
3263b71cb6ad6dabfefc9363a35872f4e70e1125603Chia-I Wu   velement.vertex_buffer_index = 0;
3273b71cb6ad6dabfefc9363a35872f4e70e1125603Chia-I Wu   velement.src_format = PIPE_FORMAT_R32G32_FLOAT;
3283b71cb6ad6dabfefc9363a35872f4e70e1125603Chia-I Wu
3293b71cb6ad6dabfefc9363a35872f4e70e1125603Chia-I Wu   /* tell renderer about the vertex buffer */
3303b71cb6ad6dabfefc9363a35872f4e70e1125603Chia-I Wu   memset(&vbuffer, 0, sizeof(vbuffer));
3313b71cb6ad6dabfefc9363a35872f4e70e1125603Chia-I Wu   vbuffer.stride = COMPONENTS * sizeof(float);  /* vertex size */
3323b71cb6ad6dabfefc9363a35872f4e70e1125603Chia-I Wu
3333b71cb6ad6dabfefc9363a35872f4e70e1125603Chia-I Wu   /* prepare the stencil buffer */
3343b71cb6ad6dabfefc9363a35872f4e70e1125603Chia-I Wu   renderer_polygon_stencil_begin(ctx->renderer,
3353b71cb6ad6dabfefc9363a35872f4e70e1125603Chia-I Wu         &velement, ctx->state.vg.fill_rule, VG_FALSE);
3363b71cb6ad6dabfefc9363a35872f4e70e1125603Chia-I Wu   for (i = 0; i < polys->num_elements; ++i) {
3373b71cb6ad6dabfefc9363a35872f4e70e1125603Chia-I Wu      struct polygon *poly = (((struct polygon**)polys->data)[i]);
3383b71cb6ad6dabfefc9363a35872f4e70e1125603Chia-I Wu
3393b71cb6ad6dabfefc9363a35872f4e70e1125603Chia-I Wu      polygon_prepare_buffer(ctx, poly);
340fa20733a622770eaaa941f64d570d7b63d8f37b6Marek Olšák      vbuffer.user_buffer = poly->user_vbuf;
3413b71cb6ad6dabfefc9363a35872f4e70e1125603Chia-I Wu
3423b71cb6ad6dabfefc9363a35872f4e70e1125603Chia-I Wu      renderer_polygon_stencil(ctx->renderer, &vbuffer,
3433b71cb6ad6dabfefc9363a35872f4e70e1125603Chia-I Wu            PIPE_PRIM_TRIANGLE_FAN, 0, (VGuint) poly->num_verts);
344544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   }
3453b71cb6ad6dabfefc9363a35872f4e70e1125603Chia-I Wu   renderer_polygon_stencil_end(ctx->renderer);
346544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin
3473b71cb6ad6dabfefc9363a35872f4e70e1125603Chia-I Wu   /* fill it */
3483b71cb6ad6dabfefc9363a35872f4e70e1125603Chia-I Wu   renderer_polygon_fill_begin(ctx->renderer, VG_FALSE);
3493b71cb6ad6dabfefc9363a35872f4e70e1125603Chia-I Wu   renderer_polygon_fill(ctx->renderer, min_x, min_y, max_x, max_y);
3503b71cb6ad6dabfefc9363a35872f4e70e1125603Chia-I Wu   renderer_polygon_fill_end(ctx->renderer);
351544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin}
352