1/*
2 * Copyright 2008, 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
30static ANPCanvas* anp_newCanvas(const ANPBitmap* bitmap) {
31    SkBitmap bm;
32    return new ANPCanvas(*SkANP::SetBitmap(&bm, *bitmap));
33}
34
35static void anp_deleteCanvas(ANPCanvas* canvas) {
36    delete canvas;
37}
38
39static void anp_save(ANPCanvas* canvas) {
40    canvas->skcanvas->save();
41}
42
43static void anp_restore(ANPCanvas* canvas) {
44    canvas->skcanvas->restore();
45}
46
47static void anp_translate(ANPCanvas* canvas, float tx, float ty) {
48    canvas->skcanvas->translate(SkFloatToScalar(tx), SkFloatToScalar(ty));
49}
50
51static void anp_scale(ANPCanvas* canvas, float sx, float sy) {
52    canvas->skcanvas->scale(SkFloatToScalar(sx), SkFloatToScalar(sy));
53}
54
55static void anp_rotate(ANPCanvas* canvas, float degrees) {
56    canvas->skcanvas->rotate(SkFloatToScalar(degrees));
57}
58
59static void anp_skew(ANPCanvas* canvas, float kx, float ky) {
60    canvas->skcanvas->skew(SkFloatToScalar(kx), SkFloatToScalar(ky));
61}
62
63static void anp_clipRect(ANPCanvas* canvas, const ANPRectF* rect) {
64    SkRect r;
65    canvas->skcanvas->clipRect(*SkANP::SetRect(&r, *rect));
66}
67
68static void anp_clipPath(ANPCanvas* canvas, const ANPPath* path) {
69    canvas->skcanvas->clipPath(*path);
70}
71static void anp_concat(ANPCanvas* canvas, const ANPMatrix* matrix) {
72    canvas->skcanvas->concat(*matrix);
73}
74
75static void anp_getTotalMatrix(ANPCanvas* canvas, ANPMatrix* matrix) {
76    const SkMatrix& src = canvas->skcanvas->getTotalMatrix();
77    *matrix = *reinterpret_cast<const ANPMatrix*>(&src);
78}
79
80static bool anp_getLocalClipBounds(ANPCanvas* canvas, ANPRectF* r,
81                                   bool antialias) {
82    SkRect bounds;
83    if (canvas->skcanvas->getClipBounds(&bounds,
84                antialias ? SkCanvas::kAA_EdgeType : SkCanvas::kBW_EdgeType)) {
85        SkANP::SetRect(r, bounds);
86        return true;
87    }
88    return false;
89}
90
91static bool anp_getDeviceClipBounds(ANPCanvas* canvas, ANPRectI* r) {
92    const SkRegion& clip = canvas->skcanvas->getTotalClip();
93    if (!clip.isEmpty()) {
94        SkANP::SetRect(r, clip.getBounds());
95        return true;
96    }
97    return false;
98}
99
100static void anp_drawColor(ANPCanvas* canvas, ANPColor color) {
101    canvas->skcanvas->drawColor(color);
102}
103
104static void anp_drawPaint(ANPCanvas* canvas, const ANPPaint* paint) {
105    canvas->skcanvas->drawPaint(*paint);
106}
107
108static void anp_drawLine(ANPCanvas* canvas, float x0, float y0,
109                         float x1, float y1, const ANPPaint* paint) {
110    canvas->skcanvas->drawLine(SkFloatToScalar(x0), SkFloatToScalar(y0),
111                           SkFloatToScalar(x1), SkFloatToScalar(y1), *paint);
112}
113
114static void anp_drawRect(ANPCanvas* canvas, const ANPRectF* rect,
115                         const ANPPaint* paint) {
116    SkRect  r;
117    canvas->skcanvas->drawRect(*SkANP::SetRect(&r, *rect), *paint);
118}
119
120static void anp_drawOval(ANPCanvas* canvas, const ANPRectF* rect,
121                         const ANPPaint* paint) {
122    SkRect  r;
123    canvas->skcanvas->drawOval(*SkANP::SetRect(&r, *rect), *paint);
124}
125
126static void anp_drawPath(ANPCanvas* canvas, const ANPPath* path,
127                         const ANPPaint* paint) {
128    canvas->skcanvas->drawPath(*path, *paint);
129}
130
131static void anp_drawText(ANPCanvas* canvas, const void* text, uint32_t length,
132                         float x, float y, const ANPPaint* paint) {
133    canvas->skcanvas->drawText(text, length,
134                               SkFloatToScalar(x), SkFloatToScalar(y),
135                               *paint);
136}
137
138static void anp_drawPosText(ANPCanvas* canvas, const void* text,
139                uint32_t byteLength, const float xy[], const ANPPaint* paint) {
140    canvas->skcanvas->drawPosText(text, byteLength,
141                                  reinterpret_cast<const SkPoint*>(xy), *paint);
142}
143
144static void anp_drawBitmap(ANPCanvas* canvas, const ANPBitmap* bitmap,
145                           float x, float y, const ANPPaint* paint) {
146    SkBitmap    bm;
147    canvas->skcanvas->drawBitmap(*SkANP::SetBitmap(&bm, *bitmap),
148                                 SkFloatToScalar(x), SkFloatToScalar(y),
149                                 paint);
150}
151
152static void anp_drawBitmapRect(ANPCanvas* canvas, const ANPBitmap* bitmap,
153                              const ANPRectI* src, const ANPRectF* dst,
154                               const ANPPaint* paint) {
155    SkBitmap    bm;
156    SkRect      dstR;
157    SkIRect     srcR, *srcPtr = NULL;
158
159    if (src) {
160        srcPtr = SkANP::SetRect(&srcR, *src);
161    }
162    canvas->skcanvas->drawBitmapRect(*SkANP::SetBitmap(&bm, *bitmap), srcPtr,
163                           *SkANP::SetRect(&dstR, *dst), paint);
164}
165
166///////////////////////////////////////////////////////////////////////////////
167
168#define ASSIGN(obj, name)   (obj)->name = anp_##name
169
170void ANPCanvasInterfaceV0_Init(ANPInterface* value) {
171    ANPCanvasInterfaceV0* i = reinterpret_cast<ANPCanvasInterfaceV0*>(value);
172
173    ASSIGN(i, newCanvas);
174    ASSIGN(i, deleteCanvas);
175    ASSIGN(i, save);
176    ASSIGN(i, restore);
177    ASSIGN(i, translate);
178    ASSIGN(i, scale);
179    ASSIGN(i, rotate);
180    ASSIGN(i, skew);
181    ASSIGN(i, clipRect);
182    ASSIGN(i, clipPath);
183    ASSIGN(i, concat);
184    ASSIGN(i, getTotalMatrix);
185    ASSIGN(i, getLocalClipBounds);
186    ASSIGN(i, getDeviceClipBounds);
187    ASSIGN(i, drawColor);
188    ASSIGN(i, drawPaint);
189    ASSIGN(i, drawLine);
190    ASSIGN(i, drawRect);
191    ASSIGN(i, drawOval);
192    ASSIGN(i, drawPath);
193    ASSIGN(i, drawText);
194    ASSIGN(i, drawPosText);
195    ASSIGN(i, drawBitmap);
196    ASSIGN(i, drawBitmapRect);
197}
198