blob: 7f15d0d770e91c5d2f0c81683fc0d239e95d19bd [file] [log] [blame]
Grace Klobafbe47c02009-05-14 17:31:45 -07001/*
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 APPLE COMPUTER, INC. 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 */
Grace Klobafbe47c02009-05-14 17:31:45 -070025
Derek Sollenbergerd7ebf272009-06-18 11:19:41 -040026#include "AnimationPlugin.h"
27
Grace Klobafbe47c02009-05-14 17:31:45 -070028#include <stdio.h>
29#include <sys/time.h>
30#include <time.h>
31#include <math.h>
32#include <string.h>
33
34extern NPNetscapeFuncs* browser;
35extern ANPLogInterfaceV0 gLogI;
36extern ANPCanvasInterfaceV0 gCanvasI;
37extern ANPPaintInterfaceV0 gPaintI;
38extern ANPPathInterfaceV0 gPathI;
39extern ANPTypefaceInterfaceV0 gTypefaceI;
40
41static void inval(NPP instance) {
42 browser->invalidaterect(instance, NULL);
43}
44
45static uint16 rnd16(float x, int inset) {
46 int ix = (int)roundf(x) + inset;
47 if (ix < 0) {
48 ix = 0;
49 }
50 return static_cast<uint16>(ix);
51}
52
53static void inval(NPP instance, const ANPRectF& r, bool doAA) {
54 const int inset = doAA ? -1 : 0;
55
56 PluginObject *obj = reinterpret_cast<PluginObject*>(instance->pdata);
57 NPRect inval;
58 inval.left = rnd16(r.left, inset);
59 inval.top = rnd16(r.top, inset);
60 inval.right = rnd16(r.right, -inset);
61 inval.bottom = rnd16(r.bottom, -inset);
62 browser->invalidaterect(instance, &inval);
63}
64
Derek Sollenbergerd7ebf272009-06-18 11:19:41 -040065static void drawPlugin(SubPlugin* plugin, const ANPBitmap& bitmap, const ANPRectI& clip) {
66 ANPCanvas* canvas = gCanvasI.newCanvas(&bitmap);
67
68 ANPRectF clipR;
69 clipR.left = clip.left;
70 clipR.top = clip.top;
71 clipR.right = clip.right;
72 clipR.bottom = clip.bottom;
73 gCanvasI.clipRect(canvas, &clipR);
74
75 plugin->draw(canvas);
76 gCanvasI.deleteCanvas(canvas);
77}
78
Grace Klobafbe47c02009-05-14 17:31:45 -070079uint32_t getMSecs() {
80 struct timeval tv;
81 gettimeofday(&tv, NULL);
82 return (uint32_t) (tv.tv_sec * 1000 + tv.tv_usec / 1000 ); // microseconds to milliseconds
83}
84
85///////////////////////////////////////////////////////////////////////////////
86
Derek Sollenbergerd7ebf272009-06-18 11:19:41 -040087BallAnimation::BallAnimation(NPP inst) : SubPlugin(inst) {
Grace Klobafbe47c02009-05-14 17:31:45 -070088 m_x = m_y = 0;
89 m_dx = 7 * SCALE;
90 m_dy = 5 * SCALE;
Derek Sollenbergerd7ebf272009-06-18 11:19:41 -040091
Grace Klobafbe47c02009-05-14 17:31:45 -070092 memset(&m_oval, 0, sizeof(m_oval));
93
94 m_paint = gPaintI.newPaint();
95 gPaintI.setFlags(m_paint, gPaintI.getFlags(m_paint) | kAntiAlias_ANPPaintFlag);
96 gPaintI.setColor(m_paint, 0xFFFF0000);
97 gPaintI.setTextSize(m_paint, 24);
Derek Sollenbergerd7ebf272009-06-18 11:19:41 -040098
Grace Klobafbe47c02009-05-14 17:31:45 -070099 ANPTypeface* tf = gTypefaceI.createFromName("serif", kItalic_ANPTypefaceStyle);
100 gPaintI.setTypeface(m_paint, tf);
101 gTypefaceI.unref(tf);
Derek Sollenbergerd7ebf272009-06-18 11:19:41 -0400102
103 //register for key and touch events
104 ANPEventFlags flags = kKey_ANPEventFlag | kTouch_ANPEventFlag;
105 NPError err = browser->setvalue(inst, kAcceptEvents_ANPSetValue, &flags);
106 if (err != NPERR_NO_ERROR) {
107 gLogI.log(inst, kError_ANPLogType, "Error selecting input events.");
108 }
Grace Klobafbe47c02009-05-14 17:31:45 -0700109}
110
111BallAnimation::~BallAnimation() {
112 gPaintI.deletePaint(m_paint);
113}
114
115static void bounce(float* x, float* dx, const float max) {
116 *x += *dx;
117 if (*x < 0) {
118 *x = 0;
119 if (*dx < 0) {
120 *dx = -*dx;
121 }
122 } else if (*x > max) {
123 *x = max;
124 if (*dx > 0) {
125 *dx = -*dx;
126 }
127 }
128}
129
130void BallAnimation::draw(ANPCanvas* canvas) {
131 NPP instance = this->inst();
132 PluginObject *obj = (PluginObject*) instance->pdata;
133 const float OW = 20;
134 const float OH = 20;
135 const int W = obj->window->width;
136 const int H = obj->window->height;
137
138 inval(instance, m_oval, true); // inval the old
139 m_oval.left = m_x;
140 m_oval.top = m_y;
141 m_oval.right = m_x + OW;
142 m_oval.bottom = m_y + OH;
143 inval(instance, m_oval, true); // inval the new
144
145 gCanvasI.drawColor(canvas, 0xFFFFFFFF);
146
147 // test out the Path API
148 {
149 ANPPath* path = gPathI.newPath();
150
151 float cx = W * 0.5f;
152 float cy = H * 0.5f;
153 gPathI.moveTo(path, 0, 0);
154 gPathI.quadTo(path, cx, cy, W, 0);
155 gPathI.quadTo(path, cx, cy, W, H);
156 gPathI.quadTo(path, cx, cy, 0, H);
157 gPathI.quadTo(path, cx, cy, 0, 0);
158
159 gPaintI.setColor(m_paint, 0xFF0000FF);
160 gCanvasI.drawPath(canvas, path, m_paint);
161
162 ANPRectF bounds;
163 memset(&bounds, 0, sizeof(bounds));
164 gPathI.getBounds(path, &bounds);
165#if 0
166 gLogI.log(instance, kDebug_ANPLogType, "drawpath: center %g %g bounds [%g %g %g %g]\n",
167 cx, cy,
168 bounds.left, bounds.top, bounds.right, bounds.bottom);
169#endif
170 gPathI.deletePath(path);
171 }
Derek Sollenbergerd7ebf272009-06-18 11:19:41 -0400172
Grace Klobafbe47c02009-05-14 17:31:45 -0700173 gPaintI.setColor(m_paint, 0xFFFF0000);
174 gCanvasI.drawOval(canvas, &m_oval, m_paint);
Derek Sollenbergerd7ebf272009-06-18 11:19:41 -0400175
Grace Klobafbe47c02009-05-14 17:31:45 -0700176 bounce(&m_x, &m_dx, obj->window->width - OW);
177 bounce(&m_y, &m_dy, obj->window->height - OH);
Derek Sollenbergerd7ebf272009-06-18 11:19:41 -0400178
179 if (mUnichar) {
Grace Klobafbe47c02009-05-14 17:31:45 -0700180 ANPFontMetrics fm;
181 gPaintI.getFontMetrics(m_paint, &fm);
Derek Sollenbergerd7ebf272009-06-18 11:19:41 -0400182
Grace Klobafbe47c02009-05-14 17:31:45 -0700183 gPaintI.setColor(m_paint, 0xFF0000FF);
Derek Sollenbergerd7ebf272009-06-18 11:19:41 -0400184 char c = static_cast<char>(mUnichar);
Grace Klobafbe47c02009-05-14 17:31:45 -0700185 gCanvasI.drawText(canvas, &c, 1, 10, -fm.fTop, m_paint);
186 }
187}
188
Derek Sollenbergerd7ebf272009-06-18 11:19:41 -0400189int16 BallAnimation::handleEvent(const ANPEvent* evt) {
190 NPP instance = this->inst();
Grace Klobafbe47c02009-05-14 17:31:45 -0700191
Derek Sollenbergerd7ebf272009-06-18 11:19:41 -0400192 switch (evt->eventType) {
193 case kDraw_ANPEventType:
194 switch (evt->data.draw.model) {
195 case kBitmap_ANPDrawingModel:
196 drawPlugin(this, evt->data.draw.data.bitmap, evt->data.draw.clip);
197 return 1;
198 default:
199 break; // unknown drawing model
200 }
Grace Klobafbe47c02009-05-14 17:31:45 -0700201
Derek Sollenbergerd7ebf272009-06-18 11:19:41 -0400202 case kKey_ANPEventType:
203 if (evt->data.key.action == kDown_ANPKeyAction) {
204 mUnichar = evt->data.key.unichar;
205 gLogI.log(instance, kDebug_ANPLogType, "ball downkey event");
206 browser->invalidaterect(instance, NULL);
207 }
208 return 1;
209
210 default:
211 break;
Grace Klobafbe47c02009-05-14 17:31:45 -0700212 }
Derek Sollenbergerd7ebf272009-06-18 11:19:41 -0400213 return 0; // unknown or unhandled event
Grace Klobafbe47c02009-05-14 17:31:45 -0700214}