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