revert between 56095 -> 55830 in arch
[AROS.git] / workbench / libs / mesa / src / gallium / state_trackers / vega / vgu.c
blobcb15bd8cecf7b24595a69c495f623c35d4c4bb55
1 /**************************************************************************
3 * Copyright 2009 VMware, Inc. All Rights Reserved.
5 * Permission is hereby granted, free of charge, to any person obtaining a
6 * copy of this software and associated documentation files (the
7 * "Software"), to deal in the Software without restriction, including
8 * without limitation the rights to use, copy, modify, merge, publish,
9 * distribute, sub license, and/or sell copies of the Software, and to
10 * permit persons to whom the Software is furnished to do so, subject to
11 * the following conditions:
13 * The above copyright notice and this permission notice (including the
14 * next paragraph) shall be included in all copies or substantial portions
15 * of the Software.
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
18 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
19 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
20 * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR
21 * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
22 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
23 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
25 **************************************************************************/
27 #include "VG/openvg.h"
28 #include "VG/vgu.h"
30 #include "matrix.h"
31 #include "path.h"
32 #include "handle.h"
34 #include "util/u_debug.h"
35 #include "util/u_pointer.h"
37 #include <math.h>
38 #include <assert.h>
40 static void vgu_append_float_coords(VGPath path,
41 const VGubyte *cmds,
42 VGint num_cmds,
43 const VGfloat *coords,
44 VGint num_coords)
46 VGubyte common_data[40 * sizeof(VGfloat)];
47 struct path *p = handle_to_path(path);
49 vg_float_to_datatype(path_datatype(p), common_data, coords, num_coords);
50 vgAppendPathData(path, num_cmds, cmds, common_data);
53 VGUErrorCode vguLine(VGPath path,
54 VGfloat x0, VGfloat y0,
55 VGfloat x1, VGfloat y1)
57 static const VGubyte cmds[] = {VG_MOVE_TO_ABS, VG_LINE_TO_ABS};
58 VGfloat coords[4];
59 VGbitfield caps;
61 if (path == VG_INVALID_HANDLE) {
62 return VGU_BAD_HANDLE_ERROR;
64 caps = vgGetPathCapabilities(path);
65 if (!(caps & VG_PATH_CAPABILITY_APPEND_TO)) {
66 return VGU_PATH_CAPABILITY_ERROR;
69 coords[0] = x0;
70 coords[1] = y0;
71 coords[2] = x1;
72 coords[3] = y1;
74 vgu_append_float_coords(path, cmds, 2, coords, 4);
76 return VGU_NO_ERROR;
79 VGUErrorCode vguPolygon(VGPath path,
80 const VGfloat * points,
81 VGint count,
82 VGboolean closed)
84 VGubyte *cmds;
85 VGfloat *coords;
86 VGbitfield caps;
87 VGint i;
89 if (path == VG_INVALID_HANDLE) {
90 return VGU_BAD_HANDLE_ERROR;
93 if (!points || count <= 0 || !is_aligned(points)) {
94 return VGU_ILLEGAL_ARGUMENT_ERROR;
97 caps = vgGetPathCapabilities(path);
98 if (!(caps & VG_PATH_CAPABILITY_APPEND_TO)) {
99 return VGU_PATH_CAPABILITY_ERROR;
102 cmds = malloc(sizeof(VGubyte) * count + 1);
103 coords = malloc(sizeof(VGfloat) * count * 2);
105 cmds[0] = VG_MOVE_TO_ABS;
106 coords[0] = points[0];
107 coords[1] = points[1];
108 for (i = 1; i < count; ++i) {
109 cmds[i] = VG_LINE_TO_ABS;
110 coords[2*i + 0] = points[2*i + 0];
111 coords[2*i + 1] = points[2*i + 1];
114 if (closed) {
115 cmds[i] = VG_CLOSE_PATH;
116 ++i;
119 vgu_append_float_coords(path, cmds, i, coords, 2*i);
121 free(cmds);
122 free(coords);
124 return VGU_NO_ERROR;
127 VGUErrorCode vguRect(VGPath path,
128 VGfloat x, VGfloat y,
129 VGfloat width, VGfloat height)
131 static const VGubyte cmds[] = {VG_MOVE_TO_ABS,
132 VG_HLINE_TO_REL,
133 VG_VLINE_TO_REL,
134 VG_HLINE_TO_REL,
135 VG_CLOSE_PATH
137 VGfloat coords[5];
138 VGbitfield caps;
140 if (path == VG_INVALID_HANDLE) {
141 return VGU_BAD_HANDLE_ERROR;
143 caps = vgGetPathCapabilities(path);
144 if (!(caps & VG_PATH_CAPABILITY_APPEND_TO)) {
145 return VGU_PATH_CAPABILITY_ERROR;
147 if (width <= 0 || height <= 0) {
148 return VGU_ILLEGAL_ARGUMENT_ERROR;
151 coords[0] = x;
152 coords[1] = y;
153 coords[2] = width;
154 coords[3] = height;
155 coords[4] = -width;
157 vgu_append_float_coords(path, cmds, 5, coords, 5);
159 return VGU_NO_ERROR;
162 VGUErrorCode vguRoundRect(VGPath path,
163 VGfloat x, VGfloat y,
164 VGfloat width,
165 VGfloat height,
166 VGfloat arcWidth,
167 VGfloat arcHeight)
169 static const VGubyte cmds[] = {VG_MOVE_TO_ABS,
170 VG_HLINE_TO_REL,
171 VG_SCCWARC_TO_REL,
172 VG_VLINE_TO_REL,
173 VG_SCCWARC_TO_REL,
174 VG_HLINE_TO_REL,
175 VG_SCCWARC_TO_REL,
176 VG_VLINE_TO_REL,
177 VG_SCCWARC_TO_REL,
178 VG_CLOSE_PATH
180 VGfloat c[26];
181 VGbitfield caps;
183 if (path == VG_INVALID_HANDLE) {
184 return VGU_BAD_HANDLE_ERROR;
186 caps = vgGetPathCapabilities(path);
187 if (!(caps & VG_PATH_CAPABILITY_APPEND_TO)) {
188 return VGU_PATH_CAPABILITY_ERROR;
190 if (width <= 0 || height <= 0) {
191 return VGU_ILLEGAL_ARGUMENT_ERROR;
194 c[0] = x + arcWidth/2; c[1] = y;
196 c[2] = width - arcWidth;
198 c[3] = arcWidth/2; c[4] = arcHeight/2; c[5] = 0;
199 c[6] = arcWidth/2; c[7] = arcHeight/2;
201 c[8] = height - arcHeight;
203 c[9] = arcWidth/2; c[10] = arcHeight/2; c[11] = 0;
204 c[12] = -arcWidth/2; c[13] = arcHeight/2;
206 c[14] = -(width - arcWidth);
208 c[15] = arcWidth/2; c[16] = arcHeight/2; c[17] = 0;
209 c[18] = -arcWidth/2; c[19] = -arcHeight/2;
211 c[20] = -(height - arcHeight);
213 c[21] = arcWidth/2; c[22] = arcHeight/2; c[23] = 0;
214 c[24] = arcWidth/2; c[25] = -arcHeight/2;
216 vgu_append_float_coords(path, cmds, 10, c, 26);
218 return VGU_NO_ERROR;
221 VGUErrorCode vguEllipse(VGPath path,
222 VGfloat cx, VGfloat cy,
223 VGfloat width,
224 VGfloat height)
226 static const VGubyte cmds[] = {VG_MOVE_TO_ABS,
227 VG_SCCWARC_TO_REL,
228 VG_SCCWARC_TO_REL,
229 VG_CLOSE_PATH
231 VGfloat coords[12];
232 VGbitfield caps;
234 if (path == VG_INVALID_HANDLE) {
235 return VGU_BAD_HANDLE_ERROR;
237 caps = vgGetPathCapabilities(path);
238 if (!(caps & VG_PATH_CAPABILITY_APPEND_TO)) {
239 return VGU_PATH_CAPABILITY_ERROR;
241 if (width <= 0 || height <= 0) {
242 return VGU_ILLEGAL_ARGUMENT_ERROR;
245 coords[0] = cx + width/2; coords[1] = cy;
247 coords[2] = width/2; coords[3] = height/2; coords[4] = 0;
248 coords[5] = -width; coords[6] = 0;
250 coords[7] = width/2; coords[8] = height/2; coords[9] = 0;
251 coords[10] = width; coords[11] = 0;
253 vgu_append_float_coords(path, cmds, 4, coords, 11);
255 return VGU_NO_ERROR;
258 VGUErrorCode vguArc(VGPath path,
259 VGfloat x, VGfloat y,
260 VGfloat width, VGfloat height,
261 VGfloat startAngle,
262 VGfloat angleExtent,
263 VGUArcType arcType)
265 VGubyte cmds[11];
266 VGfloat coords[40];
267 VGbitfield caps;
268 VGfloat last = startAngle + angleExtent;
269 VGint i, c = 0;
271 if (path == VG_INVALID_HANDLE) {
272 return VGU_BAD_HANDLE_ERROR;
274 caps = vgGetPathCapabilities(path);
275 if (!(caps & VG_PATH_CAPABILITY_APPEND_TO)) {
276 return VGU_PATH_CAPABILITY_ERROR;
278 if (width <= 0 || height <= 0) {
279 return VGU_ILLEGAL_ARGUMENT_ERROR;
281 if (arcType != VGU_ARC_OPEN &&
282 arcType != VGU_ARC_CHORD &&
283 arcType != VGU_ARC_PIE) {
284 return VGU_ILLEGAL_ARGUMENT_ERROR;
287 cmds[c] = VG_MOVE_TO_ABS; ++c;
288 coords[0] = x+cos(DEGREES_TO_RADIANS(startAngle))*width/2;
289 coords[1] = y+sin(DEGREES_TO_RADIANS(startAngle))*height/2;
290 #ifdef DEBUG_VGUARC
291 debug_printf("start [%f, %f]\n", coords[0], coords[1]);
292 #endif
293 i = 2;
294 if (angleExtent > 0) {
295 VGfloat angle = startAngle + 180;
296 while (angle < last) {
297 cmds[c] = VG_SCCWARC_TO_ABS; ++c;
298 coords[i] = width/2; coords[i+1] = height/2; coords[i+2] = 0;
299 coords[i+3] = x + cos(DEGREES_TO_RADIANS(angle))*width/2;
300 coords[i+4] = y + sin(DEGREES_TO_RADIANS(angle))*height/2;
301 #ifdef DEBUG_VGUARC
302 debug_printf("1 [%f, %f]\n", coords[i+3],
303 coords[i+4]);
304 #endif
305 i += 5;
306 angle += 180;
308 cmds[c] = VG_SCCWARC_TO_ABS; ++c;
309 coords[i] = width/2; coords[i+1] = height/2; coords[i+2] = 0;
310 coords[i+3] = x+cos(DEGREES_TO_RADIANS(last))*width/2;
311 coords[i+4] = y+sin(DEGREES_TO_RADIANS(last))*height/2;
312 #ifdef DEBUG_VGUARC
313 debug_printf("2 [%f, %f]\n", coords[i+3],
314 coords[i+4]);
315 #endif
316 i += 5;
317 } else {
318 VGfloat angle = startAngle - 180;
319 while (angle > last) {
320 cmds[c] = VG_SCWARC_TO_ABS; ++c;
321 coords[i] = width/2; coords[i+1] = height/2; coords[i+2] = 0;
322 coords[i+3] = x + cos(DEGREES_TO_RADIANS(angle)) * width/2;
323 coords[i+4] = y + sin(DEGREES_TO_RADIANS(angle)) * height/2;
324 #ifdef DEBUG_VGUARC
325 debug_printf("3 [%f, %f]\n", coords[i+3],
326 coords[i+4]);
327 #endif
328 angle -= 180;
329 i += 5;
331 cmds[c] = VG_SCWARC_TO_ABS; ++c;
332 coords[i] = width/2; coords[i+1] = height/2; coords[i+2] = 0;
333 coords[i+3] = x + cos(DEGREES_TO_RADIANS(last)) * width/2;
334 coords[i+4] = y + sin(DEGREES_TO_RADIANS(last)) * height/2;
335 #ifdef DEBUG_VGUARC
336 debug_printf("4 [%f, %f]\n", coords[i+3],
337 coords[i+4]);
338 #endif
339 i += 5;
342 if (arcType == VGU_ARC_PIE) {
343 cmds[c] = VG_LINE_TO_ABS; ++c;
344 coords[i] = x; coords[i + 1] = y;
345 i += 2;
347 if (arcType == VGU_ARC_PIE || arcType == VGU_ARC_CHORD) {
348 cmds[c] = VG_CLOSE_PATH;
349 ++c;
352 assert(c < 11);
354 vgu_append_float_coords(path, cmds, c, coords, i);
356 return VGU_NO_ERROR;
359 VGUErrorCode vguComputeWarpQuadToSquare(VGfloat sx0, VGfloat sy0,
360 VGfloat sx1, VGfloat sy1,
361 VGfloat sx2, VGfloat sy2,
362 VGfloat sx3, VGfloat sy3,
363 VGfloat * matrix)
365 struct matrix mat;
367 if (!matrix || !is_aligned(matrix))
368 return VGU_ILLEGAL_ARGUMENT_ERROR;
370 if (!matrix_quad_to_square(sx0, sy0,
371 sx1, sy1,
372 sx2, sy2,
373 sx3, sy3,
374 &mat))
375 return VGU_BAD_WARP_ERROR;
377 if (!matrix_is_invertible(&mat))
378 return VGU_BAD_WARP_ERROR;
380 memcpy(matrix, mat.m, sizeof(VGfloat) * 9);
382 return VGU_NO_ERROR;
385 VGUErrorCode vguComputeWarpSquareToQuad(VGfloat dx0, VGfloat dy0,
386 VGfloat dx1, VGfloat dy1,
387 VGfloat dx2, VGfloat dy2,
388 VGfloat dx3, VGfloat dy3,
389 VGfloat * matrix)
391 struct matrix mat;
393 if (!matrix || !is_aligned(matrix))
394 return VGU_ILLEGAL_ARGUMENT_ERROR;
396 if (!matrix_square_to_quad(dx0, dy0,
397 dx1, dy1,
398 dx2, dy2,
399 dx3, dy3,
400 &mat))
401 return VGU_BAD_WARP_ERROR;
403 if (!matrix_is_invertible(&mat))
404 return VGU_BAD_WARP_ERROR;
406 memcpy(matrix, mat.m, sizeof(VGfloat) * 9);
408 return VGU_NO_ERROR;
411 VGUErrorCode vguComputeWarpQuadToQuad(VGfloat dx0, VGfloat dy0,
412 VGfloat dx1, VGfloat dy1,
413 VGfloat dx2, VGfloat dy2,
414 VGfloat dx3, VGfloat dy3,
415 VGfloat sx0, VGfloat sy0,
416 VGfloat sx1, VGfloat sy1,
417 VGfloat sx2, VGfloat sy2,
418 VGfloat sx3, VGfloat sy3,
419 VGfloat * matrix)
421 struct matrix mat;
423 if (!matrix || !is_aligned(matrix))
424 return VGU_ILLEGAL_ARGUMENT_ERROR;
426 if (!matrix_quad_to_quad(dx0, dy0,
427 dx1, dy1,
428 dx2, dy2,
429 dx3, dy3,
430 sx0, sy0,
431 sx1, sy1,
432 sx2, sy2,
433 sx3, sy3,
434 &mat))
435 return VGU_BAD_WARP_ERROR;
437 memcpy(matrix, mat.m, sizeof(VGfloat) * 9);
439 return VGU_NO_ERROR;