blob: e478897d09d8c3502431c34b1249d6366838c9a9 [file] [log] [blame]
Derek Sollenberger4fb83e62009-07-27 16:40:13 -04001/*
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
32extern NPNetscapeFuncs* browser;
33extern ANPLogInterfaceV0 gLogI;
34extern ANPCanvasInterfaceV0 gCanvasI;
35extern ANPPaintInterfaceV0 gPaintI;
Derek Sollenbergerb6f5cd22009-07-28 14:09:50 -040036extern ANPPathInterfaceV0 gPathI;
Derek Sollenberger4fb83e62009-07-27 16:40:13 -040037extern ANPSurfaceInterfaceV0 gSurfaceI;
Derek Sollenbergerd53b56d2010-01-11 12:31:49 -050038extern ANPSystemInterfaceV0 gSystemI;
Derek Sollenberger4fb83e62009-07-27 16:40:13 -040039extern ANPTypefaceInterfaceV0 gTypefaceI;
40
41///////////////////////////////////////////////////////////////////////////////
42
Derek Sollenberger08581f12009-09-08 18:36:29 -040043PaintPlugin::PaintPlugin(NPP inst) : SurfaceSubPlugin(inst) {
Derek Sollenberger4fb83e62009-07-27 16:40:13 -040044
Derek Sollenberger4fb83e62009-07-27 16:40:13 -040045 m_isTouchActive = false;
Derek Sollenbergerb6f5cd22009-07-28 14:09:50 -040046 m_isTouchCurrentInput = true;
47 m_activePaintColor = s_redColor;
Derek Sollenberger4fb83e62009-07-27 16:40:13 -040048
49 memset(&m_drawingSurface, 0, sizeof(m_drawingSurface));
50 memset(&m_inputToggle, 0, sizeof(m_inputToggle));
51 memset(&m_colorToggle, 0, sizeof(m_colorToggle));
52 memset(&m_clearSurface, 0, sizeof(m_clearSurface));
53
54 // initialize the drawing surface
Derek Sollenberger08581f12009-09-08 18:36:29 -040055 m_surface = NULL;
Derek Sollenberger4fb83e62009-07-27 16:40:13 -040056
Derek Sollenbergerb6f5cd22009-07-28 14:09:50 -040057 // initialize the path
58 m_touchPath = gPathI.newPath();
59 if(!m_touchPath)
Derek Sollenbergere62ce172009-11-30 11:52:06 -050060 gLogI.log(kError_ANPLogType, "----%p Unable to create the touch path", inst);
Derek Sollenbergerb6f5cd22009-07-28 14:09:50 -040061
62 // initialize the paint colors
Derek Sollenberger4fb83e62009-07-27 16:40:13 -040063 m_paintSurface = gPaintI.newPaint();
64 gPaintI.setFlags(m_paintSurface, gPaintI.getFlags(m_paintSurface) | kAntiAlias_ANPPaintFlag);
65 gPaintI.setColor(m_paintSurface, 0xFFC0C0C0);
66 gPaintI.setTextSize(m_paintSurface, 18);
67
68 m_paintButton = gPaintI.newPaint();
69 gPaintI.setFlags(m_paintButton, gPaintI.getFlags(m_paintButton) | kAntiAlias_ANPPaintFlag);
70 gPaintI.setColor(m_paintButton, 0xFFA8A8A8);
71
Derek Sollenbergerb6f5cd22009-07-28 14:09:50 -040072 // initialize the typeface (set the colors)
Derek Sollenberger4fb83e62009-07-27 16:40:13 -040073 ANPTypeface* tf = gTypefaceI.createFromName("serif", kItalic_ANPTypefaceStyle);
74 gPaintI.setTypeface(m_paintSurface, tf);
Derek Sollenberger4fb83e62009-07-27 16:40:13 -040075 gTypefaceI.unref(tf);
76
Derek Sollenberger4fb83e62009-07-27 16:40:13 -040077 //register for touch events
78 ANPEventFlags flags = kTouch_ANPEventFlag;
79 NPError err = browser->setvalue(inst, kAcceptEvents_ANPSetValue, &flags);
80 if (err != NPERR_NO_ERROR) {
Derek Sollenbergere62ce172009-11-30 11:52:06 -050081 gLogI.log(kError_ANPLogType, "Error selecting input events.");
Derek Sollenberger4fb83e62009-07-27 16:40:13 -040082 }
83}
84
85PaintPlugin::~PaintPlugin() {
Derek Sollenbergerb6f5cd22009-07-28 14:09:50 -040086 gPathI.deletePath(m_touchPath);
Derek Sollenberger4fb83e62009-07-27 16:40:13 -040087 gPaintI.deletePaint(m_paintSurface);
88 gPaintI.deletePaint(m_paintButton);
Derek Sollenberger4fb83e62009-07-27 16:40:13 -040089
Derek Sollenbergerd53b56d2010-01-11 12:31:49 -050090 setContext(NULL);
91 destroySurface();
Derek Sollenberger4fb83e62009-07-27 16:40:13 -040092}
93
94ANPCanvas* PaintPlugin::getCanvas(ANPRectI* dirtyRect) {
95
96 ANPBitmap bitmap;
Derek Sollenberger08581f12009-09-08 18:36:29 -040097 JNIEnv* env = NULL;
Derek Sollenbergerb8947ee2009-10-05 14:40:18 -040098 if (!m_surface || gVM->GetEnv((void**) &env, JNI_VERSION_1_4) != JNI_OK ||
Derek Sollenberger08581f12009-09-08 18:36:29 -040099 !gSurfaceI.lock(env, m_surface, &bitmap, dirtyRect)) {
100 return NULL;
101 }
Derek Sollenbergerb6f5cd22009-07-28 14:09:50 -0400102
103 ANPCanvas* canvas = gCanvasI.newCanvas(&bitmap);
104
105 // clip the canvas to the dirty rect b/c the surface is only required to
106 // copy a minimum of the dirty rect and may copy more. The clipped canvas
107 // however will never write to pixels outside of the clipped area.
108 if (dirtyRect) {
109 ANPRectF clipR;
110 clipR.left = dirtyRect->left;
111 clipR.top = dirtyRect->top;
112 clipR.right = dirtyRect->right;
113 clipR.bottom = dirtyRect->bottom;
114 gCanvasI.clipRect(canvas, &clipR);
115 }
116
117 return canvas;
Derek Sollenberger4fb83e62009-07-27 16:40:13 -0400118}
119
120ANPCanvas* PaintPlugin::getCanvas(ANPRectF* dirtyRect) {
121
122 ANPRectI newRect;
123 newRect.left = (int) dirtyRect->left;
124 newRect.top = (int) dirtyRect->top;
125 newRect.right = (int) dirtyRect->right;
126 newRect.bottom = (int) dirtyRect->bottom;
127
128 return getCanvas(&newRect);
129}
130
131void PaintPlugin::releaseCanvas(ANPCanvas* canvas) {
Derek Sollenberger08581f12009-09-08 18:36:29 -0400132 JNIEnv* env = NULL;
Derek Sollenbergerb8947ee2009-10-05 14:40:18 -0400133 if (m_surface && gVM->GetEnv((void**) &env, JNI_VERSION_1_4) == JNI_OK) {
Derek Sollenberger08581f12009-09-08 18:36:29 -0400134 gSurfaceI.unlock(env, m_surface);
135 }
Derek Sollenberger4fb83e62009-07-27 16:40:13 -0400136 gCanvasI.deleteCanvas(canvas);
137}
138
139void PaintPlugin::drawCleanPlugin(ANPCanvas* canvas) {
140 NPP instance = this->inst();
141 PluginObject *obj = (PluginObject*) instance->pdata;
142
143 // if no canvas get a locked canvas
144 if (!canvas)
145 canvas = getCanvas();
146
147 if (!canvas)
148 return;
149
150 const float buttonWidth = 60;
151 const float buttonHeight = 30;
152 const int W = obj->window->width;
153 const int H = obj->window->height;
154
155 // color the plugin canvas
156 gCanvasI.drawColor(canvas, 0xFFCDCDCD);
157
158 // get font metrics
159 ANPFontMetrics fontMetrics;
160 gPaintI.getFontMetrics(m_paintSurface, &fontMetrics);
161
162 // draw the input toggle button
163 m_inputToggle.left = 5;
164 m_inputToggle.top = H - buttonHeight - 5;
165 m_inputToggle.right = m_inputToggle.left + buttonWidth;
166 m_inputToggle.bottom = m_inputToggle.top + buttonHeight;
167 gCanvasI.drawRect(canvas, &m_inputToggle, m_paintButton);
Derek Sollenberger4fb83e62009-07-27 16:40:13 -0400168 const char* inputText = m_isTouchCurrentInput ? "Touch" : "Mouse";
169 gCanvasI.drawText(canvas, inputText, strlen(inputText), m_inputToggle.left + 5,
170 m_inputToggle.top - fontMetrics.fTop, m_paintSurface);
171
172 // draw the color selector button
173 m_colorToggle.left = (W/2) - (buttonWidth/2);
174 m_colorToggle.top = H - buttonHeight - 5;
175 m_colorToggle.right = m_colorToggle.left + buttonWidth;
176 m_colorToggle.bottom = m_colorToggle.top + buttonHeight;
177 gCanvasI.drawRect(canvas, &m_colorToggle, m_paintButton);
Derek Sollenberger4fb83e62009-07-27 16:40:13 -0400178 const char* colorText = getColorText();
179 gCanvasI.drawText(canvas, colorText, strlen(colorText), m_colorToggle.left + 5,
180 m_colorToggle.top - fontMetrics.fTop, m_paintSurface);
181
182 // draw the clear canvas button
183 m_clearSurface.left = W - buttonWidth - 5;
184 m_clearSurface.top = H - buttonHeight - 5;
185 m_clearSurface.right = m_clearSurface.left + buttonWidth;
186 m_clearSurface.bottom = m_clearSurface.top + buttonHeight;
187 gCanvasI.drawRect(canvas, &m_clearSurface, m_paintButton);
Derek Sollenberger4fb83e62009-07-27 16:40:13 -0400188 const char* clearText = "Clear";
189 gCanvasI.drawText(canvas, clearText, strlen(clearText), m_clearSurface.left + 5,
190 m_clearSurface.top - fontMetrics.fTop, m_paintSurface);
191
192 // draw the drawing surface box (5 px from the edge)
193 m_drawingSurface.left = 5;
194 m_drawingSurface.top = 5;
195 m_drawingSurface.right = W - 5;
196 m_drawingSurface.bottom = m_colorToggle.top - 5;
197 gCanvasI.drawRect(canvas, &m_drawingSurface, m_paintSurface);
198
199 // release the canvas
200 releaseCanvas(canvas);
201}
202
203const char* PaintPlugin::getColorText() {
204
Derek Sollenbergerb6f5cd22009-07-28 14:09:50 -0400205 if (m_activePaintColor == s_blueColor)
Derek Sollenberger4fb83e62009-07-27 16:40:13 -0400206 return "Blue";
Derek Sollenbergerb6f5cd22009-07-28 14:09:50 -0400207 else if (m_activePaintColor == s_greenColor)
Derek Sollenberger4fb83e62009-07-27 16:40:13 -0400208 return "Green";
209 else
210 return "Red";
211}
212
Derek Sollenbergerd53b56d2010-01-11 12:31:49 -0500213jobject PaintPlugin::getSurface() {
214 if (m_surface) {
215 return m_surface;
216 }
Derek Sollenberger08581f12009-09-08 18:36:29 -0400217
Derek Sollenbergerd53b56d2010-01-11 12:31:49 -0500218 // load the appropriate java class and instantiate it
219 JNIEnv* env = NULL;
220 if (gVM->GetEnv((void**) &env, JNI_VERSION_1_4) != JNI_OK) {
221 gLogI.log(kError_ANPLogType, " ---- getSurface: failed to get env");
222 return NULL;
223 }
Derek Sollenberger08581f12009-09-08 18:36:29 -0400224
Derek Sollenbergerd53b56d2010-01-11 12:31:49 -0500225 const char* className = "com.android.sampleplugin.PaintSurface";
226 jclass paintClass = gSystemI.loadJavaClass(inst(), className);
227
228 if(!paintClass) {
229 gLogI.log(kError_ANPLogType, " ---- getSurface: failed to load class");
230 return NULL;
231 }
232
Derek Sollenberger08581f12009-09-08 18:36:29 -0400233 PluginObject *obj = (PluginObject*) inst()->pdata;
234 const int pW = obj->window->width;
235 const int pH = obj->window->height;
Derek Sollenbergerd53b56d2010-01-11 12:31:49 -0500236
237 jmethodID constructor = env->GetMethodID(paintClass, "<init>", "(Landroid/content/Context;III)V");
238 jobject paintSurface = env->NewObject(paintClass, constructor, m_context, (int)inst(), pW, pH);
239
240 if(!paintSurface) {
241 gLogI.log(kError_ANPLogType, " ---- getSurface: failed to construct object");
242 return NULL;
243 }
244
245 m_surface = env->NewGlobalRef(paintSurface);
246 return m_surface;
Derek Sollenberger08581f12009-09-08 18:36:29 -0400247}
Derek Sollenbergerd53b56d2010-01-11 12:31:49 -0500248
249void PaintPlugin::destroySurface() {
Derek Sollenberger08581f12009-09-08 18:36:29 -0400250 JNIEnv* env = NULL;
Derek Sollenbergerb8947ee2009-10-05 14:40:18 -0400251 if (m_surface && gVM->GetEnv((void**) &env, JNI_VERSION_1_4) == JNI_OK) {
Derek Sollenbergerd53b56d2010-01-11 12:31:49 -0500252
253 // detach the native code from the object
254 jclass javaClass = env->GetObjectClass(m_surface);
255 jmethodID invalMethod = env->GetMethodID(javaClass, "invalidateNPP", "()V");
256 env->CallVoidMethod(m_surface, invalMethod);
257
Derek Sollenberger08581f12009-09-08 18:36:29 -0400258 env->DeleteGlobalRef(m_surface);
259 m_surface = NULL;
260 }
261}
262
Derek Sollenberger4fb83e62009-07-27 16:40:13 -0400263int16 PaintPlugin::handleEvent(const ANPEvent* evt) {
Derek Sollenberger4fb83e62009-07-27 16:40:13 -0400264 switch (evt->eventType) {
Derek Sollenberger4fb83e62009-07-27 16:40:13 -0400265 case kTouch_ANPEventType: {
Derek Sollenbergerb6f5cd22009-07-28 14:09:50 -0400266 float x = (float) evt->data.touch.x;
267 float y = (float) evt->data.touch.y;
268 if (kDown_ANPTouchAction == evt->data.touch.action && m_isTouchCurrentInput) {
Derek Sollenberger4fb83e62009-07-27 16:40:13 -0400269
Derek Sollenbergerb6f5cd22009-07-28 14:09:50 -0400270 ANPRectF* rect = validTouch(evt->data.touch.x, evt->data.touch.y);
Derek Sollenberger4fb83e62009-07-27 16:40:13 -0400271 if(rect == &m_drawingSurface) {
272 m_isTouchActive = true;
Derek Sollenbergerb6f5cd22009-07-28 14:09:50 -0400273 gPathI.moveTo(m_touchPath, x, y);
274 paintTouch();
Derek Sollenberger4fb83e62009-07-27 16:40:13 -0400275 return 1;
276 }
277
278 } else if (kMove_ANPTouchAction == evt->data.touch.action && m_isTouchActive) {
Derek Sollenbergerb6f5cd22009-07-28 14:09:50 -0400279 gPathI.lineTo(m_touchPath, x, y);
280 paintTouch();
Derek Sollenberger4fb83e62009-07-27 16:40:13 -0400281 return 1;
282 } else if (kUp_ANPTouchAction == evt->data.touch.action && m_isTouchActive) {
Derek Sollenbergerb6f5cd22009-07-28 14:09:50 -0400283 gPathI.lineTo(m_touchPath, x, y);
284 paintTouch();
Derek Sollenberger4fb83e62009-07-27 16:40:13 -0400285 m_isTouchActive = false;
Derek Sollenbergerb6f5cd22009-07-28 14:09:50 -0400286 gPathI.reset(m_touchPath);
Derek Sollenberger4fb83e62009-07-27 16:40:13 -0400287 return 1;
288 } else if (kCancel_ANPTouchAction == evt->data.touch.action) {
289 m_isTouchActive = false;
Derek Sollenbergerb6f5cd22009-07-28 14:09:50 -0400290 gPathI.reset(m_touchPath);
Derek Sollenberger4fb83e62009-07-27 16:40:13 -0400291 return 1;
292 }
Derek Sollenbergerb6f5cd22009-07-28 14:09:50 -0400293
Derek Sollenberger4fb83e62009-07-27 16:40:13 -0400294 break;
295 }
296 case kMouse_ANPEventType: {
Derek Sollenbergerb6f5cd22009-07-28 14:09:50 -0400297
298 if (m_isTouchActive)
Derek Sollenbergere62ce172009-11-30 11:52:06 -0500299 gLogI.log(kError_ANPLogType, "----%p Received unintended mouse event", inst());
Derek Sollenbergerb6f5cd22009-07-28 14:09:50 -0400300
Derek Sollenberger4fb83e62009-07-27 16:40:13 -0400301 if (kDown_ANPMouseAction == evt->data.mouse.action) {
302 ANPRectF* rect = validTouch(evt->data.mouse.x, evt->data.mouse.y);
303 if (rect == &m_drawingSurface)
Derek Sollenbergerb6f5cd22009-07-28 14:09:50 -0400304 paintMouse(evt->data.mouse.x, evt->data.mouse.y);
Derek Sollenberger4fb83e62009-07-27 16:40:13 -0400305 else if (rect == &m_inputToggle)
306 toggleInputMethod();
307 else if (rect == &m_colorToggle)
308 togglePaintColor();
309 else if (rect == &m_clearSurface)
310 drawCleanPlugin();
311 }
312 return 1;
313 }
Derek Sollenbergerd53b56d2010-01-11 12:31:49 -0500314 case kCustom_ANPEventType: {
315
316 switch (evt->data.other[0]) {
317 case kSurfaceCreated_CustomEvent:
318 gLogI.log(kDebug_ANPLogType, " ---- customEvent: surfaceCreated");
319 drawCleanPlugin();
320 break;
321 case kSurfaceChanged_CustomEvent: {
322 gLogI.log(kDebug_ANPLogType, " ---- customEvent: surfaceChanged");
323
324 int width = evt->data.other[1];
325 int height = evt->data.other[2];
326
327 PluginObject *obj = (PluginObject*) inst()->pdata;
328 const int pW = obj->window->width;
329 const int pH = obj->window->height;
330 // compare to the plugin's surface dimensions
331 if (pW != width || pH != height)
332 gLogI.log(kError_ANPLogType,
333 "----%p Invalid Surface Dimensions (%d,%d):(%d,%d)",
334 inst(), pW, pH, width, height);
335 break;
336 }
337 case kSurfaceDestroyed_CustomEvent:
338 gLogI.log(kDebug_ANPLogType, " ---- customEvent: surfaceDestroyed");
339 break;
340 }
341 break; // end KCustom_ANPEventType
342 }
Derek Sollenberger4fb83e62009-07-27 16:40:13 -0400343 default:
344 break;
345 }
346 return 0; // unknown or unhandled event
347}
348
349ANPRectF* PaintPlugin::validTouch(int x, int y) {
350
351 //convert to float
352 float fx = (int) x;
353 float fy = (int) y;
354
355 if (fx > m_drawingSurface.left && fx < m_drawingSurface.right && fy > m_drawingSurface.top && fy < m_drawingSurface.bottom)
356 return &m_drawingSurface;
357 else if (fx > m_inputToggle.left && fx < m_inputToggle.right && fy > m_inputToggle.top && fy < m_inputToggle.bottom)
358 return &m_inputToggle;
359 else if (fx > m_colorToggle.left && fx < m_colorToggle.right && fy > m_colorToggle.top && fy < m_colorToggle.bottom)
360 return &m_colorToggle;
361 else if (fx > m_clearSurface.left && fx < m_clearSurface.right && fy > m_clearSurface.top && fy < m_clearSurface.bottom)
362 return &m_clearSurface;
363 else
364 return NULL;
365}
366
367void PaintPlugin::toggleInputMethod() {
368 m_isTouchCurrentInput = !m_isTouchCurrentInput;
369
370 // lock only the input toggle and redraw the canvas
Derek Sollenbergerb6f5cd22009-07-28 14:09:50 -0400371 ANPCanvas* lockedCanvas = getCanvas(&m_inputToggle);
Derek Sollenberger4fb83e62009-07-27 16:40:13 -0400372 drawCleanPlugin(lockedCanvas);
373}
374
375void PaintPlugin::togglePaintColor() {
Derek Sollenbergerb6f5cd22009-07-28 14:09:50 -0400376 if (m_activePaintColor == s_blueColor)
377 m_activePaintColor = s_redColor;
378 else if (m_activePaintColor == s_greenColor)
379 m_activePaintColor = s_blueColor;
Derek Sollenberger4fb83e62009-07-27 16:40:13 -0400380 else
Derek Sollenbergerb6f5cd22009-07-28 14:09:50 -0400381 m_activePaintColor = s_greenColor;
Derek Sollenberger4fb83e62009-07-27 16:40:13 -0400382
383 // lock only the color toggle and redraw the canvas
384 ANPCanvas* lockedCanvas = getCanvas(&m_colorToggle);
385 drawCleanPlugin(lockedCanvas);
386}
387
Derek Sollenbergerb6f5cd22009-07-28 14:09:50 -0400388void PaintPlugin::paintMouse(int x, int y) {
389 //TODO do not paint outside the drawing surface
Derek Sollenberger4fb83e62009-07-27 16:40:13 -0400390
Derek Sollenbergerb6f5cd22009-07-28 14:09:50 -0400391 //create the paint color
392 ANPPaint* fillPaint = gPaintI.newPaint();
393 gPaintI.setFlags(fillPaint, gPaintI.getFlags(fillPaint) | kAntiAlias_ANPPaintFlag);
394 gPaintI.setStyle(fillPaint, kFill_ANPPaintStyle);
395 gPaintI.setColor(fillPaint, m_activePaintColor);
Derek Sollenberger4fb83e62009-07-27 16:40:13 -0400396
397 // handle the simple "mouse" paint (draw a point)
Derek Sollenbergerb6f5cd22009-07-28 14:09:50 -0400398 ANPRectF point;
399 point.left = (float) x-3;
400 point.top = (float) y-3;
401 point.right = (float) x+3;
402 point.bottom = (float) y+3;
Derek Sollenberger4fb83e62009-07-27 16:40:13 -0400403
Derek Sollenbergerb6f5cd22009-07-28 14:09:50 -0400404 // get a canvas that is only locked around the point and draw it
405 ANPCanvas* canvas = getCanvas(&point);
406 gCanvasI.drawOval(canvas, &point, fillPaint);
Derek Sollenberger4fb83e62009-07-27 16:40:13 -0400407
Derek Sollenbergerb6f5cd22009-07-28 14:09:50 -0400408 // clean up
409 releaseCanvas(canvas);
410 gPaintI.deletePaint(fillPaint);
411}
Derek Sollenberger4fb83e62009-07-27 16:40:13 -0400412
Derek Sollenbergerb6f5cd22009-07-28 14:09:50 -0400413void PaintPlugin::paintTouch() {
414 //TODO do not paint outside the drawing surface
415
416 //create the paint color
417 ANPPaint* strokePaint = gPaintI.newPaint();
418 gPaintI.setFlags(strokePaint, gPaintI.getFlags(strokePaint) | kAntiAlias_ANPPaintFlag);
419 gPaintI.setColor(strokePaint, m_activePaintColor);
420 gPaintI.setStyle(strokePaint, kStroke_ANPPaintStyle);
421 gPaintI.setStrokeWidth(strokePaint, 6.0);
422 gPaintI.setStrokeCap(strokePaint, kRound_ANPPaintCap);
423 gPaintI.setStrokeJoin(strokePaint, kRound_ANPPaintJoin);
424
425 // handle the complex "touch" paint (draw a line)
426 ANPRectF bounds;
427 gPathI.getBounds(m_touchPath, &bounds);
428
429 // get a canvas that is only locked around the point and draw the path
430 ANPCanvas* canvas = getCanvas(&bounds);
431 gCanvasI.drawPath(canvas, m_touchPath, strokePaint);
432
433 // clean up
434 releaseCanvas(canvas);
435 gPaintI.deletePaint(strokePaint);
Derek Sollenberger4fb83e62009-07-27 16:40:13 -0400436}