1/*
2 * Copyright 2009, The Android Open Source Project
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
7 *  * Redistributions of source code must retain the above copyright
8 *    notice, this list of conditions and the following disclaimer.
9 *  * Redistributions in binary form must reproduce the above copyright
10 *    notice, this list of conditions and the following disclaimer in the
11 *    documentation and/or other materials provided with the distribution.
12 *
13 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
14 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR
17 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
18 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
20 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
21 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24 */
25
26// must include config.h first for webkit to fiddle with new/delete
27#include "config.h"
28#include "SkANP.h"
29
30#ifdef SK_SCALAR_IS_FIXED
31static void fromFloat(SkScalar dst[], const float src[], int n) {
32    for (int i = 0; i < n; i++) {
33        dst[i] = SkFloatToScalar(src[i]);
34    }
35}
36
37static void toFloat(float dst[], const SkScalar src[], int n) {
38    for (int i = 0; i < n; i++) {
39        dst[i] = SkScalarToFloat(src[i]);
40    }
41}
42#endif
43
44static ANPMatrix* anp_newMatrix() {
45    return new ANPMatrix;
46}
47
48static void anp_deleteMatrix(ANPMatrix* matrix) {
49    delete matrix;
50}
51
52static ANPMatrixFlag anp_getFlags(const ANPMatrix* matrix) {
53    return matrix->getType();
54}
55
56static void anp_copy(ANPMatrix* dst, const ANPMatrix* src) {
57    *dst = *src;
58}
59
60static void anp_get3x3(const ANPMatrix* matrix, float dst[9]) {
61    for (int i = 0; i < 9; i++) {
62        dst[i] = SkScalarToFloat(matrix->get(i));
63    }
64}
65
66static void anp_set3x3(ANPMatrix* matrix, const float src[9]) {
67    for (int i = 0; i < 9; i++) {
68        matrix->set(i, SkFloatToScalar(src[i]));
69    }
70}
71
72static void anp_setIdentity(ANPMatrix* matrix) {
73    matrix->reset();
74}
75
76static void anp_preTranslate(ANPMatrix* matrix, float tx, float ty) {
77    matrix->preTranslate(SkFloatToScalar(tx), SkFloatToScalar(ty));
78}
79
80static void anp_postTranslate(ANPMatrix* matrix, float tx, float ty) {
81    matrix->postTranslate(SkFloatToScalar(tx), SkFloatToScalar(ty));
82}
83
84static void anp_preScale(ANPMatrix* matrix, float sx, float sy) {
85    matrix->preScale(SkFloatToScalar(sx), SkFloatToScalar(sy));
86}
87
88static void anp_postScale(ANPMatrix* matrix, float sx, float sy) {
89    matrix->postScale(SkFloatToScalar(sx), SkFloatToScalar(sy));
90}
91
92static void anp_preSkew(ANPMatrix* matrix, float kx, float ky) {
93    matrix->preSkew(SkFloatToScalar(kx), SkFloatToScalar(ky));
94}
95
96static void anp_postSkew(ANPMatrix* matrix, float kx, float ky) {
97    matrix->postSkew(SkFloatToScalar(kx), SkFloatToScalar(ky));
98}
99
100static void anp_preRotate(ANPMatrix* matrix, float degrees) {
101    matrix->preRotate(SkFloatToScalar(degrees));
102}
103
104static void anp_postRotate(ANPMatrix* matrix, float degrees) {
105    matrix->postRotate(SkFloatToScalar(degrees));
106}
107
108static void anp_preConcat(ANPMatrix* matrix, const ANPMatrix* other) {
109    matrix->preConcat(*other);
110}
111
112static void anp_postConcat(ANPMatrix* matrix, const ANPMatrix* other) {
113    matrix->postConcat(*other);
114}
115
116static bool anp_invert(ANPMatrix* dst, const ANPMatrix* src) {
117    return src->invert(dst);
118}
119
120static void anp_mapPoints(ANPMatrix* matrix, float dst[], const float src[],
121                          int32_t count) {
122#ifdef SK_SCALAR_IS_FLOAT
123    matrix->mapPoints(reinterpret_cast<SkPoint*>(dst),
124                      reinterpret_cast<const SkPoint*>(src), count);
125#else
126    const int N = 64;
127    SkPoint tmp[N];
128    do {
129        int n = count;
130        if (n > N) {
131            n = N;
132        }
133        fromFloat(&tmp[0].fX, src, n*2);
134        matrix->mapPoints(tmp, n);
135        toFloat(dst, &tmp[0].fX, n*2);
136        count -= n;
137    } while (count > 0);
138#endif
139}
140
141///////////////////////////////////////////////////////////////////////////////
142
143#define ASSIGN(obj, name)   (obj)->name = anp_##name
144
145void ANPMatrixInterfaceV0_Init(ANPInterface* value) {
146    ANPMatrixInterfaceV0* i = reinterpret_cast<ANPMatrixInterfaceV0*>(value);
147
148    ASSIGN(i, newMatrix);
149    ASSIGN(i, deleteMatrix);
150    ASSIGN(i, getFlags);
151    ASSIGN(i, copy);
152    ASSIGN(i, get3x3);
153    ASSIGN(i, set3x3);
154    ASSIGN(i, setIdentity);
155    ASSIGN(i, preTranslate);
156    ASSIGN(i, postTranslate);
157    ASSIGN(i, preScale);
158    ASSIGN(i, postScale);
159    ASSIGN(i, preSkew);
160    ASSIGN(i, postSkew);
161    ASSIGN(i, preRotate);
162    ASSIGN(i, postRotate);
163    ASSIGN(i, preConcat);
164    ASSIGN(i, postConcat);
165    ASSIGN(i, invert);
166    ASSIGN(i, mapPoints);
167}
168