Derek Sollenberger | 4fb83e6 | 2009-07-27 16:40:13 -0400 | [diff] [blame] | 1 | /* |
| 2 | * Copyright 2009, 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 "PaintPlugin.h" |
| 27 | |
| 28 | #include <fcntl.h> |
| 29 | #include <math.h> |
| 30 | #include <string.h> |
| 31 | |
| 32 | extern NPNetscapeFuncs* browser; |
| 33 | extern ANPLogInterfaceV0 gLogI; |
| 34 | extern ANPCanvasInterfaceV0 gCanvasI; |
| 35 | extern ANPPaintInterfaceV0 gPaintI; |
Derek Sollenberger | b6f5cd2 | 2009-07-28 14:09:50 -0400 | [diff] [blame^] | 36 | extern ANPPathInterfaceV0 gPathI; |
Derek Sollenberger | 4fb83e6 | 2009-07-27 16:40:13 -0400 | [diff] [blame] | 37 | extern ANPSurfaceInterfaceV0 gSurfaceI; |
| 38 | extern ANPTypefaceInterfaceV0 gTypefaceI; |
| 39 | |
| 40 | /////////////////////////////////////////////////////////////////////////////// |
| 41 | |
| 42 | PaintPlugin::PaintPlugin(NPP inst) : SubPlugin(inst) { |
| 43 | |
Derek Sollenberger | 4fb83e6 | 2009-07-27 16:40:13 -0400 | [diff] [blame] | 44 | m_isTouchActive = false; |
Derek Sollenberger | b6f5cd2 | 2009-07-28 14:09:50 -0400 | [diff] [blame^] | 45 | m_isTouchCurrentInput = true; |
| 46 | m_activePaintColor = s_redColor; |
Derek Sollenberger | 4fb83e6 | 2009-07-27 16:40:13 -0400 | [diff] [blame] | 47 | |
| 48 | memset(&m_drawingSurface, 0, sizeof(m_drawingSurface)); |
| 49 | memset(&m_inputToggle, 0, sizeof(m_inputToggle)); |
| 50 | memset(&m_colorToggle, 0, sizeof(m_colorToggle)); |
| 51 | memset(&m_clearSurface, 0, sizeof(m_clearSurface)); |
| 52 | |
| 53 | // initialize the drawing surface |
| 54 | m_surfaceReady = false; |
| 55 | m_surface = gSurfaceI.newSurface(inst, kRGBA_ANPSurfaceType); |
| 56 | if(!m_surface) |
| 57 | gLogI.log(inst, kError_ANPLogType, "----%p Unable to create RGBA surface", inst); |
| 58 | |
Derek Sollenberger | b6f5cd2 | 2009-07-28 14:09:50 -0400 | [diff] [blame^] | 59 | // initialize the path |
| 60 | m_touchPath = gPathI.newPath(); |
| 61 | if(!m_touchPath) |
| 62 | gLogI.log(inst, kError_ANPLogType, "----%p Unable to create the touch path", inst); |
| 63 | |
| 64 | // initialize the paint colors |
Derek Sollenberger | 4fb83e6 | 2009-07-27 16:40:13 -0400 | [diff] [blame] | 65 | m_paintSurface = gPaintI.newPaint(); |
| 66 | gPaintI.setFlags(m_paintSurface, gPaintI.getFlags(m_paintSurface) | kAntiAlias_ANPPaintFlag); |
| 67 | gPaintI.setColor(m_paintSurface, 0xFFC0C0C0); |
| 68 | gPaintI.setTextSize(m_paintSurface, 18); |
| 69 | |
| 70 | m_paintButton = gPaintI.newPaint(); |
| 71 | gPaintI.setFlags(m_paintButton, gPaintI.getFlags(m_paintButton) | kAntiAlias_ANPPaintFlag); |
| 72 | gPaintI.setColor(m_paintButton, 0xFFA8A8A8); |
| 73 | |
Derek Sollenberger | b6f5cd2 | 2009-07-28 14:09:50 -0400 | [diff] [blame^] | 74 | // initialize the typeface (set the colors) |
Derek Sollenberger | 4fb83e6 | 2009-07-27 16:40:13 -0400 | [diff] [blame] | 75 | ANPTypeface* tf = gTypefaceI.createFromName("serif", kItalic_ANPTypefaceStyle); |
| 76 | gPaintI.setTypeface(m_paintSurface, tf); |
Derek Sollenberger | 4fb83e6 | 2009-07-27 16:40:13 -0400 | [diff] [blame] | 77 | gTypefaceI.unref(tf); |
| 78 | |
Derek Sollenberger | 4fb83e6 | 2009-07-27 16:40:13 -0400 | [diff] [blame] | 79 | //register for touch events |
| 80 | ANPEventFlags flags = kTouch_ANPEventFlag; |
| 81 | NPError err = browser->setvalue(inst, kAcceptEvents_ANPSetValue, &flags); |
| 82 | if (err != NPERR_NO_ERROR) { |
| 83 | gLogI.log(inst, kError_ANPLogType, "Error selecting input events."); |
| 84 | } |
| 85 | } |
| 86 | |
| 87 | PaintPlugin::~PaintPlugin() { |
Derek Sollenberger | b6f5cd2 | 2009-07-28 14:09:50 -0400 | [diff] [blame^] | 88 | gSurfaceI.deleteSurface(m_surface); |
| 89 | gPathI.deletePath(m_touchPath); |
Derek Sollenberger | 4fb83e6 | 2009-07-27 16:40:13 -0400 | [diff] [blame] | 90 | gPaintI.deletePaint(m_paintSurface); |
| 91 | gPaintI.deletePaint(m_paintButton); |
Derek Sollenberger | 4fb83e6 | 2009-07-27 16:40:13 -0400 | [diff] [blame] | 92 | } |
| 93 | |
| 94 | bool PaintPlugin::supportsDrawingModel(ANPDrawingModel model) { |
| 95 | return (model == kSurface_ANPDrawingModel); |
| 96 | } |
| 97 | |
| 98 | ANPCanvas* PaintPlugin::getCanvas(ANPRectI* dirtyRect) { |
| 99 | |
| 100 | ANPBitmap bitmap; |
| 101 | if (!m_surfaceReady || !gSurfaceI.lock(m_surface, &bitmap, dirtyRect)) |
| 102 | return NULL; |
Derek Sollenberger | b6f5cd2 | 2009-07-28 14:09:50 -0400 | [diff] [blame^] | 103 | |
| 104 | ANPCanvas* canvas = gCanvasI.newCanvas(&bitmap); |
| 105 | |
| 106 | // clip the canvas to the dirty rect b/c the surface is only required to |
| 107 | // copy a minimum of the dirty rect and may copy more. The clipped canvas |
| 108 | // however will never write to pixels outside of the clipped area. |
| 109 | if (dirtyRect) { |
| 110 | ANPRectF clipR; |
| 111 | clipR.left = dirtyRect->left; |
| 112 | clipR.top = dirtyRect->top; |
| 113 | clipR.right = dirtyRect->right; |
| 114 | clipR.bottom = dirtyRect->bottom; |
| 115 | gCanvasI.clipRect(canvas, &clipR); |
| 116 | } |
| 117 | |
| 118 | return canvas; |
Derek Sollenberger | 4fb83e6 | 2009-07-27 16:40:13 -0400 | [diff] [blame] | 119 | } |
| 120 | |
| 121 | ANPCanvas* PaintPlugin::getCanvas(ANPRectF* dirtyRect) { |
| 122 | |
| 123 | ANPRectI newRect; |
| 124 | newRect.left = (int) dirtyRect->left; |
| 125 | newRect.top = (int) dirtyRect->top; |
| 126 | newRect.right = (int) dirtyRect->right; |
| 127 | newRect.bottom = (int) dirtyRect->bottom; |
| 128 | |
| 129 | return getCanvas(&newRect); |
| 130 | } |
| 131 | |
| 132 | void PaintPlugin::releaseCanvas(ANPCanvas* canvas) { |
| 133 | gSurfaceI.unlock(m_surface); |
| 134 | gCanvasI.deleteCanvas(canvas); |
| 135 | } |
| 136 | |
| 137 | void PaintPlugin::drawCleanPlugin(ANPCanvas* canvas) { |
| 138 | NPP instance = this->inst(); |
| 139 | PluginObject *obj = (PluginObject*) instance->pdata; |
| 140 | |
| 141 | // if no canvas get a locked canvas |
| 142 | if (!canvas) |
| 143 | canvas = getCanvas(); |
| 144 | |
| 145 | if (!canvas) |
| 146 | return; |
| 147 | |
| 148 | const float buttonWidth = 60; |
| 149 | const float buttonHeight = 30; |
| 150 | const int W = obj->window->width; |
| 151 | const int H = obj->window->height; |
| 152 | |
| 153 | // color the plugin canvas |
| 154 | gCanvasI.drawColor(canvas, 0xFFCDCDCD); |
| 155 | |
| 156 | // get font metrics |
| 157 | ANPFontMetrics fontMetrics; |
| 158 | gPaintI.getFontMetrics(m_paintSurface, &fontMetrics); |
| 159 | |
| 160 | // draw the input toggle button |
| 161 | m_inputToggle.left = 5; |
| 162 | m_inputToggle.top = H - buttonHeight - 5; |
| 163 | m_inputToggle.right = m_inputToggle.left + buttonWidth; |
| 164 | m_inputToggle.bottom = m_inputToggle.top + buttonHeight; |
| 165 | gCanvasI.drawRect(canvas, &m_inputToggle, m_paintButton); |
Derek Sollenberger | 4fb83e6 | 2009-07-27 16:40:13 -0400 | [diff] [blame] | 166 | const char* inputText = m_isTouchCurrentInput ? "Touch" : "Mouse"; |
| 167 | gCanvasI.drawText(canvas, inputText, strlen(inputText), m_inputToggle.left + 5, |
| 168 | m_inputToggle.top - fontMetrics.fTop, m_paintSurface); |
| 169 | |
| 170 | // draw the color selector button |
| 171 | m_colorToggle.left = (W/2) - (buttonWidth/2); |
| 172 | m_colorToggle.top = H - buttonHeight - 5; |
| 173 | m_colorToggle.right = m_colorToggle.left + buttonWidth; |
| 174 | m_colorToggle.bottom = m_colorToggle.top + buttonHeight; |
| 175 | gCanvasI.drawRect(canvas, &m_colorToggle, m_paintButton); |
Derek Sollenberger | 4fb83e6 | 2009-07-27 16:40:13 -0400 | [diff] [blame] | 176 | const char* colorText = getColorText(); |
| 177 | gCanvasI.drawText(canvas, colorText, strlen(colorText), m_colorToggle.left + 5, |
| 178 | m_colorToggle.top - fontMetrics.fTop, m_paintSurface); |
| 179 | |
| 180 | // draw the clear canvas button |
| 181 | m_clearSurface.left = W - buttonWidth - 5; |
| 182 | m_clearSurface.top = H - buttonHeight - 5; |
| 183 | m_clearSurface.right = m_clearSurface.left + buttonWidth; |
| 184 | m_clearSurface.bottom = m_clearSurface.top + buttonHeight; |
| 185 | gCanvasI.drawRect(canvas, &m_clearSurface, m_paintButton); |
Derek Sollenberger | 4fb83e6 | 2009-07-27 16:40:13 -0400 | [diff] [blame] | 186 | const char* clearText = "Clear"; |
| 187 | gCanvasI.drawText(canvas, clearText, strlen(clearText), m_clearSurface.left + 5, |
| 188 | m_clearSurface.top - fontMetrics.fTop, m_paintSurface); |
| 189 | |
| 190 | // draw the drawing surface box (5 px from the edge) |
| 191 | m_drawingSurface.left = 5; |
| 192 | m_drawingSurface.top = 5; |
| 193 | m_drawingSurface.right = W - 5; |
| 194 | m_drawingSurface.bottom = m_colorToggle.top - 5; |
| 195 | gCanvasI.drawRect(canvas, &m_drawingSurface, m_paintSurface); |
| 196 | |
| 197 | // release the canvas |
| 198 | releaseCanvas(canvas); |
| 199 | } |
| 200 | |
| 201 | const char* PaintPlugin::getColorText() { |
| 202 | |
Derek Sollenberger | b6f5cd2 | 2009-07-28 14:09:50 -0400 | [diff] [blame^] | 203 | if (m_activePaintColor == s_blueColor) |
Derek Sollenberger | 4fb83e6 | 2009-07-27 16:40:13 -0400 | [diff] [blame] | 204 | return "Blue"; |
Derek Sollenberger | b6f5cd2 | 2009-07-28 14:09:50 -0400 | [diff] [blame^] | 205 | else if (m_activePaintColor == s_greenColor) |
Derek Sollenberger | 4fb83e6 | 2009-07-27 16:40:13 -0400 | [diff] [blame] | 206 | return "Green"; |
| 207 | else |
| 208 | return "Red"; |
| 209 | } |
| 210 | |
| 211 | int16 PaintPlugin::handleEvent(const ANPEvent* evt) { |
Derek Sollenberger | 4fb83e6 | 2009-07-27 16:40:13 -0400 | [diff] [blame] | 212 | switch (evt->eventType) { |
| 213 | case kSurface_ANPEventType: |
| 214 | switch (evt->data.surface.action) { |
| 215 | case kCreated_ANPSurfaceAction: |
| 216 | m_surfaceReady = true; |
| 217 | drawCleanPlugin(); |
| 218 | return 1; |
| 219 | case kDestroyed_ANPSurfaceAction: |
| 220 | m_surfaceReady = false; |
| 221 | return 1; |
| 222 | } |
| 223 | break; |
| 224 | |
| 225 | case kTouch_ANPEventType: { |
Derek Sollenberger | b6f5cd2 | 2009-07-28 14:09:50 -0400 | [diff] [blame^] | 226 | float x = (float) evt->data.touch.x; |
| 227 | float y = (float) evt->data.touch.y; |
| 228 | if (kDown_ANPTouchAction == evt->data.touch.action && m_isTouchCurrentInput) { |
Derek Sollenberger | 4fb83e6 | 2009-07-27 16:40:13 -0400 | [diff] [blame] | 229 | |
Derek Sollenberger | b6f5cd2 | 2009-07-28 14:09:50 -0400 | [diff] [blame^] | 230 | ANPRectF* rect = validTouch(evt->data.touch.x, evt->data.touch.y); |
Derek Sollenberger | 4fb83e6 | 2009-07-27 16:40:13 -0400 | [diff] [blame] | 231 | if(rect == &m_drawingSurface) { |
| 232 | m_isTouchActive = true; |
Derek Sollenberger | b6f5cd2 | 2009-07-28 14:09:50 -0400 | [diff] [blame^] | 233 | gPathI.moveTo(m_touchPath, x, y); |
| 234 | paintTouch(); |
Derek Sollenberger | 4fb83e6 | 2009-07-27 16:40:13 -0400 | [diff] [blame] | 235 | return 1; |
| 236 | } |
| 237 | |
| 238 | } else if (kMove_ANPTouchAction == evt->data.touch.action && m_isTouchActive) { |
Derek Sollenberger | b6f5cd2 | 2009-07-28 14:09:50 -0400 | [diff] [blame^] | 239 | gPathI.lineTo(m_touchPath, x, y); |
| 240 | paintTouch(); |
Derek Sollenberger | 4fb83e6 | 2009-07-27 16:40:13 -0400 | [diff] [blame] | 241 | return 1; |
| 242 | } else if (kUp_ANPTouchAction == evt->data.touch.action && m_isTouchActive) { |
Derek Sollenberger | b6f5cd2 | 2009-07-28 14:09:50 -0400 | [diff] [blame^] | 243 | gPathI.lineTo(m_touchPath, x, y); |
| 244 | paintTouch(); |
Derek Sollenberger | 4fb83e6 | 2009-07-27 16:40:13 -0400 | [diff] [blame] | 245 | m_isTouchActive = false; |
Derek Sollenberger | b6f5cd2 | 2009-07-28 14:09:50 -0400 | [diff] [blame^] | 246 | gPathI.reset(m_touchPath); |
Derek Sollenberger | 4fb83e6 | 2009-07-27 16:40:13 -0400 | [diff] [blame] | 247 | return 1; |
| 248 | } else if (kCancel_ANPTouchAction == evt->data.touch.action) { |
| 249 | m_isTouchActive = false; |
Derek Sollenberger | b6f5cd2 | 2009-07-28 14:09:50 -0400 | [diff] [blame^] | 250 | gPathI.reset(m_touchPath); |
Derek Sollenberger | 4fb83e6 | 2009-07-27 16:40:13 -0400 | [diff] [blame] | 251 | return 1; |
| 252 | } |
Derek Sollenberger | b6f5cd2 | 2009-07-28 14:09:50 -0400 | [diff] [blame^] | 253 | |
Derek Sollenberger | 4fb83e6 | 2009-07-27 16:40:13 -0400 | [diff] [blame] | 254 | break; |
| 255 | } |
| 256 | case kMouse_ANPEventType: { |
Derek Sollenberger | b6f5cd2 | 2009-07-28 14:09:50 -0400 | [diff] [blame^] | 257 | |
| 258 | if (m_isTouchActive) |
| 259 | gLogI.log(inst(), kError_ANPLogType, "----%p Received unintended mouse event", inst()); |
| 260 | |
Derek Sollenberger | 4fb83e6 | 2009-07-27 16:40:13 -0400 | [diff] [blame] | 261 | if (kDown_ANPMouseAction == evt->data.mouse.action) { |
| 262 | ANPRectF* rect = validTouch(evt->data.mouse.x, evt->data.mouse.y); |
| 263 | if (rect == &m_drawingSurface) |
Derek Sollenberger | b6f5cd2 | 2009-07-28 14:09:50 -0400 | [diff] [blame^] | 264 | paintMouse(evt->data.mouse.x, evt->data.mouse.y); |
Derek Sollenberger | 4fb83e6 | 2009-07-27 16:40:13 -0400 | [diff] [blame] | 265 | else if (rect == &m_inputToggle) |
| 266 | toggleInputMethod(); |
| 267 | else if (rect == &m_colorToggle) |
| 268 | togglePaintColor(); |
| 269 | else if (rect == &m_clearSurface) |
| 270 | drawCleanPlugin(); |
| 271 | } |
| 272 | return 1; |
| 273 | } |
| 274 | default: |
| 275 | break; |
| 276 | } |
| 277 | return 0; // unknown or unhandled event |
| 278 | } |
| 279 | |
| 280 | ANPRectF* PaintPlugin::validTouch(int x, int y) { |
| 281 | |
| 282 | //convert to float |
| 283 | float fx = (int) x; |
| 284 | float fy = (int) y; |
| 285 | |
| 286 | if (fx > m_drawingSurface.left && fx < m_drawingSurface.right && fy > m_drawingSurface.top && fy < m_drawingSurface.bottom) |
| 287 | return &m_drawingSurface; |
| 288 | else if (fx > m_inputToggle.left && fx < m_inputToggle.right && fy > m_inputToggle.top && fy < m_inputToggle.bottom) |
| 289 | return &m_inputToggle; |
| 290 | else if (fx > m_colorToggle.left && fx < m_colorToggle.right && fy > m_colorToggle.top && fy < m_colorToggle.bottom) |
| 291 | return &m_colorToggle; |
| 292 | else if (fx > m_clearSurface.left && fx < m_clearSurface.right && fy > m_clearSurface.top && fy < m_clearSurface.bottom) |
| 293 | return &m_clearSurface; |
| 294 | else |
| 295 | return NULL; |
| 296 | } |
| 297 | |
| 298 | void PaintPlugin::toggleInputMethod() { |
| 299 | m_isTouchCurrentInput = !m_isTouchCurrentInput; |
| 300 | |
| 301 | // lock only the input toggle and redraw the canvas |
Derek Sollenberger | b6f5cd2 | 2009-07-28 14:09:50 -0400 | [diff] [blame^] | 302 | ANPCanvas* lockedCanvas = getCanvas(&m_inputToggle); |
Derek Sollenberger | 4fb83e6 | 2009-07-27 16:40:13 -0400 | [diff] [blame] | 303 | drawCleanPlugin(lockedCanvas); |
| 304 | } |
| 305 | |
| 306 | void PaintPlugin::togglePaintColor() { |
Derek Sollenberger | b6f5cd2 | 2009-07-28 14:09:50 -0400 | [diff] [blame^] | 307 | if (m_activePaintColor == s_blueColor) |
| 308 | m_activePaintColor = s_redColor; |
| 309 | else if (m_activePaintColor == s_greenColor) |
| 310 | m_activePaintColor = s_blueColor; |
Derek Sollenberger | 4fb83e6 | 2009-07-27 16:40:13 -0400 | [diff] [blame] | 311 | else |
Derek Sollenberger | b6f5cd2 | 2009-07-28 14:09:50 -0400 | [diff] [blame^] | 312 | m_activePaintColor = s_greenColor; |
Derek Sollenberger | 4fb83e6 | 2009-07-27 16:40:13 -0400 | [diff] [blame] | 313 | |
| 314 | // lock only the color toggle and redraw the canvas |
| 315 | ANPCanvas* lockedCanvas = getCanvas(&m_colorToggle); |
| 316 | drawCleanPlugin(lockedCanvas); |
| 317 | } |
| 318 | |
Derek Sollenberger | b6f5cd2 | 2009-07-28 14:09:50 -0400 | [diff] [blame^] | 319 | void PaintPlugin::paintMouse(int x, int y) { |
| 320 | //TODO do not paint outside the drawing surface |
Derek Sollenberger | 4fb83e6 | 2009-07-27 16:40:13 -0400 | [diff] [blame] | 321 | |
Derek Sollenberger | b6f5cd2 | 2009-07-28 14:09:50 -0400 | [diff] [blame^] | 322 | //create the paint color |
| 323 | ANPPaint* fillPaint = gPaintI.newPaint(); |
| 324 | gPaintI.setFlags(fillPaint, gPaintI.getFlags(fillPaint) | kAntiAlias_ANPPaintFlag); |
| 325 | gPaintI.setStyle(fillPaint, kFill_ANPPaintStyle); |
| 326 | gPaintI.setColor(fillPaint, m_activePaintColor); |
Derek Sollenberger | 4fb83e6 | 2009-07-27 16:40:13 -0400 | [diff] [blame] | 327 | |
| 328 | // handle the simple "mouse" paint (draw a point) |
Derek Sollenberger | b6f5cd2 | 2009-07-28 14:09:50 -0400 | [diff] [blame^] | 329 | ANPRectF point; |
| 330 | point.left = (float) x-3; |
| 331 | point.top = (float) y-3; |
| 332 | point.right = (float) x+3; |
| 333 | point.bottom = (float) y+3; |
Derek Sollenberger | 4fb83e6 | 2009-07-27 16:40:13 -0400 | [diff] [blame] | 334 | |
Derek Sollenberger | b6f5cd2 | 2009-07-28 14:09:50 -0400 | [diff] [blame^] | 335 | // get a canvas that is only locked around the point and draw it |
| 336 | ANPCanvas* canvas = getCanvas(&point); |
| 337 | gCanvasI.drawOval(canvas, &point, fillPaint); |
Derek Sollenberger | 4fb83e6 | 2009-07-27 16:40:13 -0400 | [diff] [blame] | 338 | |
Derek Sollenberger | b6f5cd2 | 2009-07-28 14:09:50 -0400 | [diff] [blame^] | 339 | // clean up |
| 340 | releaseCanvas(canvas); |
| 341 | gPaintI.deletePaint(fillPaint); |
| 342 | } |
Derek Sollenberger | 4fb83e6 | 2009-07-27 16:40:13 -0400 | [diff] [blame] | 343 | |
Derek Sollenberger | b6f5cd2 | 2009-07-28 14:09:50 -0400 | [diff] [blame^] | 344 | void PaintPlugin::paintTouch() { |
| 345 | //TODO do not paint outside the drawing surface |
| 346 | |
| 347 | //create the paint color |
| 348 | ANPPaint* strokePaint = gPaintI.newPaint(); |
| 349 | gPaintI.setFlags(strokePaint, gPaintI.getFlags(strokePaint) | kAntiAlias_ANPPaintFlag); |
| 350 | gPaintI.setColor(strokePaint, m_activePaintColor); |
| 351 | gPaintI.setStyle(strokePaint, kStroke_ANPPaintStyle); |
| 352 | gPaintI.setStrokeWidth(strokePaint, 6.0); |
| 353 | gPaintI.setStrokeCap(strokePaint, kRound_ANPPaintCap); |
| 354 | gPaintI.setStrokeJoin(strokePaint, kRound_ANPPaintJoin); |
| 355 | |
| 356 | // handle the complex "touch" paint (draw a line) |
| 357 | ANPRectF bounds; |
| 358 | gPathI.getBounds(m_touchPath, &bounds); |
| 359 | |
| 360 | // get a canvas that is only locked around the point and draw the path |
| 361 | ANPCanvas* canvas = getCanvas(&bounds); |
| 362 | gCanvasI.drawPath(canvas, m_touchPath, strokePaint); |
| 363 | |
| 364 | // clean up |
| 365 | releaseCanvas(canvas); |
| 366 | gPaintI.deletePaint(strokePaint); |
Derek Sollenberger | 4fb83e6 | 2009-07-27 16:40:13 -0400 | [diff] [blame] | 367 | } |