Home | History | Annotate | Download | only in animation
      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