blob: e18e29a61e0fe5cc3cf284def45fe32c5152fb43 [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;
Derek Sollenberger5b011e32009-06-22 11:39:40 -040040extern ANPWindowInterfaceV0 gWindowI;
Grace Klobafbe47c02009-05-14 17:31:45 -070041
42static void inval(NPP instance) {
43 browser->invalidaterect(instance, NULL);
44}
45
46static uint16 rnd16(float x, int inset) {
47 int ix = (int)roundf(x) + inset;
48 if (ix < 0) {
49 ix = 0;
50 }
51 return static_cast<uint16>(ix);
52}
53
54static void inval(NPP instance, const ANPRectF& r, bool doAA) {
55 const int inset = doAA ? -1 : 0;
56
57 PluginObject *obj = reinterpret_cast<PluginObject*>(instance->pdata);
58 NPRect inval;
59 inval.left = rnd16(r.left, inset);
60 inval.top = rnd16(r.top, inset);
61 inval.right = rnd16(r.right, -inset);
62 inval.bottom = rnd16(r.bottom, -inset);
63 browser->invalidaterect(instance, &inval);
64}
65
66uint32_t getMSecs() {
67 struct timeval tv;
68 gettimeofday(&tv, NULL);
69 return (uint32_t) (tv.tv_sec * 1000 + tv.tv_usec / 1000 ); // microseconds to milliseconds
70}
71
72///////////////////////////////////////////////////////////////////////////////
73
Derek Sollenbergerd7ebf272009-06-18 11:19:41 -040074BallAnimation::BallAnimation(NPP inst) : SubPlugin(inst) {
Grace Klobafbe47c02009-05-14 17:31:45 -070075 m_x = m_y = 0;
76 m_dx = 7 * SCALE;
77 m_dy = 5 * SCALE;
Derek Sollenbergerd7ebf272009-06-18 11:19:41 -040078
Grace Klobafbe47c02009-05-14 17:31:45 -070079 memset(&m_oval, 0, sizeof(m_oval));
80
81 m_paint = gPaintI.newPaint();
82 gPaintI.setFlags(m_paint, gPaintI.getFlags(m_paint) | kAntiAlias_ANPPaintFlag);
83 gPaintI.setColor(m_paint, 0xFFFF0000);
84 gPaintI.setTextSize(m_paint, 24);
Derek Sollenbergerd7ebf272009-06-18 11:19:41 -040085
Grace Klobafbe47c02009-05-14 17:31:45 -070086 ANPTypeface* tf = gTypefaceI.createFromName("serif", kItalic_ANPTypefaceStyle);
87 gPaintI.setTypeface(m_paint, tf);
88 gTypefaceI.unref(tf);
Derek Sollenbergerd7ebf272009-06-18 11:19:41 -040089
90 //register for key and touch events
Derek Sollenbergerc654bce2009-07-20 10:03:58 -040091 ANPEventFlags flags = kKey_ANPEventFlag | kTouch_ANPEventFlag;
Derek Sollenbergerd7ebf272009-06-18 11:19:41 -040092 NPError err = browser->setvalue(inst, kAcceptEvents_ANPSetValue, &flags);
93 if (err != NPERR_NO_ERROR) {
94 gLogI.log(inst, kError_ANPLogType, "Error selecting input events.");
95 }
Grace Klobafbe47c02009-05-14 17:31:45 -070096}
97
98BallAnimation::~BallAnimation() {
99 gPaintI.deletePaint(m_paint);
100}
101
102static void bounce(float* x, float* dx, const float max) {
103 *x += *dx;
104 if (*x < 0) {
105 *x = 0;
106 if (*dx < 0) {
107 *dx = -*dx;
108 }
109 } else if (*x > max) {
110 *x = max;
111 if (*dx > 0) {
112 *dx = -*dx;
113 }
114 }
115}
116
Derek Sollenberger21f39912009-07-09 09:19:39 -0400117bool BallAnimation::supportsDrawingModel(ANPDrawingModel model) {
118 return (model == kBitmap_ANPDrawingModel);
119}
120
Derek Sollenbergerc0f26572009-07-16 11:38:02 -0400121void BallAnimation::drawPlugin(const ANPBitmap& bitmap, const ANPRectI& clip) {
122 ANPCanvas* canvas = gCanvasI.newCanvas(&bitmap);
123
124 ANPRectF clipR;
125 clipR.left = clip.left;
126 clipR.top = clip.top;
127 clipR.right = clip.right;
128 clipR.bottom = clip.bottom;
129 gCanvasI.clipRect(canvas, &clipR);
130
131 draw(canvas);
132 gCanvasI.deleteCanvas(canvas);
133}
134
Grace Klobafbe47c02009-05-14 17:31:45 -0700135void BallAnimation::draw(ANPCanvas* canvas) {
136 NPP instance = this->inst();
137 PluginObject *obj = (PluginObject*) instance->pdata;
138 const float OW = 20;
139 const float OH = 20;
140 const int W = obj->window->width;
141 const int H = obj->window->height;
142
143 inval(instance, m_oval, true); // inval the old
144 m_oval.left = m_x;
145 m_oval.top = m_y;
146 m_oval.right = m_x + OW;
147 m_oval.bottom = m_y + OH;
148 inval(instance, m_oval, true); // inval the new
149
150 gCanvasI.drawColor(canvas, 0xFFFFFFFF);
151
152 // test out the Path API
153 {
154 ANPPath* path = gPathI.newPath();
155
156 float cx = W * 0.5f;
157 float cy = H * 0.5f;
158 gPathI.moveTo(path, 0, 0);
159 gPathI.quadTo(path, cx, cy, W, 0);
160 gPathI.quadTo(path, cx, cy, W, H);
161 gPathI.quadTo(path, cx, cy, 0, H);
162 gPathI.quadTo(path, cx, cy, 0, 0);
163
164 gPaintI.setColor(m_paint, 0xFF0000FF);
165 gCanvasI.drawPath(canvas, path, m_paint);
166
167 ANPRectF bounds;
168 memset(&bounds, 0, sizeof(bounds));
169 gPathI.getBounds(path, &bounds);
170#if 0
171 gLogI.log(instance, kDebug_ANPLogType, "drawpath: center %g %g bounds [%g %g %g %g]\n",
172 cx, cy,
173 bounds.left, bounds.top, bounds.right, bounds.bottom);
174#endif
175 gPathI.deletePath(path);
176 }
Derek Sollenbergerd7ebf272009-06-18 11:19:41 -0400177
Grace Klobafbe47c02009-05-14 17:31:45 -0700178 gPaintI.setColor(m_paint, 0xFFFF0000);
179 gCanvasI.drawOval(canvas, &m_oval, m_paint);
Derek Sollenbergerd7ebf272009-06-18 11:19:41 -0400180
Grace Klobafbe47c02009-05-14 17:31:45 -0700181 bounce(&m_x, &m_dx, obj->window->width - OW);
182 bounce(&m_y, &m_dy, obj->window->height - OH);
Derek Sollenbergerd7ebf272009-06-18 11:19:41 -0400183
184 if (mUnichar) {
Grace Klobafbe47c02009-05-14 17:31:45 -0700185 ANPFontMetrics fm;
186 gPaintI.getFontMetrics(m_paint, &fm);
Derek Sollenbergerd7ebf272009-06-18 11:19:41 -0400187
Grace Klobafbe47c02009-05-14 17:31:45 -0700188 gPaintI.setColor(m_paint, 0xFF0000FF);
Derek Sollenbergerd7ebf272009-06-18 11:19:41 -0400189 char c = static_cast<char>(mUnichar);
Grace Klobafbe47c02009-05-14 17:31:45 -0700190 gCanvasI.drawText(canvas, &c, 1, 10, -fm.fTop, m_paint);
191 }
192}
193
Derek Sollenbergerc654bce2009-07-20 10:03:58 -0400194void BallAnimation::showEntirePluginOnScreen() {
Derek Sollenberger5b011e32009-06-22 11:39:40 -0400195 NPP instance = this->inst();
196 PluginObject *obj = (PluginObject*) instance->pdata;
197 NPWindow *window = obj->window;
198
Derek Sollenbergerc654bce2009-07-20 10:03:58 -0400199 ANPRectI visibleRects[1];
Derek Sollenberger5b011e32009-06-22 11:39:40 -0400200
Derek Sollenbergerc654bce2009-07-20 10:03:58 -0400201 visibleRects[0].left = 0;
202 visibleRects[0].top = 0;
203 visibleRects[0].right = window->width;
204 visibleRects[0].bottom = window->height;
Derek Sollenberger5b011e32009-06-22 11:39:40 -0400205
Derek Sollenbergerc654bce2009-07-20 10:03:58 -0400206 gWindowI.setVisibleRects(instance, visibleRects, 1);
207 gWindowI.clearVisibleRects(instance);
Derek Sollenberger5b011e32009-06-22 11:39:40 -0400208}
209
Derek Sollenbergerd7ebf272009-06-18 11:19:41 -0400210int16 BallAnimation::handleEvent(const ANPEvent* evt) {
211 NPP instance = this->inst();
Grace Klobafbe47c02009-05-14 17:31:45 -0700212
Derek Sollenbergerd7ebf272009-06-18 11:19:41 -0400213 switch (evt->eventType) {
214 case kDraw_ANPEventType:
215 switch (evt->data.draw.model) {
216 case kBitmap_ANPDrawingModel:
Derek Sollenbergerc0f26572009-07-16 11:38:02 -0400217 drawPlugin(evt->data.draw.data.bitmap, evt->data.draw.clip);
Derek Sollenbergerd7ebf272009-06-18 11:19:41 -0400218 return 1;
219 default:
220 break; // unknown drawing model
221 }
Grace Klobafbe47c02009-05-14 17:31:45 -0700222
Derek Sollenbergerd7ebf272009-06-18 11:19:41 -0400223 case kKey_ANPEventType:
224 if (evt->data.key.action == kDown_ANPKeyAction) {
225 mUnichar = evt->data.key.unichar;
226 gLogI.log(instance, kDebug_ANPLogType, "ball downkey event");
227 browser->invalidaterect(instance, NULL);
228 }
229 return 1;
Derek Sollenberger5b011e32009-06-22 11:39:40 -0400230 case kTouch_ANPEventType:
231 if (kDown_ANPTouchAction == evt->data.touch.action) {
Derek Sollenbergerc654bce2009-07-20 10:03:58 -0400232 showEntirePluginOnScreen();
Derek Sollenberger5b011e32009-06-22 11:39:40 -0400233 }
234 return 1;
Derek Sollenbergerd7ebf272009-06-18 11:19:41 -0400235 default:
236 break;
Grace Klobafbe47c02009-05-14 17:31:45 -0700237 }
Derek Sollenbergerd7ebf272009-06-18 11:19:41 -0400238 return 0; // unknown or unhandled event
Grace Klobafbe47c02009-05-14 17:31:45 -0700239}