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 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 */ 25 26 #include "AnimationPlugin.h" 27 28 #include <math.h> 29 #include <string.h> 30 31 extern NPNetscapeFuncs* browser; 32 extern ANPLogInterfaceV0 gLogI; 33 extern ANPCanvasInterfaceV0 gCanvasI; 34 extern ANPPaintInterfaceV0 gPaintI; 35 extern ANPPathInterfaceV0 gPathI; 36 extern ANPWindowInterfaceV0 gWindowI; 37 38 static uint16 rnd16(float x, int inset) { 39 int ix = (int)roundf(x) + inset; 40 if (ix < 0) { 41 ix = 0; 42 } 43 return static_cast<uint16>(ix); 44 } 45 46 static void inval(NPP instance, const ANPRectF& r, bool doAA) { 47 const int inset = doAA ? -1 : 0; 48 49 NPRect inval; 50 inval.left = rnd16(r.left, inset); 51 inval.top = rnd16(r.top, inset); 52 inval.right = rnd16(r.right, -inset); 53 inval.bottom = rnd16(r.bottom, -inset); 54 browser->invalidaterect(instance, &inval); 55 } 56 57 static void bounce(float* x, float* dx, const float max) { 58 *x += *dx; 59 if (*x < 0) { 60 *x = 0; 61 if (*dx < 0) { 62 *dx = -*dx; 63 } 64 } else if (*x > max) { 65 *x = max; 66 if (*dx > 0) { 67 *dx = -*dx; 68 } 69 } 70 } 71 /////////////////////////////////////////////////////////////////////////////// 72 73 BallAnimation::BallAnimation(NPP inst) : SubPlugin(inst) { 74 m_x = m_y = 0; 75 m_dx = 7 * SCALE; 76 m_dy = 5 * SCALE; 77 78 memset(&m_oval, 0, sizeof(m_oval)); 79 80 m_paint = gPaintI.newPaint(); 81 gPaintI.setFlags(m_paint, gPaintI.getFlags(m_paint) | kAntiAlias_ANPPaintFlag); 82 gPaintI.setColor(m_paint, 0xFFFF0000); 83 84 //register for touch events 85 ANPEventFlags flags = kTouch_ANPEventFlag; 86 NPError err = browser->setvalue(inst, kAcceptEvents_ANPSetValue, &flags); 87 if (err != NPERR_NO_ERROR) { 88 gLogI.log(kError_ANPLogType, "Error selecting input events."); 89 } 90 } 91 92 BallAnimation::~BallAnimation() { 93 gPaintI.deletePaint(m_paint); 94 } 95 96 bool BallAnimation::supportsDrawingModel(ANPDrawingModel model) { 97 return (model == kBitmap_ANPDrawingModel); 98 } 99 100 void BallAnimation::drawPlugin(const ANPBitmap& bitmap, const ANPRectI& clip) { 101 102 // create a canvas 103 ANPCanvas* canvas = gCanvasI.newCanvas(&bitmap); 104 105 // clip the canvas 106 ANPRectF clipR; 107 clipR.left = clip.left; 108 clipR.top = clip.top; 109 clipR.right = clip.right; 110 clipR.bottom = clip.bottom; 111 gCanvasI.clipRect(canvas, &clipR); 112 113 // setup variables 114 PluginObject *obj = (PluginObject*) inst()->pdata; 115 const float OW = 20; 116 const float OH = 20; 117 const int W = obj->window->width; 118 const int H = obj->window->height; 119 120 // paint the canvas (using the path API) 121 gCanvasI.drawColor(canvas, 0xFFFFFFFF); 122 { 123 ANPPath* path = gPathI.newPath(); 124 125 float cx = W * 0.5f; 126 float cy = H * 0.5f; 127 gPathI.moveTo(path, 0, 0); 128 gPathI.quadTo(path, cx, cy, W, 0); 129 gPathI.quadTo(path, cx, cy, W, H); 130 gPathI.quadTo(path, cx, cy, 0, H); 131 gPathI.quadTo(path, cx, cy, 0, 0); 132 133 gPaintI.setColor(m_paint, 0xFF0000FF); 134 gCanvasI.drawPath(canvas, path, m_paint); 135 136 ANPRectF bounds; 137 memset(&bounds, 0, sizeof(bounds)); 138 gPathI.getBounds(path, &bounds); 139 gPathI.deletePath(path); 140 } 141 142 // draw the oval 143 inval(inst(), 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(inst(), m_oval, true); // inval the new 149 gPaintI.setColor(m_paint, 0xFFFF0000); 150 gCanvasI.drawOval(canvas, &m_oval, m_paint); 151 152 // update the coordinates of the oval 153 bounce(&m_x, &m_dx, obj->window->width - OW); 154 bounce(&m_y, &m_dy, obj->window->height - OH); 155 156 // delete the canvas 157 gCanvasI.deleteCanvas(canvas); 158 } 159 160 void BallAnimation::showEntirePluginOnScreen() { 161 NPP instance = this->inst(); 162 PluginObject *obj = (PluginObject*) instance->pdata; 163 NPWindow *window = obj->window; 164 165 ANPRectI visibleRects[1]; 166 167 visibleRects[0].left = 0; 168 visibleRects[0].top = 0; 169 visibleRects[0].right = window->width; 170 visibleRects[0].bottom = window->height; 171 172 gWindowI.setVisibleRects(instance, visibleRects, 1); 173 gWindowI.clearVisibleRects(instance); 174 } 175 176 int16 BallAnimation::handleEvent(const ANPEvent* evt) { 177 NPP instance = this->inst(); 178 179 switch (evt->eventType) { 180 case kDraw_ANPEventType: 181 switch (evt->data.draw.model) { 182 case kBitmap_ANPDrawingModel: 183 drawPlugin(evt->data.draw.data.bitmap, evt->data.draw.clip); 184 return 1; 185 default: 186 break; // unknown drawing model 187 } 188 case kTouch_ANPEventType: 189 if (kDown_ANPTouchAction == evt->data.touch.action) { 190 showEntirePluginOnScreen(); 191 } 192 return 1; 193 default: 194 break; 195 } 196 return 0; // unknown or unhandled event 197 } 198