/[zanavi_public1]/navit/navit/graphics/android/graphics_android.c
ZANavi

Contents of /navit/navit/graphics/android/graphics_android.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 56 - (show annotations) (download)
Sun Mar 19 08:44:36 2017 UTC (7 years, 1 month ago) by zoff99
File MIME type: text/plain
File size: 77067 byte(s)
updates
1 /**
2 * ZANavi, Zoff Android Navigation system.
3 * Copyright (C) 2011-2012 Zoff <zoff@zoff.cc>
4 *
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License
7 * version 2 as published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the
16 * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
17 * Boston, MA 02110-1301, USA.
18 */
19
20 /**
21 * Navit, a modular navigation system.
22 * Copyright (C) 2005-2008 Navit Team
23 *
24 * This program is free software; you can redistribute it and/or
25 * modify it under the terms of the GNU General Public License
26 * version 2 as published by the Free Software Foundation.
27 *
28 * This program is distributed in the hope that it will be useful,
29 * but WITHOUT ANY WARRANTY; without even the implied warranty of
30 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
31 * GNU General Public License for more details.
32 *
33 * You should have received a copy of the GNU General Public License
34 * along with this program; if not, write to the
35 * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
36 * Boston, MA 02110-1301, USA.
37 */
38
39 #include <errno.h>
40
41 #include <unistd.h>
42 #include <stdlib.h>
43 #include <math.h>
44 #include <glib.h>
45 #include "config.h"
46 #include "window.h"
47 #include "point.h"
48 #include "graphics.h"
49 #include "color.h"
50 #include "plugin.h"
51 #include "event.h"
52 #include "debug.h"
53 #include "callback.h"
54 #include <android/bitmap.h>
55 #include "android.h"
56
57 int dummy;
58
59 jclass NavitClass2 = NULL;
60 jmethodID Navit_get_graphics_object_by_name;
61
62 struct graphics_priv
63 {
64 jclass NavitGraphicsClass;
65 jmethodID NavitGraphics_draw_polyline, NavitGraphics_draw_polyline2, NavitGraphics_draw_polyline3, NavitGraphics_draw_polyline4, NavitGraphics_draw_polyline_dashed, NavitGraphics_set_dashes, NavitGraphics_draw_polygon, NavitGraphics_draw_polygon2, NavitGraphics_draw_rectangle, NavitGraphics_draw_circle, NavitGraphics_draw_text, NavitGraphics_draw_image,
66 NavitGraphics_draw_bigmap, NavitGraphics_draw_image_warp, NavitGraphics_draw_mode, NavitGraphics_draw_drag, NavitGraphics_overlay_disable, NavitGraphics_overlay_resize, NavitGraphics_SetCamera, NavitGraphicsClass_rotate_and_scale_bitmap;
67
68 jclass PaintClass;
69 jmethodID Paint_init, Paint_setStrokeWidth, Paint_setARGB;
70
71 jobject NavitGraphics;
72 jobject Paint;
73
74 jclass BitmapFactoryClass;
75 jmethodID BitmapFactory_decodeFile, BitmapFactory_decodeResource;
76
77 jclass BitmapClass;
78 jmethodID Bitmap_getHeight, Bitmap_getWidth;
79
80 jclass ContextClass;
81 jmethodID Context_getResources;
82
83 jclass ResourcesClass;
84 jobject Resources;
85 jmethodID Resources_getIdentifier;
86
87 struct callback_list *cbl;
88 struct window win;
89 };
90
91 struct graphics_font_priv
92 {
93 int size;
94 };
95
96 struct graphics_gc_priv
97 {
98 struct graphics_priv *gra;
99 int linewidth;
100 enum draw_mode_num mode;
101 int a, r, g, b;
102 };
103
104 struct graphics_image_priv
105 {
106 jobject Bitmap;
107 int width;
108 int height;
109 struct point hot;
110 };
111
112 static GHashTable *image_cache_hash = NULL;
113
114
115
116
117 void drawLineOverlap(uint32_t *map_buffer, int disp_width, int disp_height, int16_t aXStart, int16_t aYStart, int16_t aXEnd, int16_t aYEnd, uint8_t aOverlap,
118 uint32_t aColor, int alpha);
119
120
121 static int find_class_global(char *name, jclass *ret)
122 {
123 //DBG // dbg(0,"EEnter\n");
124 JNIEnv *jnienv2;
125 jnienv2 = jni_getenv();
126
127 *ret = (*jnienv2)->FindClass(jnienv2, name);
128 if (!*ret)
129 {
130 //DBG // dbg(0, "Failed to get Class %s\n", name);
131 return 0;
132 }
133 *ret = (*jnienv2)->NewGlobalRef(jnienv2, *ret);
134 return 1;
135 }
136
137 static int find_method(jclass class, char *name, char *args, jmethodID *ret)
138 {
139 JNIEnv *jnienv2;
140 jnienv2 = jni_getenv();
141
142 //DBG // dbg(0,"EEnter\n");
143 *ret = (*jnienv2)->GetMethodID(jnienv2, class, name, args);
144 if (*ret == NULL)
145 {
146 //DBG // dbg(0, "Failed to get Method %s with signature %s\n", name, args);
147 return 0;
148 }
149 return 1;
150 }
151
152 static int find_static_method(jclass class, char *name, char *args, jmethodID *ret)
153 {
154 JNIEnv *jnienv2;
155 jnienv2 = jni_getenv();
156
157 //DBG // dbg(0,"EEnter\n");
158 *ret = (*jnienv2)->GetStaticMethodID(jnienv2, class, name, args);
159 if (*ret == NULL)
160 {
161 //DBG // dbg(0, "Failed to get static Method %s with signature %s\n", name, args);
162 return 0;
163 }
164 return 1;
165 }
166
167 static void graphics_destroy(struct graphics_priv *gr)
168 {
169 }
170
171 static void font_destroy(struct graphics_font_priv *font)
172 {
173 g_free(font);
174 }
175
176 static struct graphics_font_methods font_methods =
177 { font_destroy };
178
179 static struct graphics_font_priv *font_new(struct graphics_priv *gr, struct graphics_font_methods *meth, char *font, int size, int flags)
180 {
181 struct graphics_font_priv *ret=g_new0(struct graphics_font_priv, 1);
182 *meth = font_methods;
183
184 ret->size = size;
185 return ret;
186 }
187
188 static void gc_destroy(struct graphics_gc_priv *gc)
189 {
190 //DBG // dbg(0,"EEnter\n");
191
192 g_free(gc);
193 }
194
195 static void gc_set_linewidth(struct graphics_gc_priv *gc, int w)
196 {
197 gc->linewidth = w;
198 }
199
200
201 // UNUSED --------------
202 static void gc_set_dashes(struct graphics_priv *gra, struct graphics_gc_priv *gc, int w, int offset, int dash_list[], int order)
203 {
204 //JNIEnv *jnienv2;
205 //jnienv2 = jni_getenv();
206 //(*jnienv2)->CallVoidMethod(jnienv2, gra->NavitGraphics, gra->NavitGraphics_set_dashes, gc->gra->Paint, dash_list[0], order);
207 }
208
209
210 static void gc_set_foreground(struct graphics_gc_priv *gc, struct color *c)
211 {
212 gc->r = c->r >> 8;
213 gc->g = c->g >> 8;
214 gc->b = c->b >> 8;
215 gc->a = c->a >> 8;
216
217 // dbg(0, "CCCC:2:%d %d %d %d\n", gc->r, gc->g, gc->b, gc->a);
218 }
219
220 static void gc_set_background(struct graphics_gc_priv *gc, struct color *c)
221 {
222 }
223
224 static struct graphics_gc_methods gc_methods =
225 { gc_destroy, gc_set_linewidth, gc_set_dashes, gc_set_foreground, gc_set_background };
226
227 static struct graphics_gc_priv *gc_new(struct graphics_priv *gr, struct graphics_gc_methods *meth)
228 {
229 ////DBG // dbg(0,"EEnter\n");
230
231 struct graphics_gc_priv *ret=g_new0(struct graphics_gc_priv, 1);
232 *meth = gc_methods;
233
234 ret->gra = gr;
235 ret->a = ret->r = ret->g = ret->b = 255;
236 ret->linewidth = 1;
237 return ret;
238 }
239
240 static void image_destroy(struct graphics_image_priv *img)
241 {
242 // unused?
243 }
244
245 static struct graphics_image_methods image_methods =
246 { image_destroy };
247
248 static struct graphics_image_priv *
249 image_new(struct graphics_priv *gra, struct graphics_image_methods *meth, char *path, int *w, int *h, struct point *hot, int rotation)
250 {
251 //DBG // dbg(0,"EEnter\n");
252
253 JNIEnv *jnienv2;
254 jnienv2 = jni_getenv();
255
256 int thread_id = gettid();
257 // dbg(0, "THREAD ID=%d\n", thread_id);
258
259
260 struct graphics_image_priv* ret = NULL;
261
262 if (!g_hash_table_lookup_extended(image_cache_hash, path, NULL, (gpointer) & ret))
263 {
264 ret=g_new0(struct graphics_image_priv, 1);
265 jstring string;
266 int id;
267
268 //dbg(0, "enter %s\n", path);
269 if (!strncmp(path, "res/drawable/", 13))
270 {
271 jstring a = (*jnienv2)->NewStringUTF(jnienv2, "drawable");
272 jstring b = (*jnienv2)->NewStringUTF(jnienv2, "com.zoffcc.applications.zanavi");
273 char *path_noext = g_strdup(path + 13);
274 char *pos = strrchr(path_noext, '.');
275 if (pos)
276 {
277 *pos = '\0';
278 }
279 // dbg(0, "path_noext=%s a=%s b=%s\n", path_noext, a, b);
280 string = (*jnienv2)->NewStringUTF(jnienv2, path_noext);
281 g_free(path_noext);
282 id = (*jnienv2)->CallIntMethod(jnienv2, gra->Resources, gra->Resources_getIdentifier, string, a, b);
283 //DBG // dbg(0, "id=%d\n", id);
284 //DBG // dbg(0,"JNI\n");
285 if (id)
286 {
287 ret->Bitmap = (*jnienv2)->CallStaticObjectMethod(jnienv2, gra->BitmapFactoryClass, gra->BitmapFactory_decodeResource, gra->Resources, id);
288 }
289 (*jnienv2)->DeleteLocalRef(jnienv2, b);
290 (*jnienv2)->DeleteLocalRef(jnienv2, a);
291 }
292 else
293 {
294 string = (*jnienv2)->NewStringUTF(jnienv2, path);
295 //DBG // dbg(0,"JNI\n");
296 ret->Bitmap = (*jnienv2)->CallStaticObjectMethod(jnienv2, gra->BitmapFactoryClass, gra->BitmapFactory_decodeFile, string);
297 // there should be a check here, if we really want any rotation/scaling
298 // otherwise the call is overkill
299 //DBG // dbg(0,"JNI\n");
300 ret->Bitmap = (*jnienv2)->CallStaticObjectMethod(jnienv2, gra->NavitGraphicsClass, gra->NavitGraphicsClass_rotate_and_scale_bitmap, ret->Bitmap, *w, *h, rotation);
301 }
302
303 //// dbg(1, "result=%p\n", ret->Bitmap);
304 if (ret->Bitmap)
305 {
306 //DBG // dbg(0,"JNI\n");
307 ret->Bitmap = (*jnienv2)->NewGlobalRef(jnienv2, ret->Bitmap);
308 // ICS (*jnienv2)->DeleteLocalRef(jnienv2, ret->Bitmap);
309 //DBG // dbg(0,"JNI\n");
310 ret->width = (*jnienv2)->CallIntMethod(jnienv2, ret->Bitmap, gra->Bitmap_getWidth);
311 //DBG // dbg(0,"JNI\n");
312 ret->height = (*jnienv2)->CallIntMethod(jnienv2, ret->Bitmap, gra->Bitmap_getHeight);
313 //// dbg(1, "w=%d h=%d for %s\n", ret->width, ret->height, path);
314 ret->hot.x = ret->width / 2;
315
316 // dbg(0, "POI_ICON:001:%s", path);
317
318 if ( (!strncmp(path, "res/drawable/poi_", 17)) || (!strncmp(path, "poi_", 4)) )
319 {
320 // if icon starts with "poi_" then the hotspot is in the middle of the lower edge
321 ret->hot.y = ret->height;
322 // dbg(0, "POI_ICON:002:%s %d %d", path, ret->hot.y, ret->height);
323 }
324 else
325 {
326 ret->hot.y = ret->height / 2;
327 // dbg(0, "POI_ICON:003:%s %d %d", path, ret->hot.y, ret->height);
328 }
329 }
330 else
331 {
332 g_free(ret);
333 ret = NULL;
334 //DBG // dbg(0, "Failed to open %s\n", path);
335 }
336 //DBG // dbg(0,"JNI\n");
337 (*jnienv2)->DeleteLocalRef(jnienv2, string);
338 //DBG // dbg(0,"JNI\n");
339 g_hash_table_insert(image_cache_hash, g_strdup(path), (gpointer) ret);
340 }
341
342 if (ret)
343 {
344 *w = ret->width;
345 *h = ret->height;
346
347 // dbg(0, "POI_ICON:004:%s %d %d", path, ret->hot.y, ret->height);
348
349 if (hot)
350 {
351 *hot = ret->hot;
352 }
353 }
354
355 if (ret == NULL)
356 {
357 // log alert: icon missing
358 if (path == NULL)
359 {
360 // ?? no path string ??
361 }
362 else
363 {
364 send_alert_to_java(1, path);
365 }
366 }
367
368 return ret;
369 }
370
371 static void initPaint(struct graphics_priv *gra, struct graphics_gc_priv *gc)
372 {
373 //DBG // dbg(0,"EEnter\n");
374
375 JNIEnv *jnienv2;
376 jnienv2 = jni_getenv();
377
378 float wf = gc->linewidth;
379 (*jnienv2)->CallVoidMethod(jnienv2, gc->gra->Paint, gra->Paint_setStrokeWidth, wf);
380 (*jnienv2)->CallVoidMethod(jnienv2, gc->gra->Paint, gra->Paint_setARGB, gc->a, gc->r, gc->g, gc->b);
381 }
382
383 static void draw_lines(struct graphics_priv *gra, struct graphics_gc_priv *gc, struct point *p, int count)
384 {
385 //DBG // dbg(0,"EEnter\n");
386 jint pc[count * 2];
387 int i;
388 jintArray points;
389
390 if (count <= 0)
391 return;
392
393 JNIEnv *jnienv2;
394 jnienv2 = jni_getenv();
395
396 points = (*jnienv2)->NewIntArray(jnienv2, count * 2);
397 for (i = 0; i < count; i++)
398 {
399 pc[i * 2] = p[i].x;
400 pc[i * 2 + 1] = p[i].y;
401 }
402 // initPaint(gra, gc);
403 (*jnienv2)->SetIntArrayRegion(jnienv2, points, 0, count * 2, pc);
404 (*jnienv2)->CallVoidMethod(jnienv2, gra->NavitGraphics, gra->NavitGraphics_draw_polyline, points, gc->linewidth, gc->r, gc->g, gc->b, gc->a);
405 (*jnienv2)->DeleteLocalRef(jnienv2, points);
406 }
407
408
409
410 // for ARGB_888 Bitmap
411 static uint32_t createPixel(int r, int g, int b, int a)
412 {
413 if (main_map_bitmapinfo->format == ANDROID_BITMAP_FORMAT_RGBA_8888)
414 {
415 return ((a & 0xff) << 24)
416 | ((b & 0xff) << 16)
417 | ((g & 0xff) << 8)
418 | ((r & 0xff));
419 }
420 else
421 {
422 return 0;
423 }
424 }
425
426 static int createColorFromPixel_r(uint32_t color)
427 {
428 if (main_map_bitmapinfo->format == ANDROID_BITMAP_FORMAT_RGBA_8888)
429 {
430 return (color & 0xff);
431 }
432 else
433 {
434 return 0;
435 }
436 }
437
438 static int createColorFromPixel_b(uint32_t color)
439 {
440 if (main_map_bitmapinfo->format == ANDROID_BITMAP_FORMAT_RGBA_8888)
441 {
442 return (color & (0xff << 16));
443 }
444 else
445 {
446 return 0;
447 }
448 }
449
450 static int createColorFromPixel_g(uint32_t color)
451 {
452 if (main_map_bitmapinfo->format == ANDROID_BITMAP_FORMAT_RGBA_8888)
453 {
454 return (color & (0xff << 8));
455 }
456 else
457 {
458 return 0;
459 }
460 }
461
462
463 static void c_set_pixel(uint32_t *map_buffer, int line_width, int height, int x, int y, uint32_t color)
464 {
465 if ((x < 0) || (y < 0) || (x > (line_width -1 )) || (y > (height -1 )))
466 {
467 return;
468 }
469
470 uint32_t *line = map_buffer;
471 line = line + (y * line_width); // set y-coord
472 ((uint32_t*)line)[x] = color; // x-coord --> set color of pixel
473 }
474
475 static void c_set_pixel_with_alpha(uint32_t *map_buffer, int line_width, int height, int x, int y, uint32_t color, int alpha)
476 {
477 if ((x < 0) || (y < 0) || (x > (line_width -1 )) || (y > (height -1 )))
478 {
479 return;
480 }
481
482 uint32_t *line = map_buffer;
483 line = line + (y * line_width); // set y-coord
484 ((uint32_t*)line)[x] = color; // x-coord --> set color of pixel
485 }
486
487
488 #define my_lrint(a) ((int)((a)+0.5))
489 #define HYPOT(x,y) sqrtf((x)*(x)+(y)*(y))
490
491 struct murphy_t
492 {
493 int u,v; /* delta x , delta y */
494 int ku,kt,kv,kd,ks; /* loop constants */
495 int tk;
496 int oct2;
497 int quad4;
498 };
499
500
501 inline float normconstant(float fu, float fv)
502 {
503 const int choice=2; /*change this to suit taste/compute power etc.*/
504 const int u=fabs(fu), v=fabs(fv);
505
506 switch (choice)
507 {
508 case 1:
509 return (u+v>>2); /*12% thickness error - uses add and shift only*/
510 case 2:
511 if ((v+v+v)>u) /*2.7% thickness error, uses compare, add and shift only*/
512 {
513 return (u-(u>>3)+(v>>1));
514 }
515 else
516 {
517 return (u+(v>>3));
518 }
519 case 3:
520 return HYPOT(u,v); /*ideal*/
521 }
522
523 return 0;
524 }
525
526
527 static void murphy_perpendicular(struct murphy_t *murphy, int pt_x, int pt_y, int d0, int d1, uint32_t color, uint32_t *map_buffer, int line_width, int height)
528 { /*Implements Figure 4B*/
529
530 d0=-d0;
531 int q;
532
533 // dbg(0,"enter:bitmap:001 tk=%d d0=%d kt=%d kd=%d ku=%d kv=%d ks=%d\n", murphy->tk, d0, murphy->kt, murphy->kd, murphy->ku, murphy->kv, murphy->ks);
534
535 //if ((d0 == 0) && (murphy->tk == 0))
536 //{
537 // return;
538 //}
539
540 for(q=0; d0 <= murphy->tk; ++q )
541 { /*inner loop counter*/
542 //dbg(0,"bitmap:003.1 tk=%d q=%d d0=%d\n", murphy->tk, q, d0);
543
544 c_set_pixel(map_buffer, line_width, height, pt_x, pt_y, color);
545
546 if (d1 < murphy->kt)
547 { /*square move MS*/
548 // OO // ++pt_y;
549 ++pt_y;
550 d1+=murphy->kv;
551 d0+=murphy->ku;
552 }
553 else
554 { /*diagonal move MD*/
555 // OO // --pt_x;
556 // OO // ++pt_y;
557 --pt_x;
558 ++pt_y;
559 d1+=murphy->kd;
560 d0+=murphy->ks;
561 }
562
563 if (q > 10000)
564 {
565 dbg(0,"enter:bitmap:001 tk=%d d0=%d kt=%d kd=%d ku=%d kv=%d ks=%d\n", murphy->tk, d0, murphy->kt, murphy->kd, murphy->ku, murphy->kv, murphy->ks);
566 dbg(0,"bitmap:003.1 tk=%d q=%d d0=%d\n", murphy->tk, q, d0);
567
568 dbg(0, "bitmap:**ERROR** in loop!! \n");
569 break;
570 }
571
572 //dbg(0,"bitmap:003.2\n");
573 }
574
575 //dbg(0,"bitmap:ready:099\n");
576 }
577
578
579 static void murphy_wideline(uint32_t *map_buffer, int line_width, int height, int from_x, int from_y, int to_x, int to_y, uint32_t color, int width)
580 {
581 struct murphy_t murphy;
582 int pt_x, pt_y;
583 int temp;
584
585 int orig_dx;
586 int orig_dy;
587 int steep;
588 int quart;
589
590 float offset = width / 2.0f;
591
592 murphy.u = to_x - from_x; /*delta x*/
593 murphy.v = to_y - from_y; /*delta y*/
594
595 orig_dx = murphy.u;
596 orig_dy = murphy.v;
597
598 steep = 0;
599 if (abs(orig_dy) > abs(orig_dx))
600 {
601 steep = 1;
602 }
603
604 if (orig_dy < 0) // oben
605 {
606 if (orig_dx < 0) // links
607 {
608 quart = 2;
609 }
610 else // rechts
611 {
612 quart = 1;
613 }
614 }
615 else // unten
616 {
617 if (orig_dx < 0) // links
618 {
619 quart = 3;
620 }
621 else // rechts
622 {
623 quart = 4;
624 }
625 }
626
627 dbg(0,"enter:bitmap:001.0 dx=%d dy=%d steep=%d quart=%d\n", orig_dx, orig_dy, steep, quart);
628
629
630 if (murphy.u < 0) /* delta x < 0 --> links */
631 { /* swap to make sure we are in quadrants 1 or 4 --> turn 180° to left */
632 temp = to_x;
633 to_x = from_x;
634 from_x = temp;
635
636 temp = to_y;
637 to_y = from_y;
638 from_y = temp;
639
640 murphy.u *= -1;
641 murphy.v *= -1;
642 }
643
644 if (murphy.v < 0) /* delta y < 0 --> rechts oben */
645 { /* swap to 1st quadrant and flag */
646 murphy.v *= -1; // *(-1)
647 murphy.quad4 = 1; // 1
648 }
649 else // rechts unten
650 {
651 // murphy.v *= -1; // ----
652 murphy.quad4 = 0; // 0
653 }
654
655 if (murphy.v > murphy.u) // steile linie (v > u)
656 {
657 /* deltay > deltax = octant 2
658 /* swap things if in 2 octant */
659 temp = murphy.u;
660 murphy.u = murphy.v;
661 murphy.v = temp;
662
663 murphy.oct2 = 1; // 1
664 }
665 else // flache linie
666 {
667 murphy.oct2 = 0; // 0
668 }
669
670 //if ( (steep == 0)&&( (quart==1)||(quart==3) ) )
671 //{
672 // murphy.ku=murphy.u+murphy.u; // 2*dx /*change in l for square shift*/
673 // murphy.kv=-murphy.v-murphy.v; // 2*dy /*change in d for square shift*/
674 // murphy.kd=murphy.kv-murphy.ku; // 2*dy - 2*dx /*change in d for diagonal shift*/
675 // murphy.ks=murphy.kv+murphy.ku; // 2*dy + 2*dx /*change in l for diagonal shift*/
676 // murphy.kt=murphy.u-murphy.kv; // dx - (2*dy) /*diag/square decision threshold*/
677 //}
678 //else
679 //{
680 murphy.ku=murphy.u+murphy.u; // 2*dx /*change in l for square shift*/
681 murphy.kv=murphy.v+murphy.v; // 2*dy /*change in d for square shift*/
682 murphy.kd=murphy.kv-murphy.ku; // 2*dy - 2*dx /*change in d for diagonal shift*/
683
684 murphy.ks=murphy.kv+murphy.ku; // 2*dy + 2*dx /*change in l for diagonal shift*/
685 murphy.kt=murphy.u-murphy.kv; // dx - (2*dy) /*diag/square decision threshold*/
686 //}
687
688 dbg(0,"enter:bitmap:001a.1 x1=%d y1=%d x2=%d y2=%d\n", from_x, from_y, to_x, to_y);
689 dbg(0,"enter:bitmap:001a.2 u=%d v=%d o2=%d q4=%d\n", murphy.u, murphy.v, murphy.oct2, murphy.quad4);
690 dbg(0,"enter:bitmap:001a.4 ku=%d kv=%d kd=%d ks=%d kt=%d\n", murphy.ku, murphy.kv, murphy.kd, murphy.ks, murphy.kt);
691
692 int d0 = 0,d1 = 0;
693 float ang;
694
695 if (murphy.v == 0)
696 {
697 ang = 0.0f;
698 dbg(0,"bitmap:003c ang=%f v=%d\n", ang, murphy.v);
699 }
700 else if (murphy.u == 0)
701 {
702 //ang = atanf((float)murphy.v/(float)murphy.u); /* calc new initial point - offset both sides of ideal */
703 ang = 3.1415f / 2.0f;
704 dbg(0,"bitmap:003a ang=%f v=%d\n", ang, murphy.v);
705 }
706 else
707 {
708 errno = 0;
709 ang = atanf((float)murphy.v/(float)murphy.u); /* calc new initial point - offset both sides of ideal */
710 dbg(0,"bitmap:003b ang=%f errno=%d\n", ang, errno);
711
712 if (errno != 0)
713 {
714 ang = 0.0f;
715 }
716 }
717
718 if (murphy.oct2 == 0) // ==
719 {
720 pt_x = from_x + my_lrint(offset * sinf(ang)); // sinf +
721 if (murphy.quad4 == 0) // ==
722 {
723 pt_y = from_y - my_lrint(offset * cosf(ang)); // cosf -
724 }
725 else
726 {
727 pt_y = from_y + my_lrint(offset * cosf(ang)); // cosf +
728 }
729 }
730 else
731 {
732 pt_x = from_x + my_lrint(offset * cosf(ang)); // cosf +
733 if (murphy.quad4 == 0) // ==
734 {
735 pt_y = from_y + my_lrint(offset * sinf(ang)); // sinf +
736 }
737 else
738 {
739 pt_y = from_y - my_lrint(offset * sinf(ang)); // sinf -
740 }
741 }
742
743 dbg(0,"enter:bitmap:001c fx=%d fy=%d xmiddle=%d ymiddle=%d\n", from_x, from_y, pt_x, pt_y);
744
745 //dbg(0,"bitmap:004\n");
746 murphy.tk = 4.*HYPOT(pt_x-from_x, pt_y-from_y) * normconstant(murphy.u,murphy.v); /*used here for constant thickness line*/
747 dbg(0,"bitmap:005 tk=%d\n", murphy.tk);
748
749
750 int p=0;
751 /*outer loop counter*/
752
753 while (p <= murphy.u) // run from [ 0 .. delta x ]
754 {
755 /*outer loop, stepping along line*/
756
757 dbg(0,"bitmap:006.1 p=%d m.u=%d pt_x=%d pt_y=%d d0=%d d1=%d\n", p, murphy.u, pt_x, pt_y, d0, d1);
758 // ** murphy_perpendicular(&murphy, pt_x, pt_y, d0, d1, color, map_buffer, line_width, height);
759 dbg(0,"bitmap:006.1 p=%d m.u=%d pt_x=%d pt_y=%d d0=%d d1=%d\n", p, murphy.u, pt_x, pt_y, d0, d1);
760 c_set_pixel(map_buffer, line_width, height, pt_x, pt_y, color);
761 //dbg(0,"bitmap:006.2\n");
762
763 if (1 == 1) // (d0 < murphy.kt)
764 {
765 /*square move*/
766 if (murphy.oct2 == 0) // ==
767 {
768 if (murphy.quad4 == 0) // ==
769 {
770 // OO // ++pt_y;
771 ++pt_y;
772 }
773 else
774 {
775 // OO // --pt_y;
776 --pt_y;
777 }
778 }
779 else
780 {
781 // OO // ++pt_x;
782 ++pt_x;
783 }
784 }
785 else
786 {
787 /*diagonal move*/
788 d0 -= murphy.ku;
789 if (d1 < murphy.kt)
790 {
791 /*normal start*/
792 ++pt_x;
793 ++pt_y; /*move M1*/
794 d1 += murphy.kv;
795 }
796 else
797 {
798 /*double square move, need extra perpendicular line*/
799 ++pt_y; /*move M2*/
800 d1 += murphy.kd;
801 dbg(0,"bitmap:006.2 p=%d m.u=%d pt_x=%d pt_y=%d d0=%d d1=%d\n", p, murphy.u, pt_x, pt_y, d0, d1);
802 // ** murphy_perpendicular(&murphy,pt_x,pt_y,d0,d1, color, map_buffer, line_width, height); /*extra perpendicular*/
803 dbg(0,"bitmap:006.2 p=%d m.u=%d pt_x=%d pt_y=%d d0=%d d1=%d\n", p, murphy.u, pt_x, pt_y, d0, d1);
804 c_set_pixel(map_buffer, line_width, height, pt_x, pt_y, color);
805 ++pt_x; /*move m0*/
806 }
807 }
808
809 d0 += murphy.kv;
810 ++p;
811
812 //dbg(0,"bitmap:006.99\n");
813 }
814
815 //dbg(0,"bitmap:ready:99\n");
816 }
817
818
819
820
821
822
823
824 /**************************************************************************
825 * *
826 * draws a line using Bresenham's line-drawing algorithm, which uses *
827 * no multiplication or division. *
828 **************************************************************************/
829
830 #define sgn(x) ((x<0)?-1:((x>0)?1:0)) /* macro to return the sign of a
831 number */
832
833 static void c_draw_line3_fast(uint32_t *map_buffer, int line_width, int height, int x1, int y1, int x2, int y2, uint32_t color)
834 {
835 //uint32_t color = createPixel(r, g, b, a);
836
837 //dbg(0, "bitmap line:%d %d %d %d\n", x1, y1, x2, y2);
838
839 int i,dx,dy,sdx,sdy,dxabs,dyabs,x,y,px,py;
840
841 dx=x2-x1; /* the horizontal distance of the line */
842 dy=y2-y1; /* the vertical distance of the line */
843 dxabs=abs(dx);
844 dyabs=abs(dy);
845 sdx=sgn(dx);
846 sdy=sgn(dy);
847 x=dyabs >> 1;
848 y=dxabs >> 1;
849 px=x1;
850 py=y1;
851
852 if (dxabs>=dyabs) // the line is more horizontal than vertical
853 {
854 for(i=0;i < dxabs;i++)
855 {
856 y+=dyabs;
857 if (y >= dxabs)
858 {
859 y-=dxabs;
860 py+=sdy;
861 }
862 px+=sdx;
863
864 c_set_pixel(map_buffer, line_width, height, px, py, color);
865 }
866 }
867 else // the line is more vertical than horizontal
868 {
869 for(i=0;i < dyabs;i++)
870 {
871 x+=dxabs;
872 if (x >= dyabs)
873 {
874 x-=dyabs;
875 px+=sdx;
876 }
877 py+=sdy;
878
879 c_set_pixel(map_buffer, line_width, height, px, py, color);
880 }
881 }
882 }
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899 // -------------------
900 // -------------------
901 // -------------------
902 // -------------------
903 // -------------------
904 // -------------------
905 // -------------------
906 // -------------------
907 // -------------------
908 // -------------------
909 // -------------------
910 // -------------------
911 // -------------------
912 // -------------------
913 // -------------------
914 // -------------------
915 // -------------------
916 // -------------------
917 // -------------------
918 // -------------------
919 // -------------------
920 // -------------------
921 // -------------------
922 // -------------------
923 // -------------------
924 // -------------------
925 // -------------------
926 // -------------------
927 // -------------------
928 // -------------------
929 // -------------------
930 // -------------------
931
932 #define LINE_OVERLAP_NONE 0 // No line overlap
933 #define LINE_OVERLAP_MAJOR 0x01 // Overlap - first go major then minor direction
934 #define LINE_OVERLAP_MINOR 0x02 // Overlap - first go minor then major direction
935 #define LINE_OVERLAP_BOTH 0x03 // Overlap - both
936
937 #define LINE_THICKNESS_MIDDLE 0
938 #define LINE_THICKNESS_DRAW_CLOCKWISE 1
939 #define LINE_THICKNESS_DRAW_COUNTERCLOCKWISE 2
940
941 struct ThickLine
942 {
943 int16_t StartX;
944 int16_t StartY;
945 int16_t EndX;
946 int16_t EndY;
947 int16_t Thickness;
948 uint8_t ThicknessMode;
949 uint32_t Color;
950 uint32_t BackgroundColor;
951 };
952
953 typedef int bool;
954 #define true 1
955 #define false 0
956
957
958 static void c_set_pixel2(uint32_t *map_buffer, int line_width, int height, uint16_t x, uint16_t y, uint32_t color)
959 {
960 if ((x < 0) || (y < 0) || (x > (line_width -1 )) || (y > (height -1)))
961 {
962 return;
963 }
964
965 uint32_t *line = map_buffer;
966 line = line + (y * line_width); // set y-coord
967 ((uint32_t*)line)[x] = color; // x-coord --> set color of pixel
968 }
969
970 static void c_set_pixel2_with_alpha(uint32_t *map_buffer, int line_width, int height, uint16_t x, uint16_t y, uint32_t color, int alpha)
971 {
972 if ((x < 0) || (y < 0) || (x > (line_width -1 )) || (y > (height -1)))
973 {
974 return;
975 }
976
977 // alpha 0 -> transparent
978 // alpha 255 -> full line
979
980 if (alpha == 0)
981 {
982 return;
983 }
984
985 // alpha2 = float [0 .. 1]
986 float alpha2 = (float)alpha / 255.0f;
987 float one_minus_alpha2 = 1 - alpha2;
988
989 uint32_t *line = map_buffer;
990 line = line + (y * line_width); // set y-coord
991
992 uint32_t color_old = ((uint32_t*)line)[x];
993
994 // formula: out = alpha2 * new + (1 - alpha2) * old
995 int r_out = alpha2 * (float)createColorFromPixel_r(color) + one_minus_alpha2 * (float)createColorFromPixel_r(color_old);
996 int g_out = alpha2 * (float)createColorFromPixel_g(color) + one_minus_alpha2 * (float)createColorFromPixel_g(color_old);
997 int b_out = alpha2 * (float)createColorFromPixel_b(color) + one_minus_alpha2 * (float)createColorFromPixel_b(color_old);
998 if (r_out > 255)
999 {
1000 r_out = 255;
1001 }
1002 if (g_out > 255)
1003 {
1004 g_out = 255;
1005 }
1006 if (b_out > 255)
1007 {
1008 b_out = 255;
1009 }
1010
1011 uint32_t color_out = createPixel(r_out, g_out, b_out, 255);
1012
1013 ((uint32_t*)line)[x] = color_out; // x-coord --> set color of pixel
1014 }
1015
1016
1017 #if 0
1018 static void c_fillRect(uint32_t *map_buffer, int line_width, int height, int16_t aXStart, int16_t aYStart, int16_t aXEnd, int16_t aYEnd, uint32_t aColor)
1019 {
1020 dbg(0, "enter\n");
1021
1022 return;
1023
1024 int i;
1025 int j;
1026 int16_t temp;
1027 uint32_t *line = map_buffer;
1028
1029 if (aYEnd < aYStart)
1030 {
1031 temp = aYStart;
1032 aYStart = aYEnd;
1033 aYEnd = temp;
1034 }
1035
1036 if (aXEnd < aXStart)
1037 {
1038 temp = aXStart;
1039 aXStart = aXEnd;
1040 aXEnd = temp;
1041 }
1042
1043 line = line + (aYStart * line_width); // set y-coord
1044 for(j = aYStart;j <= aYEnd;j++)
1045 {
1046 if ((j >= 0)||(j < height))
1047 {
1048 for(i = aXStart;i <= aXEnd;aXStart++)
1049 {
1050 if ((i >= 0)||(i < line_width))
1051 {
1052 ((uint32_t*)line)[i] = aColor; // x-coord --> set color of pixel
1053 }
1054 }
1055 }
1056 line++;
1057 }
1058
1059 dbg(0, "leave\n");
1060 }
1061 #endif
1062
1063
1064 /**
1065 * modified Bresenham
1066 */
1067 void drawLine(uint32_t *map_buffer, int disp_width, int disp_height, uint16_t aXStart, uint16_t aYStart, uint16_t aXEnd, uint16_t aYEnd, uint32_t aColor, int alpha)
1068 {
1069 drawLineOverlap(map_buffer, disp_width, disp_height, aXStart, aYStart, aXEnd, aYEnd, LINE_OVERLAP_NONE, aColor, alpha);
1070 }
1071
1072 /**
1073 * modified Bresenham with optional overlap (esp. for drawThickLine())
1074 * Overlap draws additional pixel when changing minor direction - for standard bresenham overlap = LINE_OVERLAP_NONE (0)
1075 *
1076 * Sample line:
1077 *
1078 * 00+
1079 * -0000+
1080 * -0000+
1081 * -00
1082 *
1083 * 0 pixels are drawn for normal line without any overlap
1084 * + pixels are drawn if LINE_OVERLAP_MAJOR
1085 * - pixels are drawn if LINE_OVERLAP_MINOR
1086 */
1087
1088
1089 void drawLineOverlap(uint32_t *map_buffer, int disp_width, int disp_height, int16_t aXStart, int16_t aYStart, int16_t aXEnd, int16_t aYEnd, uint8_t aOverlap,
1090 uint32_t aColor, int alpha)
1091 {
1092
1093 //dbg(0, " enter\n");
1094
1095 int16_t tDeltaX, tDeltaY, tDeltaXTimes2, tDeltaYTimes2, tError, tStepX, tStepY;
1096
1097 /*
1098 if (aXStart >= disp_width) {
1099 aXStart = disp_width - 1;
1100 }
1101 if (aXStart < 0) {
1102 aXStart = 0;
1103 }
1104 if (aXEnd >= disp_width) {
1105 aXEnd = disp_width - 1;
1106 }
1107 if (aXEnd < 0) {
1108 aXEnd = 0;
1109 }
1110 if (aYStart >= disp_height) {
1111 aYStart = disp_height - 1;
1112 }
1113 if (aYStart < 0) {
1114 aYStart = 0;
1115 }
1116 if (aYEnd >= disp_height) {
1117 aYEnd = disp_height - 1;
1118 }
1119 if (aYEnd < 0) {
1120 aYEnd = 0;
1121 }
1122 */
1123
1124 //if (aXStart == aXEnd)
1125 //{
1126 // //horizontal or vertical line -> fillRect() is faster
1127 // // fillRect(aXStart, aYStart, aXEnd, aYEnd, aColor);
1128 // //c_fillRect(map_buffer, disp_width, disp_height, aXStart, aYStart, aXEnd, aYEnd, aColor);
1129 //}
1130 //else
1131 //{
1132 //calculate direction
1133 tDeltaX = aXEnd - aXStart;
1134 tDeltaY = aYEnd - aYStart;
1135 if (tDeltaX < 0) {
1136 tDeltaX = -tDeltaX;
1137 tStepX = -1;
1138 } else {
1139 tStepX = +1;
1140 }
1141 if (tDeltaY < 0) {
1142 tDeltaY = -tDeltaY;
1143 tStepY = -1;
1144 } else {
1145 tStepY = +1;
1146 }
1147 tDeltaXTimes2 = tDeltaX << 1;
1148 tDeltaYTimes2 = tDeltaY << 1;
1149 //draw start pixel
1150 if (alpha != 255)
1151 {
1152 c_set_pixel2_with_alpha(map_buffer, disp_width, disp_height, aXStart, aYStart, aColor, alpha);
1153 }
1154 else
1155 {
1156 c_set_pixel2(map_buffer, disp_width, disp_height, aXStart, aYStart, aColor);
1157 }
1158 // drawPixel(aXStart, aYStart, aColor);
1159 if (tDeltaX > tDeltaY)
1160 {
1161 // start value represents a half step in Y direction
1162 tError = tDeltaYTimes2 - tDeltaX;
1163 //dbg(0, " w loop1 start\n");
1164 while (aXStart != aXEnd)
1165 {
1166 // step in main direction
1167 aXStart += tStepX;
1168 if (tError >= 0)
1169 {
1170 if (aOverlap & LINE_OVERLAP_MAJOR)
1171 {
1172 // draw pixel in main direction before changing
1173 if (alpha != 255)
1174 {
1175 c_set_pixel2_with_alpha(map_buffer, disp_width, disp_height, aXStart, aYStart, aColor, alpha);
1176 }
1177 else
1178 {
1179 c_set_pixel2(map_buffer, disp_width, disp_height, aXStart, aYStart, aColor);
1180 }
1181 // drawPixel(aXStart, aYStart, aColor);
1182 }
1183 // change Y
1184 aYStart += tStepY;
1185 if (aOverlap & LINE_OVERLAP_MINOR)
1186 {
1187 // draw pixel in minor direction before changing
1188 if (alpha != 255)
1189 {
1190 c_set_pixel2_with_alpha(map_buffer, disp_width, disp_height, aXStart, aYStart, aColor, alpha);
1191 }
1192 else
1193 {
1194 c_set_pixel2(map_buffer, disp_width, disp_height, aXStart - tStepX, aYStart, aColor);
1195 }
1196 // drawPixel(aXStart - tStepX, aYStart, aColor);
1197 }
1198 tError -= tDeltaXTimes2;
1199 }
1200 tError += tDeltaYTimes2;
1201 if (alpha != 255)
1202 {
1203 c_set_pixel2_with_alpha(map_buffer, disp_width, disp_height, aXStart, aYStart, aColor, alpha);
1204 }
1205 else
1206 {
1207 c_set_pixel2(map_buffer, disp_width, disp_height, aXStart, aYStart, aColor);
1208 }
1209 // drawPixel(aXStart, aYStart, aColor);
1210 }
1211 //dbg(0, " w loop1 end\n");
1212 }
1213 else
1214 {
1215 tError = tDeltaXTimes2 - tDeltaY;
1216 //dbg(0, " w loop2 start\n");
1217 while (aYStart != aYEnd)
1218 {
1219 aYStart += tStepY;
1220 if (tError >= 0) {
1221 if (aOverlap & LINE_OVERLAP_MAJOR) {
1222 // draw pixel in main direction before changing
1223 if (alpha != 255)
1224 {
1225 c_set_pixel2_with_alpha(map_buffer, disp_width, disp_height, aXStart, aYStart, aColor, alpha);
1226 }
1227 else
1228 {
1229 c_set_pixel2(map_buffer, disp_width, disp_height, aXStart, aYStart, aColor);
1230 }
1231 // drawPixel(aXStart, aYStart, aColor);
1232 }
1233 aXStart += tStepX;
1234 if (aOverlap & LINE_OVERLAP_MINOR) {
1235 // draw pixel in minor direction before changing
1236 if (alpha != 255)
1237 {
1238 c_set_pixel2_with_alpha(map_buffer, disp_width, disp_height, aXStart, aYStart, aColor, alpha);
1239 }
1240 else
1241 {
1242 c_set_pixel2(map_buffer, disp_width, disp_height, aXStart, aYStart - tStepY, aColor);
1243 }
1244 // drawPixel(aXStart, aYStart - tStepY, aColor);
1245 }
1246 tError -= tDeltaYTimes2;
1247 }
1248 tError += tDeltaXTimes2;
1249 if (alpha != 255)
1250 {
1251 c_set_pixel2_with_alpha(map_buffer, disp_width, disp_height, aXStart, aYStart, aColor, alpha);
1252 }
1253 else
1254 {
1255 c_set_pixel2(map_buffer, disp_width, disp_height, aXStart, aYStart, aColor);
1256 }
1257 // drawPixel(aXStart, aYStart, aColor);
1258 }
1259 //dbg(0, " w loop2 end\n");
1260 }
1261 //}
1262
1263 //dbg(0, " leave\n");
1264 }
1265
1266
1267
1268 /**
1269 * Bresenham with thickness
1270 * no pixel missed and every pixel only drawn once!
1271 */
1272 void drawThickLine(uint32_t *map_buffer, int disp_width, int disp_height, int16_t aXStart, int16_t aYStart, int16_t aXEnd, int16_t aYEnd, int16_t aThickness, uint8_t aThicknessMode,
1273 uint32_t aColor, int alpha)
1274 {
1275 int16_t i, tDeltaX, tDeltaY, tDeltaXTimes2, tDeltaYTimes2, tError, tStepX, tStepY;
1276
1277 if(aThickness <= 1)
1278 {
1279 drawLineOverlap(map_buffer, disp_width, disp_height, aXStart, aYStart, aXEnd, aYEnd, LINE_OVERLAP_NONE, aColor, alpha);
1280 return;
1281 }
1282
1283 /*
1284 if (aXStart >= disp_width) {
1285 aXStart = disp_width - 1;
1286 }
1287 if (aXStart < 0) {
1288 aXStart = 0;
1289 }
1290 if (aXEnd >= disp_width) {
1291 aXEnd = disp_width - 1;
1292 }
1293 if (aXEnd < 0) {
1294 aXEnd = 0;
1295 }
1296 if (aYStart >= disp_height) {
1297 aYStart = disp_height - 1;
1298 }
1299 if (aYStart < 0) {
1300 aYStart = 0;
1301 }
1302 if (aYEnd >= disp_height) {
1303 aYEnd = disp_height - 1;
1304 }
1305 if (aYEnd < 0) {
1306 aYEnd = 0;
1307 }
1308 */
1309
1310 /**
1311 * For coordinatesystem with 0.0 topleft
1312 * Swap X and Y delta and calculate clockwise (new delta X inverted)
1313 * or counterclockwise (new delta Y inverted) rectangular direction.
1314 * The right rectangular direction for LINE_OVERLAP_MAJOR toggles with each octant
1315 */
1316 tDeltaY = aXEnd - aXStart;
1317 tDeltaX = aYEnd - aYStart;
1318 // mirror 4 quadrants to one and adjust deltas and stepping direction
1319 bool tSwap = true; // count effective mirroring
1320 if (tDeltaX < 0) {
1321 tDeltaX = -tDeltaX;
1322 tStepX = -1;
1323 tSwap = !tSwap;
1324 } else {
1325 tStepX = +1;
1326 }
1327 if (tDeltaY < 0) {
1328 tDeltaY = -tDeltaY;
1329 tStepY = -1;
1330 tSwap = !tSwap;
1331 } else {
1332 tStepY = +1;
1333 }
1334 tDeltaXTimes2 = tDeltaX << 1;
1335 tDeltaYTimes2 = tDeltaY << 1;
1336 bool tOverlap;
1337
1338 // adjust for right direction of thickness from line origin
1339 int tDrawStartAdjustCount = aThickness / 2;
1340 if (aThicknessMode == LINE_THICKNESS_DRAW_COUNTERCLOCKWISE)
1341 {
1342 tDrawStartAdjustCount = aThickness - 1;
1343 }
1344 else if (aThicknessMode == LINE_THICKNESS_DRAW_CLOCKWISE)
1345 {
1346 tDrawStartAdjustCount = 0;
1347 }
1348
1349 // which octant are we now
1350 if (tDeltaX >= tDeltaY) {
1351 if (tSwap) {
1352 tDrawStartAdjustCount = (aThickness - 1) - tDrawStartAdjustCount;
1353 tStepY = -tStepY;
1354 } else {
1355 tStepX = -tStepX;
1356 }
1357 /*
1358 * Vector for draw direction of lines is rectangular and counterclockwise to original line
1359 * Therefore no pixel will be missed if LINE_OVERLAP_MAJOR is used
1360 * on changing in minor rectangular direction
1361 */
1362 // adjust draw start point
1363 tError = tDeltaYTimes2 - tDeltaX;
1364 for (i = tDrawStartAdjustCount; i > 0; i--) {
1365 // change X (main direction here)
1366 aXStart -= tStepX;
1367 aXEnd -= tStepX;
1368 if (tError >= 0) {
1369 // change Y
1370 aYStart -= tStepY;
1371 aYEnd -= tStepY;
1372 tError -= tDeltaXTimes2;
1373 }
1374 tError += tDeltaYTimes2;
1375 }
1376 //draw start line
1377 drawLine(map_buffer, disp_width, disp_height, aXStart, aYStart, aXEnd, aYEnd, aColor, alpha);
1378 // draw aThickness lines
1379 tError = tDeltaYTimes2 - tDeltaX;
1380 for (i = aThickness; i > 1; i--) {
1381 // change X (main direction here)
1382 aXStart += tStepX;
1383 aXEnd += tStepX;
1384 tOverlap = LINE_OVERLAP_NONE;
1385 if (tError >= 0) {
1386 // change Y
1387 aYStart += tStepY;
1388 aYEnd += tStepY;
1389 tError -= tDeltaXTimes2;
1390 /*
1391 * change in minor direction reverse to line (main) direction
1392 * because of chosing the right (counter)clockwise draw vector
1393 * use LINE_OVERLAP_MAJOR to fill all pixel
1394 *
1395 * EXAMPLE:
1396 * 1,2 = Pixel of first lines
1397 * 3 = Pixel of third line in normal line mode
1398 * - = Pixel which will be drawn in LINE_OVERLAP_MAJOR mode
1399 * 33
1400 * 3333-22
1401 * 3333-222211
1402 * 33-22221111
1403 * 221111 /\
1404 * 11 Main direction of draw vector
1405 * -> Line main direction
1406 * <- Minor direction of counterclockwise draw vector
1407 */
1408 tOverlap = LINE_OVERLAP_MAJOR;
1409 }
1410 tError += tDeltaYTimes2;
1411 drawLineOverlap(map_buffer, disp_width, disp_height, aXStart, aYStart, aXEnd, aYEnd, tOverlap, aColor, alpha);
1412 }
1413 } else {
1414 // the other octant
1415 if (tSwap) {
1416 tStepX = -tStepX;
1417 } else {
1418 tDrawStartAdjustCount = (aThickness - 1) - tDrawStartAdjustCount;
1419 tStepY = -tStepY;
1420 }
1421 // adjust draw start point
1422 tError = tDeltaXTimes2 - tDeltaY;
1423 for (i = tDrawStartAdjustCount; i > 0; i--) {
1424 aYStart -= tStepY;
1425 aYEnd -= tStepY;
1426 if (tError >= 0) {
1427 aXStart -= tStepX;
1428 aXEnd -= tStepX;
1429 tError -= tDeltaYTimes2;
1430 }
1431 tError += tDeltaXTimes2;
1432 }
1433 //draw start line
1434 drawLine(map_buffer, disp_width, disp_height, aXStart, aYStart, aXEnd, aYEnd, aColor, alpha);
1435 tError = tDeltaXTimes2 - tDeltaY;
1436 for (i = aThickness; i > 1; i--) {
1437 aYStart += tStepY;
1438 aYEnd += tStepY;
1439 tOverlap = LINE_OVERLAP_NONE;
1440 if (tError >= 0) {
1441 aXStart += tStepX;
1442 aXEnd += tStepX;
1443 tError -= tDeltaYTimes2;
1444 tOverlap = LINE_OVERLAP_MAJOR;
1445 }
1446 tError += tDeltaXTimes2;
1447 drawLineOverlap(map_buffer, disp_width, disp_height, aXStart, aYStart, aXEnd, aYEnd, tOverlap, aColor, alpha);
1448 }
1449 }
1450 }
1451
1452
1453
1454 /**
1455 * The same as before, but no clipping, some pixel are drawn twice (use LINE_OVERLAP_BOTH)
1456 * and direction of thickness changes for each octant (except for LINE_THICKNESS_MIDDLE and aThickness odd)
1457 */
1458 void drawThickLineSimple(uint32_t *map_buffer, int disp_width, int disp_height, int16_t aXStart, int16_t aYStart, int16_t aXEnd, int16_t aYEnd, int16_t aThickness,
1459 uint8_t aThicknessMode, uint32_t aColor, int alpha)
1460 {
1461 //dbg(0, "enter\n");
1462
1463 if(aThickness <= 1)
1464 {
1465 drawLineOverlap(map_buffer, disp_width, disp_height, aXStart, aYStart, aXEnd, aYEnd, LINE_OVERLAP_NONE, aColor, alpha);
1466 //dbg(0, "return 001\n");
1467 return;
1468 }
1469
1470
1471 int16_t i, tDeltaX, tDeltaY, tDeltaXTimes2, tDeltaYTimes2, tError, tStepX, tStepY;
1472
1473 tDeltaY = aXStart - aXEnd;
1474 tDeltaX = aYEnd - aYStart;
1475 // mirror 4 quadrants to one and adjust deltas and stepping direction
1476 if (tDeltaX < 0) {
1477 tDeltaX = -tDeltaX;
1478 tStepX = -1;
1479 } else {
1480 tStepX = +1;
1481 }
1482 if (tDeltaY < 0) {
1483 tDeltaY = -tDeltaY;
1484 tStepY = -1;
1485 } else {
1486 tStepY = +1;
1487 }
1488 tDeltaXTimes2 = tDeltaX << 1;
1489 tDeltaYTimes2 = tDeltaY << 1;
1490 bool tOverlap;
1491 // which octant are we now
1492 if (tDeltaX > tDeltaY)
1493 {
1494 if (aThicknessMode == LINE_THICKNESS_MIDDLE)
1495 {
1496 // adjust draw start point
1497 tError = tDeltaYTimes2 - tDeltaX;
1498 for (i = aThickness / 2; i > 0; i--)
1499 {
1500 // change X (main direction here)
1501 aXStart -= tStepX;
1502 aXEnd -= tStepX;
1503 if (tError >= 0)
1504 {
1505 // change Y
1506 aYStart -= tStepY;
1507 aYEnd -= tStepY;
1508 tError -= tDeltaXTimes2;
1509 }
1510 tError += tDeltaYTimes2;
1511 }
1512 }
1513 //draw start line
1514 //drawLine(aXStart, aYStart, aXEnd, aYEnd, aColor);
1515 drawLine(map_buffer, disp_width, disp_height, aXStart, aYStart, aXEnd, aYEnd, aColor, alpha);
1516 // draw aThickness lines
1517 tError = tDeltaYTimes2 - tDeltaX;
1518
1519 for (i = aThickness; i > 1; i--)
1520 {
1521 // change X (main direction here)
1522 aXStart += tStepX;
1523 aXEnd += tStepX;
1524 tOverlap = LINE_OVERLAP_NONE;
1525 if (tError >= 0)
1526 {
1527 // change Y
1528 aYStart += tStepY;
1529 aYEnd += tStepY;
1530 tError -= tDeltaXTimes2;
1531 tOverlap = LINE_OVERLAP_BOTH;
1532 }
1533 tError += tDeltaYTimes2;
1534 drawLineOverlap(map_buffer, disp_width, disp_height, aXStart, aYStart, aXEnd, aYEnd, tOverlap, aColor, alpha);
1535 // drawLineOverlap(aXStart, aYStart, aXEnd, aYEnd, tOverlap, aColor);
1536 }
1537 }
1538 else
1539 {
1540 // adjust draw start point
1541 if (aThicknessMode == LINE_THICKNESS_MIDDLE)
1542 {
1543 tError = tDeltaXTimes2 - tDeltaY;
1544 for (i = aThickness / 2; i > 0; i--)
1545 {
1546 aYStart -= tStepY;
1547 aYEnd -= tStepY;
1548 if (tError >= 0)
1549 {
1550 aXStart -= tStepX;
1551 aXEnd -= tStepX;
1552 tError -= tDeltaYTimes2;
1553 }
1554 tError += tDeltaXTimes2;
1555 }
1556 }
1557 //draw start line
1558 //drawLine(aXStart, aYStart, aXEnd, aYEnd, aColor);
1559 drawLine(map_buffer, disp_width, disp_height, aXStart, aYStart, aXEnd, aYEnd, aColor, alpha);
1560 tError = tDeltaXTimes2 - tDeltaY;
1561 for (i = aThickness; i > 1; i--)
1562 {
1563 aYStart += tStepY;
1564 aYEnd += tStepY;
1565 tOverlap = LINE_OVERLAP_NONE;
1566 if (tError >= 0)
1567 {
1568 aXStart += tStepX;
1569 aXEnd += tStepX;
1570 tError -= tDeltaYTimes2;
1571 tOverlap = LINE_OVERLAP_BOTH;
1572 }
1573 tError += tDeltaXTimes2;
1574 drawLineOverlap(map_buffer, disp_width, disp_height, aXStart, aYStart, aXEnd, aYEnd, tOverlap, aColor, alpha);
1575 // drawLineOverlap(aXStart, aYStart, aXEnd, aYEnd, tOverlap, aColor);
1576 }
1577 }
1578
1579 //dbg(0, "leave\n");
1580
1581 }
1582
1583
1584
1585
1586 // -------------------
1587 // -------------------
1588 // -------------------
1589 // -------------------
1590 // -------------------
1591 // -------------------
1592 // -------------------
1593 // -------------------
1594 // -------------------
1595 // -------------------
1596 // -------------------
1597 // -------------------
1598 // -------------------
1599 // -------------------
1600 // -------------------
1601 // -------------------
1602 // -------------------
1603 // -------------------
1604 // -------------------
1605 // -------------------
1606 // -------------------
1607 // -------------------
1608 // -------------------
1609 // -------------------
1610 // -------------------
1611 // -------------------
1612 // -------------------
1613 // -------------------
1614 // -------------------
1615 // -------------------
1616 // -------------------
1617 // -------------------
1618
1619
1620
1621
1622
1623
1624
1625
1626
1627
1628
1629 #if 0
1630 static void c_draw_line3_fast_width(uint32_t *map_buffer, int line_width, int height, int x1, int y1, int x2, int y2, int r, int g, int b, int a, int width)
1631 {
1632 // dbg(0,"rgba:%d %d %d %d\n", r, b, g, a);
1633
1634
1635 if (width == 1)
1636 {
1637 c_draw_line3_fast(map_buffer, line_width, height, x1, y1, x2, y2, r, g, b, a);
1638 }
1639 else
1640 {
1641 uint32_t color = createPixel(r, g, b, a);
1642 //c_draw_line3_fast(map_buffer, line_width, height, x1, y1, x2, y2, r, g, b, a);
1643
1644 //drawThickLine (map_buffer, line_width, height, x1, y1, x2, y2, width, LINE_THICKNESS_MIDDLE, color);
1645 drawThickLineSimple(map_buffer, line_width, height, x1, y1, x2, y2, width, LINE_THICKNESS_MIDDLE, color);
1646 }
1647
1648
1649
1650 #if 0
1651 uint32_t color;
1652
1653 int cx = (int)(line_width / 2.0f);
1654 int cy = (int)(height / 2.0f);
1655 int dl = 150;
1656 int dm = 20;
1657
1658 int ww = 10;
1659
1660
1661 // nach: links unten steil (gelb)
1662 dbg(0,"bitmap:lu steil\n");
1663 color = createPixel(255, 255, 0, 255);
1664 //murphy_wideline(map_buffer, line_width, height, cx, cy, cx - dm, cy + dl, color, ww);
1665 //c_draw_line3_fast(map_buffer, line_width, height, cx, cy, cx - dm, cy + dl, 255, 255, 0, 255);
1666 drawThickLine(map_buffer, line_width, height, cx, cy, cx - dm, cy + dl, ww, LINE_THICKNESS_MIDDLE, color);
1667 dbg(0,"bitmap:lu steil\n");
1668
1669
1670 // nach: rechts unten steil (rot)
1671 dbg(0,"bitmap:ru steil\n");
1672 color = createPixel(255, 0, 0, 255);
1673 //murphy_wideline(map_buffer, line_width, height, cx, cy, cx + dm, cy + dl, color, ww);
1674 //c_draw_line3_fast(map_buffer, line_width, height, cx, cy, cx + dm, cy + dl, 255, 0, 0, 255);
1675 drawThickLine(map_buffer, line_width, height, cx, cy, cx + dm, cy + dl, ww, LINE_THICKNESS_MIDDLE, color);
1676 dbg(0,"bitmap:ru steil\n");
1677
1678
1679 // nach: rechts unten flach (grün)
1680 dbg(0,"bitmap:ru flach\n");
1681 color = createPixel(0, 255, 0, 255);
1682 //murphy_wideline(map_buffer, line_width, height, cx, cy, cx + dl, cy + dm, color, ww);
1683 //c_draw_line3_fast(map_buffer, line_width, height, cx, cy, cx + dl, cy + dm, 0, 255, 0, 255);
1684 drawThickLine(map_buffer, line_width, height, cx, cy, cx + dl, cy + dm, ww, LINE_THICKNESS_MIDDLE, color);
1685
1686 dbg(0,"bitmap:ru flach\n");
1687
1688
1689 // nach: rechts oben flach (blau) XX
1690 dbg(0,"bitmap:ro flach\n");
1691 color = createPixel(0, 0, 255, 255);
1692 //murphy_wideline(map_buffer, line_width, height, cx, cy, cx + dl, cy - dm, color, ww);
1693 //c_draw_line3_fast(map_buffer, line_width, height, cx, cy, cx + dl, cy - dm, 0, 0, 255, 255);
1694 drawThickLine(map_buffer, line_width, height, cx, cy, cx + dl, cy - dm, ww, LINE_THICKNESS_MIDDLE, color);
1695 dbg(0,"bitmap:ro flach\n");
1696
1697
1698 // nach: rechts oben steil (türkis)
1699 dbg(0,"bitmap:ro steil\n");
1700 color = createPixel(0, 255, 255, 255);
1701 //murphy_wideline(map_buffer, line_width, height, cx, cy, cx + dm, cy - dl, color, 6);
1702 //c_draw_line3_fast(map_buffer, line_width, height, cx, cy, cx + dm, cy - dl, 0, 255, 255, 255);
1703 drawThickLine(map_buffer, line_width, height, cx, cy, cx + dm, cy - dl, ww, LINE_THICKNESS_MIDDLE, color);
1704 dbg(0,"bitmap:ro steil\n");
1705
1706
1707 // nach: links oben steil (schwarz)
1708 dbg(0,"bitmap:lo steil\n");
1709 color = createPixel(0, 0, 0, 255);
1710 //murphy_wideline(map_buffer, line_width, height, cx, cy, cx - dm, cy - dl, color, ww);
1711 //c_draw_line3_fast(map_buffer, line_width, height, cx, cy, cx - dm, cy - dl, 0, 0, 0, 255);
1712 drawThickLine(map_buffer, line_width, height, cx, cy, cx - dm, cy - dl, ww, LINE_THICKNESS_MIDDLE, color);
1713 dbg(0,"bitmap:lo steil\n");
1714
1715
1716 // nach: links oben flach (pink)
1717 dbg(0,"bitmap:lo flach\n");
1718 color = createPixel(255, 0, 255, 255);
1719 //murphy_wideline(map_buffer, line_width, height, cx, cy, cx - dl, cy - dm, color, ww);
1720 //c_draw_line3_fast(map_buffer, line_width, height, cx, cy, cx - dl, cy - dm, 255, 0, 255, 255);
1721 drawThickLine(map_buffer, line_width, height, cx, cy, cx - dl, cy - dm, ww, LINE_THICKNESS_MIDDLE, color);
1722 dbg(0,"bitmap:lo flach\n");
1723
1724 // nach: links unten flach (braun) XX
1725 dbg(0,"bitmap:lu flach\n");
1726 color = createPixel(130, 78, 6, 255);
1727 //murphy_wideline(map_buffer, line_width, height, cx, cy, cx - dl, cy + dm, color, ww);
1728 //c_draw_line3_fast(map_buffer, line_width, height, cx, cy, cx - dl, cy + dm, 130, 78, 6, 255);
1729 drawThickLine(map_buffer, line_width, height, cx, cy, cx - dl, cy + dm, ww, LINE_THICKNESS_MIDDLE, color);
1730 dbg(0,"bitmap:lu flach\n");
1731 #endif
1732
1733 }
1734 #endif
1735
1736
1737 /*
1738 *
1739 *
1740 * ********* DRAW normal lines *********
1741 *
1742 *
1743 */
1744 static void draw_lines3(struct graphics_priv *gra, struct graphics_gc_priv *gc, struct point *p, int count, int order, int width, int dashes, struct color *c, int clinedrawing_mode_active, int with_end)
1745 {
1746 //DBG // dbg(0,"EEnter\n");
1747 int i;
1748 if (count <= 0)
1749 {
1750 return;
1751 }
1752
1753 // dbg(0, "count=%d\n", count);
1754
1755 JNIEnv *jnienv2;
1756 jnienv2 = jni_getenv();
1757
1758 if (clinedrawing_mode_active)
1759 {
1760
1761 // ---------- c linedrawing ------------
1762 // ---------- c linedrawing ------------
1763 // ---------- c linedrawing ------------
1764 // ---------- c linedrawing ------------
1765 // ---------- c linedrawing ------------
1766
1767
1768 if (main_map_bitmapinfo == NULL)
1769 {
1770 int ret;
1771 main_map_bitmapinfo = &main_map_bitmapinfo2;
1772
1773 if ((ret = AndroidBitmap_getInfo(jnienv2, main_map_bitmap, main_map_bitmapinfo)) < 0)
1774 {
1775 //dbg(0, "AndroidBitmap_getInfo() failed ! error=%d", ret);
1776 // main_map_bitmapinfo = NULL;
1777 }
1778
1779 //dbg(0, "bitmap image :: width is %d; height is %d; stride is %d; format is %d;flags is %d", main_map_bitmapinfo2.width,main_map_bitmapinfo2.height,main_map_bitmapinfo2.stride,main_map_bitmapinfo2.format,main_map_bitmapinfo2.flags);
1780
1781 if (main_map_bitmapinfo2.format == ANDROID_BITMAP_FORMAT_RGBA_8888)
1782 {
1783 //dbg(0, "Bitmap format is RGBA_8888 !");
1784 }
1785 else if (main_map_bitmapinfo2.format == ANDROID_BITMAP_FORMAT_RGB_565)
1786 {
1787 //dbg(0, "Bitmap format is RGB_565 !");
1788 }
1789 else if (main_map_bitmapinfo2.format == ANDROID_BITMAP_FORMAT_RGBA_4444)
1790 {
1791 //dbg(0, "Bitmap format is RGBA_4444 !");
1792 }
1793 }
1794
1795
1796 if (main_map_bitmapinfo != NULL)
1797 {
1798 int ret;
1799 void* pixels;
1800
1801 if ((ret = AndroidBitmap_lockPixels(jnienv2, main_map_bitmap, &pixels)) < 0)
1802 {
1803 // dbg(0, "AndroidBitmap_lockPixels() failed ! error=%d", ret);
1804 }
1805 else
1806 {
1807 if (count > 1)
1808 {
1809 uint32_t color = createPixel(c->r >> 8, c->g >> 8, c->b >> 8, c->a >> 8);
1810
1811 for (i = 0; i < (count - 1); i++)
1812 {
1813 // drawThickLine ((uint32_t*)pixels, main_map_bitmapinfo->width, main_map_bitmapinfo->height, p[i].x, p[i].y, p[i + 1].x, p[i + 1].y, width, LINE_THICKNESS_MIDDLE, color, c->a >> 8);
1814 drawThickLineSimple((uint32_t*)pixels, main_map_bitmapinfo->width, main_map_bitmapinfo->height, p[i].x, p[i].y, p[i + 1].x, p[i + 1].y, width, LINE_THICKNESS_MIDDLE, color, c->a >> 8);
1815 //c_draw_line3_fast((uint32_t*)pixels, main_map_bitmapinfo->width, main_map_bitmapinfo->height, p[i].x, p[i].y, p[i + 1].x, p[i + 1].y, 0, 0, 0, 255);
1816 }
1817 }
1818 else
1819 {
1820 // dbg(0, "bitmap:b line count=%d\n", count);
1821 }
1822
1823 AndroidBitmap_unlockPixels(jnienv2, main_map_bitmap);
1824 }
1825 }
1826 // ---------- c linedrawing ------------
1827 // ---------- c linedrawing ------------
1828 // ---------- c linedrawing ------------
1829 // ---------- c linedrawing ------------
1830 // ---------- c linedrawing ------------
1831
1832 }
1833 else
1834 {
1835
1836
1837 // ------- java linedrawing ------------
1838 // ------- java linedrawing ------------
1839 // ------- java linedrawing ------------
1840 // ------- java linedrawing ------------
1841 // ------- java linedrawing ------------
1842
1843
1844 jintArray points;
1845 jint pc[count * 2];
1846
1847 points = (*jnienv2)->NewIntArray(jnienv2, count * 2);
1848 for (i = 0; i < count; i++)
1849 {
1850 pc[i * 2] = p[i].x;
1851 pc[i * 2 + 1] = p[i].y;
1852 }
1853 (*jnienv2)->SetIntArrayRegion(jnienv2, points, 0, count * 2, pc);
1854 (*jnienv2)->CallVoidMethod(jnienv2, gra->NavitGraphics, gra->NavitGraphics_draw_polyline3, points, order, width, dashes, c->r >> 8, c->g >> 8, c->b >> 8, c->a >> 8, with_end);
1855 (*jnienv2)->DeleteLocalRef(jnienv2, points);
1856
1857 // ------- java linedrawing ------------
1858 // ------- java linedrawing ------------
1859 // ------- java linedrawing ------------
1860 // ------- java linedrawing ------------
1861 // ------- java linedrawing ------------
1862
1863 }
1864
1865 }
1866
1867 static void draw_lines4(struct graphics_priv *gra, struct graphics_gc_priv *gc, struct point *p, int count, int order, int width, int type, int dashes, struct color *c, int with_end)
1868 {
1869 //DBG // dbg(0,"EEnter\n");
1870
1871 // draw tunnel-street or bridge-street
1872 // type:1 -> tunnel
1873 // type:2 -> bridge
1874 // ------------------------------------------
1875 // type > 90 -> some signal (not a real line)
1876
1877 JNIEnv *jnienv2;
1878 jnienv2 = jni_getenv();
1879
1880
1881 if (type > 90)
1882 {
1883 // "***" signal
1884 (*jnienv2)->CallVoidMethod(jnienv2, gra->NavitGraphics, gra->NavitGraphics_draw_polyline4, NULL, order, width, type, 0, 0, 0, 0, 0, with_end);
1885 }
1886 else
1887 {
1888 jint pc[count * 2];
1889 int i;
1890 jintArray points;
1891 if (count <= 0)
1892 {
1893 return;
1894 }
1895 points = (*jnienv2)->NewIntArray(jnienv2, count * 2);
1896 for (i = 0; i < count; i++)
1897 {
1898 pc[i * 2] = p[i].x;
1899 pc[i * 2 + 1] = p[i].y;
1900 }
1901 // initPaint(gra, gc);
1902 (*jnienv2)->SetIntArrayRegion(jnienv2, points, 0, count * 2, pc);
1903 (*jnienv2)->CallVoidMethod(jnienv2, gra->NavitGraphics, gra->NavitGraphics_draw_polyline4, points, order, width, type, dashes, c->r >> 8, c->g >> 8, c->b >> 8, c->a >> 8, with_end);
1904 (*jnienv2)->DeleteLocalRef(jnienv2, points);
1905 }
1906 }
1907
1908 // ---------------------------------
1909 // draw oneway arrow ---------------
1910 // ---------------------------------
1911 static void draw_lines2(struct graphics_priv *gra, struct graphics_gc_priv *gc, struct point *p, int count, int order, int oneway)
1912 {
1913 // dbg(0,"EEnter\n");
1914 jint pc[count * 2];
1915 int i;
1916 jintArray points;
1917 if (count <= 0)
1918 {
1919 return;
1920 }
1921
1922 JNIEnv *jnienv2;
1923 jnienv2 = jni_getenv();
1924
1925 points = (*jnienv2)->NewIntArray(jnienv2, count * 2);
1926 for (i = 0; i < count; i++)
1927 {
1928 pc[i * 2] = p[i].x;
1929 pc[i * 2 + 1] = p[i].y;
1930 }
1931 // initPaint(gra, gc);
1932 (*jnienv2)->SetIntArrayRegion(jnienv2, points, 0, count * 2, pc);
1933 (*jnienv2)->CallVoidMethod(jnienv2, gra->NavitGraphics, gra->NavitGraphics_draw_polyline2, points, order, oneway);
1934 (*jnienv2)->DeleteLocalRef(jnienv2, points);
1935 }
1936
1937 static void draw_lines_dashed(struct graphics_priv *gra, struct graphics_gc_priv *gc, struct point *p, int count, int order, int oneway)
1938 {
1939 jint pc[count * 2];
1940 int i;
1941 jintArray points;
1942 if (count <= 0)
1943 return;
1944
1945 JNIEnv *jnienv2;
1946 jnienv2 = jni_getenv();
1947
1948 points = (*jnienv2)->NewIntArray(jnienv2, count * 2);
1949 for (i = 0; i < count; i++)
1950 {
1951 pc[i * 2] = p[i].x;
1952 pc[i * 2 + 1] = p[i].y;
1953 }
1954 initPaint(gra, gc);
1955 (*jnienv2)->SetIntArrayRegion(jnienv2, points, 0, count * 2, pc);
1956 (*jnienv2)->CallVoidMethod(jnienv2, gra->NavitGraphics, gra->NavitGraphics_draw_polyline_dashed, gc->gra->Paint, points, order, oneway);
1957 (*jnienv2)->DeleteLocalRef(jnienv2, points);
1958 }
1959
1960 static void draw_polygon(struct graphics_priv *gra, struct graphics_gc_priv *gc, struct point *p, int count)
1961 {
1962 jint pc[count * 2];
1963 int i;
1964 jintArray points;
1965 if (count <= 0)
1966 return;
1967
1968 JNIEnv *jnienv2;
1969 jnienv2 = jni_getenv();
1970
1971 points = (*jnienv2)->NewIntArray(jnienv2, count * 2);
1972 for (i = 0; i < count; i++)
1973 {
1974 pc[i * 2] = p[i].x;
1975 pc[i * 2 + 1] = p[i].y;
1976 }
1977
1978 // dbg(0, "CCCC:%d %d %d %d\n", gc->r, gc->g, gc->b, gc->a);
1979
1980 // initPaint(gra, gc);
1981 (*jnienv2)->SetIntArrayRegion(jnienv2, points, 0, count * 2, pc);
1982 (*jnienv2)->CallVoidMethod(jnienv2, gra->NavitGraphics, gra->NavitGraphics_draw_polygon, points, gc->linewidth, gc->r, gc->g, gc->b, gc->a);
1983 (*jnienv2)->DeleteLocalRef(jnienv2, points);
1984 }
1985
1986
1987 /* not used anymore */
1988 /* not used anymore */
1989 static void draw_polygon2(struct graphics_priv *gra, struct graphics_gc_priv *gc, struct point *p, int count, int order, int oneway)
1990 {
1991 jint pc[count * 2];
1992 int i;
1993 jintArray points;
1994 if (count <= 0)
1995 return;
1996
1997 JNIEnv *jnienv2;
1998 jnienv2 = jni_getenv();
1999
2000 points = (*jnienv2)->NewIntArray(jnienv2, count * 2);
2001 for (i = 0; i < count; i++)
2002 {
2003 pc[i * 2] = p[i].x;
2004 pc[i * 2 + 1] = p[i].y;
2005 }
2006 initPaint(gra, gc);
2007 (*jnienv2)->SetIntArrayRegion(jnienv2, points, 0, count * 2, pc);
2008 (*jnienv2)->CallVoidMethod(jnienv2, gra->NavitGraphics, gra->NavitGraphics_draw_polygon2, gc->gra->Paint, points, order, oneway);
2009 (*jnienv2)->DeleteLocalRef(jnienv2, points);
2010 }
2011
2012 static void draw_rectangle(struct graphics_priv *gra, struct graphics_gc_priv *gc, struct point *p, int w, int h)
2013 {
2014 JNIEnv *jnienv2;
2015 jnienv2 = jni_getenv();
2016
2017 initPaint(gra, gc);
2018 (*jnienv2)->CallVoidMethod(jnienv2, gra->NavitGraphics, gra->NavitGraphics_draw_rectangle, gc->gra->Paint, p->x, p->y, w, h);
2019 }
2020
2021 static void draw_circle(struct graphics_priv *gra, struct graphics_gc_priv *gc, struct point *p, int r)
2022 {
2023 JNIEnv *jnienv2;
2024 jnienv2 = jni_getenv();
2025
2026 // use gc->linewidth as width;
2027
2028 initPaint(gra, gc);
2029 (*jnienv2)->CallVoidMethod(jnienv2, gra->NavitGraphics, gra->NavitGraphics_draw_circle, gc->gra->Paint, p->x, p->y, r);
2030 }
2031
2032 static void draw_text(struct graphics_priv *gra, struct graphics_gc_priv *fg, struct graphics_gc_priv *bg, struct graphics_font_priv *font, char *text, struct point *p, int dx, int dy)
2033 {
2034 //// dbg(1, "enter %s\n", text);
2035 JNIEnv *jnienv2;
2036 jnienv2 = jni_getenv();
2037
2038 // initPaint(gra, fg);
2039 jstring string = (*jnienv2)->NewStringUTF(jnienv2, text);
2040 (*jnienv2)->CallVoidMethod(jnienv2, gra->NavitGraphics, gra->NavitGraphics_draw_text, p->x, p->y, string, font->size, dx, dy, fg->r, fg->g, fg->b, fg->a);
2041 (*jnienv2)->DeleteLocalRef(jnienv2, string);
2042 }
2043
2044 static void draw_image(struct graphics_priv *gra, struct graphics_gc_priv *fg, struct point *p, struct graphics_image_priv *img)
2045 {
2046 //DBG // dbg(0,"EEnter\n");
2047
2048 JNIEnv *jnienv2;
2049 jnienv2 = jni_getenv();
2050
2051 //// dbg(1, "enter %p\n", img);
2052 // initPaint(gra, fg);
2053 (*jnienv2)->CallVoidMethod(jnienv2, gra->NavitGraphics, gra->NavitGraphics_draw_image, p->x, p->y, img->Bitmap, fg->r, fg->g, fg->b, fg->a);
2054
2055 }
2056
2057 static void draw_bigmap(struct graphics_priv *gra, struct graphics_gc_priv *fg, int yaw, int order, float clat, float clng, int x, int y, int scx, int scy, int px, int py, int valid)
2058 {
2059 //DBG // dbg(0,"EEnter\n");
2060
2061 JNIEnv *jnienv2;
2062 jnienv2 = jni_getenv();
2063
2064 (*jnienv2)->CallVoidMethod(jnienv2, gra->NavitGraphics, gra->NavitGraphics_draw_bigmap, yaw, order, clat, clng, x, y, scx, scy, px, py, valid);
2065
2066 //DBG // dbg(0,"leave\n");
2067 }
2068
2069 static void draw_image_warp(struct graphics_priv *gr, struct graphics_gc_priv *fg, struct point *p, int count, char *data)
2070 {
2071 //dbg(0,"draw_image_warp:filename=%s\n", data);
2072 //dbg(0,"draw_image_warp:count=%d\n", count);
2073
2074 /*
2075 void imlib_render_image_on_drawable_skewed(int source_x, int source_y,
2076 int source_width,
2077 int source_height,
2078 int destination_x,
2079 int destination_y,
2080 int h_angle_x, int h_angle_y,
2081 int v_angle_x, int v_angle_y);
2082
2083 if (count == 3) {
2084 imlib_render_image_on_drawable_skewed(0, 0, w, h, p[0].x, p[0].y, p[1].x-p[0].x, p[1].y-p[0].y, p[2].x-p[0].x, p[2].y-p[0].y);
2085 }
2086 if (count == 2) {
2087 imlib_render_image_on_drawable_skewed(0, 0, w, h, p[0].x, p[0].y, p[1].x-p[0].x, 0, 0, p[1].y-p[0].y);
2088 }
2089 if (count == 1) {
2090 imlib_render_image_on_drawable_skewed(0, 0, w, h, p[0].x-w/2, p[0].y-h/2, w, 0, 0, h);
2091 }
2092
2093 */
2094
2095 JNIEnv *jnienv2;
2096 jnienv2 = jni_getenv();
2097
2098 jstring string = (*jnienv2)->NewStringUTF(jnienv2, data);
2099
2100 if (count == 3)
2101 {
2102 /* 0 1
2103 2 */
2104 (*jnienv2)->CallVoidMethod(jnienv2, gr->NavitGraphics, gr->NavitGraphics_draw_image_warp, string, count, p[0].x, p[0].y, p[1].x, p[1].y, p[2].x, p[2].y);
2105 }
2106 else if (count == 2)
2107 {
2108 /* 0
2109 1 */
2110 (*jnienv2)->CallVoidMethod(jnienv2, gr->NavitGraphics, gr->NavitGraphics_draw_image_warp, string, count, p[0].x, p[0].y, p[1].x, p[1].y, 0, 0);
2111 }
2112 else if (count == 1)
2113 {
2114 /*
2115 0
2116 */
2117 (*jnienv2)->CallVoidMethod(jnienv2, gr->NavitGraphics, gr->NavitGraphics_draw_image_warp, string, count, p[0].x, p[0].y, 0, 0, 0, 0);
2118 }
2119
2120 (*jnienv2)->DeleteLocalRef(jnienv2, string);
2121
2122 }
2123
2124 static void draw_restore(struct graphics_priv *gr, struct point *p, int w, int h)
2125 {
2126 }
2127
2128 static void draw_drag(struct graphics_priv *gra, struct point *p)
2129 {
2130 //DBG // dbg(0,"EEnter\n");
2131 JNIEnv *jnienv2;
2132 jnienv2 = jni_getenv();
2133
2134 (*jnienv2)->CallVoidMethod(jnienv2, gra->NavitGraphics, gra->NavitGraphics_draw_drag, p ? p->x : 0, p ? p->y : 0);
2135 }
2136
2137 static void background_gc(struct graphics_priv *gr, struct graphics_gc_priv *gc)
2138 {
2139 }
2140
2141 static void draw_mode(struct graphics_priv *gra, enum draw_mode_num mode)
2142 {
2143 //DBG // dbg(0,"EEnter\n");
2144 JNIEnv *jnienv2;
2145 jnienv2 = jni_getenv();
2146
2147 (*jnienv2)->CallVoidMethod(jnienv2, gra->NavitGraphics, gra->NavitGraphics_draw_mode, (int) mode);
2148 }
2149
2150 static struct graphics_priv * overlay_new(const char* name, struct graphics_priv *gr, struct graphics_methods *meth, struct point *p, int w, int h, int alpha, int wraparound);
2151
2152 static void *
2153 get_data(struct graphics_priv *this, const char *type)
2154 {
2155 //DBG // dbg(0,"EEnter\n");
2156
2157 if (strcmp(type, "window"))
2158 {
2159 return NULL;
2160 }
2161
2162 return &this->win;
2163 }
2164
2165 static void image_free(struct graphics_priv *gr, struct graphics_image_priv *priv)
2166 {
2167 }
2168
2169 static void get_text_bbox(struct graphics_priv *gr, struct graphics_font_priv *font, char *text, int dx, int dy, struct point *ret, int estimate)
2170 {
2171 ////DBG // dbg(0,"EEnter\n");
2172
2173 // this is a rough estimate!! otherwise java methods would be called, and thats too slow!
2174
2175 int len = g_utf8_strlen(text, -1);
2176 int xMin = 0;
2177 int yMin = 0;
2178 int yMax = 13 * font->size / 256;
2179 int xMax = 9 * font->size * len / 256;
2180
2181 ret[0].x = xMin;
2182 ret[0].y = -yMin;
2183 ret[1].x = xMin;
2184 ret[1].y = -yMax;
2185 ret[2].x = xMax;
2186 ret[2].y = -yMax;
2187 ret[3].x = xMax;
2188 ret[3].y = -yMin;
2189 }
2190
2191 static void overlay_disable(struct graphics_priv *gra, int disable)
2192 {
2193 // UNUSED ----
2194
2195 //DBG // dbg(0,"EEnter\n");
2196 //JNIEnv *jnienv2;
2197 //jnienv2 = jni_getenv();
2198 //
2199 //(*jnienv2)->CallVoidMethod(jnienv2, gra->NavitGraphics, gra->NavitGraphics_overlay_disable, disable);
2200 }
2201
2202 static void overlay_resize(struct graphics_priv *gra, struct point *pnt, int w, int h, int alpha, int wraparound)
2203 {
2204 // UNUSED ----
2205
2206 //DBG // dbg(0,"EEnter\n");
2207 //JNIEnv *jnienv2;
2208 //jnienv2 = jni_getenv();
2209 //
2210 //(*jnienv2)->CallVoidMethod(jnienv2, gra->NavitGraphics, gra->NavitGraphics_overlay_resize, pnt ? pnt->x : 0, pnt ? pnt->y : 0, w, h, alpha, wraparound);
2211 }
2212
2213 static int set_attr(struct graphics_priv *gra, struct attr *attr)
2214 {
2215 //DBG // dbg(0,"EEnter\n");
2216 JNIEnv *jnienv2;
2217 jnienv2 = jni_getenv();
2218
2219 switch (attr->type)
2220 {
2221 case attr_use_camera:
2222 (*jnienv2)->CallVoidMethod(jnienv2, gra->NavitGraphics, gra->NavitGraphics_SetCamera, attr->u.num);
2223 return 1;
2224 default:
2225 return 0;
2226 }
2227 }
2228
2229 static struct graphics_methods graphics_methods =
2230 { graphics_destroy, draw_mode, draw_lines, draw_lines2, draw_lines3, draw_lines4, draw_lines_dashed, draw_polygon, draw_polygon2, draw_rectangle, draw_circle, draw_text, draw_image, draw_bigmap, draw_image_warp, draw_restore, draw_drag, font_new, gc_new, background_gc, overlay_new, image_new, get_data,
2231 image_free, get_text_bbox, overlay_disable, overlay_resize, set_attr, };
2232
2233 /*
2234 static void resize_callback(struct graphics_priv *gra, int w, int h)
2235 {
2236 //DBG // dbg(0,"EEnter\n");
2237 // //DBG // dbg(0,"w=%d h=%d ok\n",w,h);
2238 // callback_list_call_attr_2(gra->cbl, attr_resize, (void *) w, (void *) h);
2239 navit_resize(attr_resize, this_);
2240 }
2241 */
2242
2243 /*
2244 static void motion_callback(struct graphics_priv *gra, int x, int y)
2245 {
2246 //DBG // dbg(0,"EEnter\n");
2247
2248 struct point p;
2249 p.x = x;
2250 p.y = y;
2251 callback_list_call_attr_1(gra->cbl, attr_motion, (void *) &p);
2252 }
2253 */
2254
2255 /*
2256 static void keypress_callback(struct graphics_priv *gra, char *s)
2257 {
2258 //DBG // dbg(0,"EEnter\n");
2259 callback_list_call_attr_1(gra->cbl, attr_keypress, s);
2260 }
2261 */
2262
2263 /*
2264 static void button_callback(struct graphics_priv *gra, int pressed, int button, int x, int y)
2265 {
2266 //DBG // dbg(0,"EEnter\n");
2267
2268 struct point p;
2269 p.x = x;
2270 p.y = y;
2271 // //DBG // dbg(0,"XXXXXXXYYYYYYYYY\n");
2272 callback_list_call_attr_3(gra->cbl, attr_button, (void *) pressed, (void *) button, (void *) &p);
2273 }
2274 */
2275
2276 static int set_activity(jobject graphics)
2277 {
2278 // dbg(0,"EEnter\n");
2279 // ---- DISABLED -------
2280 return 1;
2281 }
2282
2283 static int graphics_android_init(const char* name, struct graphics_priv *ret, struct graphics_priv *parent, struct point *pnt, int w, int h, int alpha, int wraparound, int use_camera)
2284 {
2285 struct callback *cb;
2286
2287 // overwrite JNIenv!!
2288 JNIEnv *jnienv2;
2289 jnienv2 = jni_getenv();
2290
2291 // dbg(0, "at 2 jnienv2=%p\n", jnienv2);
2292 int thread_id = gettid();
2293 // dbg(0, "THREAD ID=%d\n", thread_id);
2294
2295 //DBG // dbg(0,"a1\n");
2296 if (!find_class_global("android/graphics/Paint", &ret->PaintClass))
2297 return 0;
2298 //DBG // dbg(0,"a2\n");
2299 if (!find_method(ret->PaintClass, "<init>", "(I)V", &ret->Paint_init))
2300 return 0;
2301 //DBG // dbg(0,"a3\n");
2302 if (!find_method(ret->PaintClass, "setARGB", "(IIII)V", &ret->Paint_setARGB))
2303 return 0;
2304 //DBG // dbg(0,"a4\n");
2305 if (!find_method(ret->PaintClass, "setStrokeWidth", "(F)V", &ret->Paint_setStrokeWidth))
2306 return 0;
2307
2308 //DBG // dbg(0,"a4.1\n");
2309 if (!find_class_global("android/graphics/BitmapFactory", &ret->BitmapFactoryClass))
2310 return 0;
2311 //DBG // dbg(0,"a4.2\n");
2312 if (!find_static_method(ret->BitmapFactoryClass, "decodeFile", "(Ljava/lang/String;)Landroid/graphics/Bitmap;", &ret->BitmapFactory_decodeFile))
2313 return 0;
2314 //DBG // dbg(0,"a4.3\n");
2315 if (!find_static_method(ret->BitmapFactoryClass, "decodeResource", "(Landroid/content/res/Resources;I)Landroid/graphics/Bitmap;", &ret->BitmapFactory_decodeResource))
2316 return 0;
2317
2318 //DBG // dbg(0,"a4.4\n");
2319 if (!find_class_global("android/graphics/Bitmap", &ret->BitmapClass))
2320 return 0;
2321 //DBG // dbg(0,"a4.5\n");
2322 if (!find_method(ret->BitmapClass, "getHeight", "()I", &ret->Bitmap_getHeight))
2323 return 0;
2324 //DBG // dbg(0,"a4.6\n");
2325 if (!find_method(ret->BitmapClass, "getWidth", "()I", &ret->Bitmap_getWidth))
2326 return 0;
2327 //DBG // dbg(0,"a4.7\n");
2328 if (!find_class_global("android/content/Context", &ret->ContextClass))
2329 return 0;
2330 //DBG // dbg(0,"a4.8\n");
2331 if (!find_method(ret->ContextClass, "getResources", "()Landroid/content/res/Resources;", &ret->Context_getResources))
2332 return 0;
2333 //DBG // dbg(0,"a5\n");
2334 ret->Resources = (*jnienv2)->CallObjectMethod(jnienv2, android_activity, ret->Context_getResources);
2335 //DBG // dbg(0,"a6\n");
2336 if (ret->Resources)
2337 {
2338 ret->Resources = (*jnienv2)->NewGlobalRef(jnienv2, ret->Resources);
2339 }
2340 //DBG // dbg(0,"a7\n");
2341 if (!find_class_global("android/content/res/Resources", &ret->ResourcesClass))
2342 return 0;
2343 //DBG // dbg(0,"a8\n");
2344 if (!find_method(ret->ResourcesClass, "getIdentifier", "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)I", &ret->Resources_getIdentifier))
2345 return 0;
2346 //DBG // dbg(0,"a9\n");
2347 if (!find_class_global("com/zoffcc/applications/zanavi/NavitGraphics", &ret->NavitGraphicsClass))
2348 return 0;
2349 //DBG // dbg(0, "at 3\n");
2350
2351
2352 // --------------- Init the new Graphics Object here -----------------
2353 // --------------- Init the new Graphics Object here -----------------
2354 // --------------- Init the new Graphics Object here -----------------
2355 // dbg(0,"Init the new Graphics Object here: %s\n", name);
2356
2357 //DBG // dbg(0, "at 4 android_activity=%p\n", android_activity);
2358
2359
2360
2361
2362 if (NavitClass2 == NULL)
2363 {
2364 if (!android_find_class_global("com/zoffcc/applications/zanavi/Navit", &NavitClass2))
2365 {
2366 NavitClass2 = NULL;
2367 return 0;
2368 }
2369 }
2370
2371 if (!find_static_method(NavitClass2, "get_graphics_object_by_name", "(Ljava/lang/String;)Lcom/zoffcc/applications/zanavi/NavitGraphics;", &Navit_get_graphics_object_by_name))
2372 return 0;
2373
2374
2375 /// --old-- ret->NavitGraphics = (*jnienv2)->NewObject(jnienv2, ret->NavitGraphicsClass, cid, android_activity, parent ? parent->NavitGraphics : NULL, pnt ? pnt->x : 0, pnt ? pnt->y : 0, w, h, alpha, wraparound, use_camera);
2376
2377 /// --new--
2378 jstring string = (*jnienv2)->NewStringUTF(jnienv2, name);
2379 ret->NavitGraphics = (*jnienv2)->CallStaticObjectMethod(jnienv2, NavitClass2, Navit_get_graphics_object_by_name, string);
2380 (*jnienv2)->DeleteLocalRef(jnienv2, string);
2381 /// --new--
2382
2383
2384 // dbg(0, "result=%p\n", ret->NavitGraphics);
2385 if (ret->NavitGraphics)
2386 {
2387 ret->NavitGraphics = (*jnienv2)->NewGlobalRef(jnienv2, ret->NavitGraphics);
2388 }
2389
2390 // --------------- Init the new Graphics Object here -----------------
2391 // --------------- Init the new Graphics Object here -----------------
2392 // --------------- Init the new Graphics Object here -----------------
2393
2394
2395
2396
2397
2398
2399 /* Create a single global Paint, otherwise android will quickly run out
2400 * of global refs.*/
2401 /* 0x101 = text kerning (default), antialiasing */
2402 ret->Paint = (*jnienv2)->NewObject(jnienv2, ret->PaintClass, ret->Paint_init, 0x101);
2403
2404 //DBG // dbg(0, "l result=%p\n", ret->Paint);
2405 if (ret->Paint)
2406 {
2407 ret->Paint = (*jnienv2)->NewGlobalRef(jnienv2, ret->Paint);
2408 }
2409 //DBG // dbg(0, "g result=%p\n", ret->Paint);
2410
2411
2412 // public Bitmap rotate_and_scale_bitmap(Bitmap in, int w, int h, int angle)
2413
2414 if (!find_static_method(ret->NavitGraphicsClass, "rotate_and_scale_bitmap", "(Landroid/graphics/Bitmap;III)Landroid/graphics/Bitmap;", &ret->NavitGraphicsClass_rotate_and_scale_bitmap))
2415 return 0;
2416 if (!find_method(ret->NavitGraphicsClass, "draw_polyline", "([IIIIII)V", &ret->NavitGraphics_draw_polyline))
2417 return 0;
2418 if (!find_method(ret->NavitGraphicsClass, "draw_polyline2", "([III)V", &ret->NavitGraphics_draw_polyline2))
2419 return 0;
2420 if (!find_method(ret->NavitGraphicsClass, "draw_polyline3", "([IIIIIIIII)V", &ret->NavitGraphics_draw_polyline3))
2421 return 0;
2422 if (!find_method(ret->NavitGraphicsClass, "draw_polyline4", "([IIIIIIIIII)V", &ret->NavitGraphics_draw_polyline4))
2423 return 0;
2424 if (!find_method(ret->NavitGraphicsClass, "draw_polyline_dashed", "(Landroid/graphics/Paint;[III)V", &ret->NavitGraphics_draw_polyline_dashed))
2425 return 0;
2426 if (!find_method(ret->NavitGraphicsClass, "set_dashes", "(Landroid/graphics/Paint;II)V", &ret->NavitGraphics_set_dashes))
2427 return 0;
2428 if (!find_method(ret->NavitGraphicsClass, "draw_polygon", "([IIIIII)V", &ret->NavitGraphics_draw_polygon))
2429 return 0;
2430 if (!find_method(ret->NavitGraphicsClass, "draw_polygon2", "(Landroid/graphics/Paint;[III)V", &ret->NavitGraphics_draw_polygon2))
2431 return 0;
2432 if (!find_method(ret->NavitGraphicsClass, "draw_rectangle", "(Landroid/graphics/Paint;IIII)V", &ret->NavitGraphics_draw_rectangle))
2433 return 0;
2434 if (!find_method(ret->NavitGraphicsClass, "draw_circle", "(Landroid/graphics/Paint;III)V", &ret->NavitGraphics_draw_circle))
2435 return 0;
2436 if (!find_method(ret->NavitGraphicsClass, "draw_text", "(IILjava/lang/String;IIIIIII)V", &ret->NavitGraphics_draw_text))
2437 return 0;
2438 if (!find_method(ret->NavitGraphicsClass, "draw_image", "(IILandroid/graphics/Bitmap;IIII)V", &ret->NavitGraphics_draw_image))
2439 return 0;
2440 if (!find_method(ret->NavitGraphicsClass, "draw_bigmap", "(IIFFIIIIIII)V", &ret->NavitGraphics_draw_bigmap))
2441 return 0;
2442 if (!find_method(ret->NavitGraphicsClass, "draw_warp", "(Ljava/lang/String;IIIIIII)V", &ret->NavitGraphics_draw_image_warp))
2443 return 0;
2444
2445 if (!find_method(ret->NavitGraphicsClass, "draw_mode", "(I)V", &ret->NavitGraphics_draw_mode))
2446 return 0;
2447 if (!find_method(ret->NavitGraphicsClass, "draw_drag", "(II)V", &ret->NavitGraphics_draw_drag))
2448 return 0;
2449 //if (!find_method(ret->NavitGraphicsClass, "overlay_disable", "(I)V", &ret->NavitGraphics_overlay_disable))
2450 // return 0;
2451 //if (!find_method(ret->NavitGraphicsClass, "overlay_resize", "(IIIIII)V", &ret->NavitGraphics_overlay_resize))
2452 // return 0;
2453 /*
2454 if (!find_method(ret->NavitGraphicsClass, "SetCamera", "(I)V", &ret->NavitGraphics_SetCamera))
2455 return 0;
2456 */
2457
2458 //DBG // dbg(0,"99\n");
2459 #if 0
2460 set_activity(ret->NavitGraphics);
2461 #endif
2462 return 1;
2463 }
2464
2465 static int graphics_android_fullscreen(struct window *win, int on)
2466 {
2467 return 1;
2468 }
2469
2470 static jclass NavitClass;
2471 static jmethodID Navit_disableSuspend, Navit_exit;
2472
2473 static void graphics_android_disable_suspend(struct window *win)
2474 {
2475 //DBG // dbg(0,"enter\n");
2476 JNIEnv *jnienv2;
2477 jnienv2 = jni_getenv();
2478
2479 (*jnienv2)->CallVoidMethod(jnienv2, android_activity, Navit_disableSuspend);
2480 }
2481
2482 struct graphics_priv *
2483 graphics_android_new(struct navit *nav, struct graphics_methods *meth, struct attr **attrs, struct callback_list *cbl)
2484 {
2485 // dbg(0,"EEnter\n");
2486
2487 int thread_id = gettid();
2488 // dbg(0, "THREAD ID=%d\n", thread_id);
2489
2490 struct graphics_priv *ret;
2491 struct attr *attr;
2492 int use_camera = 0;
2493
2494 // dbg(0,"event system - start\n");
2495 if (!event_request_system("android", "graphics_android"))
2496 {
2497 return NULL;
2498 }
2499 // dbg(0,"event system - end\n");
2500
2501 ret=g_new0(struct graphics_priv, 1);
2502 ret->cbl = cbl;
2503 *meth = graphics_methods;
2504 ret->win.priv = ret;
2505 ret->win.fullscreen = graphics_android_fullscreen;
2506 ret->win.disable_suspend = graphics_android_disable_suspend;
2507 if ((attr = attr_search(attrs, NULL, attr_use_camera)))
2508 {
2509 use_camera = attr->u.num;
2510 }
2511 image_cache_hash = g_hash_table_new(g_str_hash, g_str_equal);
2512
2513
2514 // --------------- try to get a new Graphics Object -----------------
2515 // --------------- try to get a new Graphics Object -----------------
2516 // --------------- try to get a new Graphics Object -----------------
2517 // dbg(0,"try to get a new Graphics Object\n");
2518 if (graphics_android_init("type:map-main", ret, NULL, NULL, 0, 0, 0, 0, use_camera))
2519 {
2520 ////DBG // dbg(0,"returning %p\n",ret);
2521 return ret;
2522 }
2523 else
2524 {
2525 g_free(ret);
2526 return NULL;
2527 }
2528 }
2529
2530 static struct graphics_priv *
2531 overlay_new(const char* name, struct graphics_priv *gr, struct graphics_methods *meth, struct point *p, int w, int h, int alpha, int wraparound)
2532 {
2533 // dbg(0,"EEnter\n");
2534
2535 int thread_id = gettid();
2536 // dbg(0, "THREAD ID=%d\n", thread_id);
2537
2538 struct graphics_priv *ret=g_new0(struct graphics_priv, 1);
2539 *meth = graphics_methods;
2540
2541 // --------------- try to get a new Graphics Object -----------------
2542 // --------------- try to get a new Graphics Object -----------------
2543 // --------------- try to get a new Graphics Object -----------------
2544 // dbg(0,"try to get a new Graphics Object: %s\n", name);
2545 if (graphics_android_init(name ,ret, gr, p, w, h, alpha, wraparound, 0))
2546 {
2547 // dbg(0, "returning %p\n", ret);
2548 return ret;
2549 }
2550 else
2551 {
2552 g_free(ret);
2553 return NULL;
2554 }
2555 }
2556
2557 static void event_android_main_loop_run(void)
2558 {
2559 // dbg(0, "enter\n");
2560 }
2561
2562 static void event_android_main_loop_quit(void)
2563 {
2564 // dbg(0, "enter\n");
2565
2566 // overwrite JNIenv!!
2567 JNIEnv *jnienv2;
2568 jnienv2 = jni_getenv();
2569
2570 int thread_id = gettid();
2571 // dbg(0, "THREAD ID=%d\n", thread_id);
2572
2573 // ******* exit(0);
2574 (*jnienv2)->CallVoidMethod(jnienv2, android_activity, Navit_exit);
2575 }
2576
2577 static jclass NavitTimeoutClass;
2578 static jmethodID NavitTimeout_init;
2579 static jmethodID NavitTimeout_remove;
2580
2581 static jclass NavitIdleClass;
2582 static jmethodID NavitIdle_init;
2583 static jmethodID NavitIdle_remove;
2584
2585 static jclass NavitWatchClass;
2586 static jmethodID NavitWatch_init;
2587 static jmethodID NavitWatch_remove;
2588
2589 static struct event_watch *
2590 event_android_add_watch(void *h, enum event_watch_cond cond, struct callback *cb)
2591 {
2592 // dbg(0,"enter\n");
2593 jobject ret;
2594 ret = (*jnienv)->NewObject(jnienv, NavitWatchClass, NavitWatch_init, (int) h, (int) cond, (int) cb);
2595 // //DBG // dbg(0,"result for %p,%d,%p=%p\n",h,cond,cb,ret);
2596 if (ret)
2597 {
2598 //DBG // dbg(0,"result for %p,%p\n",h,ret);
2599 ret = (*jnienv)->NewGlobalRef(jnienv, ret);
2600 //DBG // dbg(0,"g ret %p\n",ret);
2601 }
2602 return (struct event_watch *) ret;
2603 }
2604
2605 static void event_android_remove_watch(struct event_watch *ev)
2606 {
2607 // dbg(0,"enter\n");
2608 if (ev)
2609 {
2610 //DBG // dbg(0,"enter %p\n",ev);
2611 jobject obj = (jobject) ev;
2612 // maybe need this ? ICS obj = (*jnienv)->NewGlobalRef(jnienv, obj);
2613 (*jnienv)->CallVoidMethod(jnienv, obj, NavitWatch_remove);
2614 // ICS (*jnienv)->DeleteGlobalRef(jnienv, obj);
2615 }
2616 }
2617
2618 static struct event_timeout *
2619 event_android_add_timeout(int timeout, int multi, struct callback *cb)
2620 {
2621 // dbg(0,"EEnter\n");
2622
2623 // overwrite JNIenv!!
2624 JNIEnv *jnienv2;
2625 jnienv2 = jni_getenv();
2626
2627 int thread_id = gettid();
2628 // dbg(0, "THREAD ID=%d\n", thread_id);
2629
2630 // timeout -> delay in milliseconds
2631
2632 jobject ret;
2633 jobject ret_g = NULL;
2634 ret = (*jnienv2)->NewObject(jnienv2, NavitTimeoutClass, NavitTimeout_init, timeout, multi, (int) cb);
2635 //// dbg(0, "result for %d,%d,%p\n", timeout, multi, cb);
2636
2637 if (ret)
2638 {
2639 //// dbg(0,"l ret=%p\n",ret);
2640 ret_g = (*jnienv2)->NewGlobalRef(jnienv2, ret);
2641 // dbg(0,"g ret=%p\n",ret_g);
2642 }
2643 //// dbg(0,"leave\n");
2644 return (struct event_timeout *) ret_g;
2645 }
2646
2647 static void event_android_remove_timeout(struct event_timeout *to)
2648 {
2649 // dbg(0,"EEnter\n");
2650
2651 // overwrite JNIenv!!
2652 JNIEnv *jnienv2;
2653 jnienv2 = jni_getenv();
2654
2655 // int thread_id = gettid();
2656 // dbg(0, "THREAD ID=%d\n", thread_id);
2657
2658
2659 if (to)
2660 {
2661 // dbg(0, "remove %p\n", to);
2662 jobject obj = (jobject) to;
2663 (*jnienv2)->CallVoidMethod(jnienv2, obj, NavitTimeout_remove);
2664 // ICS
2665 //// dbg(0, "remove 1\n");
2666 (*jnienv2)->DeleteGlobalRef(jnienv2, obj);
2667 //// dbg(0, "remove 2\n");
2668 }
2669 }
2670
2671 static struct event_idle *
2672 event_android_add_idle(int priority, struct callback *cb)
2673 {
2674 // ----------------------------------------------------
2675 // ----------------------------------------------------
2676 // "priority" param is now misused here as "multi"
2677 // priority == 1000 -> set multi = 0
2678 // ----------------------------------------------------
2679 // ----------------------------------------------------
2680
2681 //// dbg(0,"EEnter\n");
2682
2683 #if 0
2684 jobject ret;
2685 // dbg(1,"enter\n");
2686 ret=(*jnienv)->NewObject(jnienv, NavitIdleClass, NavitIdle_init, (int)cb);
2687 // dbg(1,"result for %p=%p\n",cb,ret);
2688 if (ret)
2689 (*jnienv)->NewGlobalRef(jnienv, ret);
2690 return (struct event_idle *)ret;
2691 #endif
2692 // ----- xxxxxxxx ------
2693 if (priority == 1000)
2694 {
2695 //dbg(0,"event add idle timeout=10 multi=0\n", priority);
2696 return (struct event_idle *) event_android_add_timeout(10, 0, cb);
2697 }
2698 else
2699 {
2700 //dbg(0,"event add idle timeout=%d multi=1\n", priority);
2701 return (struct event_idle *) event_android_add_timeout(priority, 1, cb);
2702 }
2703 }
2704
2705 static void event_android_remove_idle(struct event_idle *ev)
2706 {
2707 //// dbg(0,"EEnter\n");
2708
2709 #if 0
2710 // dbg(1,"enter %p\n",ev);
2711 if (ev)
2712 {
2713 jobject obj=(jobject )ev;
2714 (*jnienv)->CallVoidMethod(jnienv, obj, NavitIdle_remove);
2715 (*jnienv)->DeleteGlobalRef(jnienv, obj);
2716 }
2717 #endif
2718 event_android_remove_timeout((struct event_timeout *) ev);
2719 }
2720
2721 static void event_android_call_callback(struct callback_list *cb)
2722 {
2723 //DBG // dbg(0,"enter\n");
2724 }
2725
2726 static struct event_methods event_android_methods =
2727 { event_android_main_loop_run, event_android_main_loop_quit, event_android_add_watch, event_android_remove_watch, event_android_add_timeout, event_android_remove_timeout, event_android_add_idle, event_android_remove_idle, event_android_call_callback, };
2728
2729 struct event_priv *
2730 event_android_new(struct event_methods *meth)
2731 {
2732
2733 // overwrite JNIenv!!
2734 JNIEnv *jnienv2;
2735 jnienv2 = jni_getenv();
2736
2737 // int thread_id = gettid();
2738 // dbg(0, "THREAD ID=%d\n", thread_id);
2739
2740
2741 // dbg(0,"enter\n");
2742 if (!find_class_global("com/zoffcc/applications/zanavi/NavitTimeout", &NavitTimeoutClass))
2743 return NULL;
2744
2745 // dbg(0,"ev 001\n");
2746 NavitTimeout_init = (*jnienv2)->GetMethodID(jnienv2, NavitTimeoutClass, "<init>", "(IZI)V");
2747 if (NavitTimeout_init == NULL)
2748 return NULL;
2749 // dbg(0,"ev 002\n");
2750 NavitTimeout_remove = (*jnienv2)->GetMethodID(jnienv2, NavitTimeoutClass, "remove", "()V");
2751 if (NavitTimeout_remove == NULL)
2752 return NULL;
2753 #if 0
2754 if (!find_class_global("com/zoffcc/applications/zanavi/NavitIdle", &NavitIdleClass))
2755 return NULL;
2756 NavitIdle_init = (*jnienv2)->GetMethodID(jnienv2, NavitIdleClass, "<init>", "(I)V");
2757 if (NavitIdle_init == NULL)
2758 return NULL;
2759 NavitIdle_remove = (*jnienv2)->GetMethodID(jnienv2, NavitIdleClass, "remove", "()V");
2760 if (NavitIdle_remove == NULL)
2761 return NULL;
2762 #endif
2763
2764 // dbg(0,"ev 003\n");
2765 if (!find_class_global("com/zoffcc/applications/zanavi/NavitWatch", &NavitWatchClass))
2766 return NULL;
2767 // dbg(0,"ev 004\n");
2768 NavitWatch_init = (*jnienv2)->GetMethodID(jnienv2, NavitWatchClass, "<init>", "(III)V");
2769 if (NavitWatch_init == NULL)
2770 return NULL;
2771 // dbg(0,"ev 005\n");
2772 NavitWatch_remove = (*jnienv2)->GetMethodID(jnienv2, NavitWatchClass, "remove", "()V");
2773 if (NavitWatch_remove == NULL)
2774 return NULL;
2775
2776 // dbg(0,"ev 006\n");
2777 if (!find_class_global("com/zoffcc/applications/zanavi/Navit", &NavitClass))
2778 return NULL;
2779 // dbg(0,"ev 007\n");
2780 Navit_disableSuspend = (*jnienv2)->GetMethodID(jnienv2, NavitClass, "disableSuspend", "()V");
2781 if (Navit_disableSuspend == NULL)
2782 return NULL;
2783 // dbg(0,"ev 008\n");
2784 Navit_exit = (*jnienv2)->GetMethodID(jnienv2, NavitClass, "exit2", "()V");
2785 if (Navit_exit == NULL)
2786 return NULL;
2787
2788 // dbg(0,"ok\n");
2789
2790 *meth = event_android_methods;
2791 return NULL;
2792 }
2793
2794 #ifdef PLUGSSS
2795 void plugin_init(void)
2796 {
2797 dbg(0,"enter\n");
2798 plugin_register_graphics_type("android", graphics_android_new);
2799 plugin_register_event_type("android", event_android_new);
2800 }
2801 #endif
2802

   
Visit the ZANavi Wiki