changeset 2535:d862d9e4069b

Android: Implement most of the rest of drawing except for fonts... With varying degrees of functionality... more work needed.
author bsmith@81767d24-ef19-dc11-ae90-00e081727c95
date Tue, 11 May 2021 09:03:30 +0000
parents c4255630cade
children d172ab2eddb6
files android/DWindows.kt android/dw.cpp
diffstat 2 files changed, 195 insertions(+), 5 deletions(-) [+]
line wrap: on
line diff
--- a/android/DWindows.kt	Tue May 11 06:38:09 2021 +0000
+++ b/android/DWindows.kt	Tue May 11 09:03:30 2021 +0000
@@ -404,6 +404,7 @@
     var threadCond = threadLock.newCondition()
     var notificationID: Int = 0
     private var paint = Paint()
+    private var bgcolor: Int = 0
 
     // Our version of runOnUiThread that waits for execution
     fun waitOnUiThread(runnable: Runnable)
@@ -1908,11 +1909,47 @@
             }
 
             if(canvas != null) {
+                paint.flags = 0
+                paint.style = Paint.Style.STROKE
                 canvas.drawLine(x1.toFloat(), y1.toFloat(), x2.toFloat(), y2.toFloat(), paint)
             }
         }
     }
 
+    fun drawText(render: DWRender?, bitmap: Bitmap?, x: Int, y: Int, text:String)
+    {
+        waitOnUiThread {
+            var canvas: Canvas? = null
+
+            if(render != null) {
+                canvas = render.cachedCanvas
+            } else if(bitmap != null) {
+                canvas = Canvas(bitmap)
+            }
+
+            if(canvas != null) {
+                // Save the old color for later...
+                var rect = Rect()
+                val oldcolor = paint.color
+                // Prepare to draw the background rect
+                paint.color = bgcolor
+                paint.flags = 0
+                paint.style = Paint.Style.FILL_AND_STROKE
+                paint.textAlign = Paint.Align.LEFT
+                paint.getTextBounds(text, 0, text.length, rect)
+                rect.top += y
+                rect.bottom += y
+                rect.left += x
+                rect.right += x
+                canvas.drawRect(rect, paint)
+                // Restore the color and prepare to draw text
+                paint.color = oldcolor
+                paint.style = Paint.Style.STROKE
+                canvas.drawText(text, x.toFloat(), y.toFloat(), paint)
+            }
+        }
+    }
+
     fun drawRect(render: DWRender?, bitmap: Bitmap?, x: Int, y: Int, width: Int, height: Int)
     {
         waitOnUiThread {
@@ -1925,11 +1962,94 @@
             }
 
             if(canvas != null) {
+                paint.flags = 0
+                paint.style = Paint.Style.FILL_AND_STROKE
                 canvas.drawRect(x.toFloat(), y.toFloat(), x.toFloat() + width.toFloat(), y.toFloat() + height.toFloat(), paint)
             }
         }
     }
 
+    fun drawPolygon(render: DWRender?, bitmap: Bitmap?, flags: Int, npoints: Int, x: IntArray, y: IntArray)
+    {
+        var points = FloatArray(npoints*2)
+
+        // Convert to a single IntArray
+        for (i in 0 until npoints) {
+            points[(i*2)] = x[i].toFloat()
+            points[(i*2)+1] = y[i].toFloat()
+        }
+
+        waitOnUiThread {
+            var canvas: Canvas? = null
+
+            if(render != null) {
+                canvas = render.cachedCanvas
+            } else if(bitmap != null) {
+                canvas = Canvas(bitmap)
+            }
+
+            if(canvas != null) {
+                // Handle the DW_DRAW_NOAA flag
+                if((flags and (1 shl 2)) == 0) {
+                    paint.flags = Paint.ANTI_ALIAS_FLAG
+                } else {
+                    paint.flags = 0
+                }
+                // Handle the DW_DRAW_FILL flag
+                if((flags and 1)  == 1) {
+                    paint.style = Paint.Style.FILL_AND_STROKE
+                } else {
+                    paint.style = Paint.Style.STROKE
+                }
+                canvas.drawPoints(points, paint)
+            }
+        }
+    }
+
+    fun drawArc(render: DWRender?, bitmap: Bitmap?, flags: Int, xorigin: Int, yorigin: Int,
+                x1: Int, y1: Int, x2: Int, y2: Int)
+    {
+        waitOnUiThread {
+            var canvas: Canvas? = null
+
+            if(render != null) {
+                canvas = render.cachedCanvas
+            } else if(bitmap != null) {
+                canvas = Canvas(bitmap)
+            }
+
+            if(canvas != null) {
+                var a1: Double = Math.atan2((y1 - yorigin).toDouble(), (x1 - xorigin).toDouble())
+                var a2: Double = Math.atan2((y2 - yorigin).toDouble(), (x2 - xorigin).toDouble())
+                val dx = (xorigin - x1).toDouble()
+                val dy = (yorigin - y1).toDouble()
+                val r: Double = Math.sqrt(dx * dx + dy * dy)
+                val left = (xorigin-r).toFloat()
+                val top = (yorigin-r).toFloat()
+                val rect = RectF(left, top, (left + (r*2)).toFloat(), (top + (r*2)).toFloat())
+
+                /* Convert to degrees */
+                a1 *= 180.0 / Math.PI
+                a2 *= 180.0 / Math.PI
+                val sweep = Math.abs(a1 - a2)
+
+                // Handle the DW_DRAW_NOAA flag
+                if((flags and (1 shl 2)) == 0) {
+                    paint.flags = Paint.ANTI_ALIAS_FLAG
+                } else {
+                    paint.flags = 0
+                }
+                // Handle the DW_DRAW_FILL flag
+                if((flags and 1)  == 1) {
+                    paint.style = Paint.Style.FILL_AND_STROKE
+                } else {
+                    paint.style = Paint.Style.STROKE
+                }
+                canvas.drawArc(rect, a1.toFloat(), sweep.toFloat(), false, paint)
+            }
+        }
+    }
+
     fun colorSet(alpha: Int, red: Int, green: Int, blue: Int)
     {
         waitOnUiThread {
@@ -1941,6 +2061,15 @@
         }
     }
 
+    fun bgColorSet(alpha: Int, red: Int, green: Int, blue: Int)
+    {
+        if(alpha != 0) {
+            this.bgcolor = Color.argb(alpha, red, green, blue)
+        } else {
+            this.bgcolor = Color.rgb(red, green, blue)
+        }
+    }
+
     fun timerConnect(interval: Long, sigfunc: Long, data: Long): Timer
     {
         // creating timer task, timer
--- a/android/dw.cpp	Tue May 11 06:38:09 2021 +0000
+++ b/android/dw.cpp	Tue May 11 09:03:30 2021 +0000
@@ -2456,6 +2456,20 @@
  */
 void API dw_color_background_set(unsigned long value)
 {
+    JNIEnv *env;
+
+    if((env = (JNIEnv *)pthread_getspecific(_dw_env_key)))
+    {
+        unsigned long color = _dw_get_color(value);
+
+        // First get the class that contains the method you need to call
+        jclass clazz = _dw_find_class(env, DW_CLASS_NAME);
+        // Get the method that you want to call
+        jmethodID bgColorSet = env->GetMethodID(clazz, "bgColorSet",
+                                              "(IIII)V");
+        // Call the method on the object
+        env->CallVoidMethod(_dw_obj, bgColorSet, 0, (jint)DW_RED_VALUE(color), (jint)DW_GREEN_VALUE(color), (jint)DW_BLUE_VALUE(color));
+    }
 }
 
 /* Allows the user to choose a color using the system's color chooser dialog.
@@ -2488,7 +2502,7 @@
         jmethodID drawPoint = env->GetMethodID(clazz, "drawPoint",
                                                "(Lorg/dbsoft/dwindows/DWRender;Landroid/graphics/Bitmap;II)V");
         // Call the method on the object
-        env->CallVoidMethod(_dw_obj, drawPoint, handle, pixmap->bitmap, x, y);
+        env->CallVoidMethod(_dw_obj, drawPoint, handle, pixmap ? pixmap->bitmap : NULL, x, y);
     }
 }
 
@@ -2513,7 +2527,7 @@
         jmethodID drawLine = env->GetMethodID(clazz, "drawLine",
                                               "(Lorg/dbsoft/dwindows/DWRender;Landroid/graphics/Bitmap;IIII)V");
         // Call the method on the object
-        env->CallVoidMethod(_dw_obj, drawLine, handle, pixmap->bitmap, x1, y1, x2, y2);
+        env->CallVoidMethod(_dw_obj, drawLine, handle, pixmap ? pixmap->bitmap : NULL, x1, y1, x2, y2);
     }
 }
 
@@ -2527,6 +2541,20 @@
  */
 void API dw_draw_text(HWND handle, HPIXMAP pixmap, int x, int y, const char *text)
 {
+    JNIEnv *env;
+
+    if((handle || pixmap) && text && (env = (JNIEnv *)pthread_getspecific(_dw_env_key)))
+    {
+        // Construct the string
+        jstring jstr = env->NewStringUTF(text);
+        // First get the class that contains the method you need to call
+        jclass clazz = _dw_find_class(env, DW_CLASS_NAME);
+        // Get the method that you want to call
+        jmethodID drawLine = env->GetMethodID(clazz, "drawText",
+                                              "(Lorg/dbsoft/dwindows/DWRender;Landroid/graphics/Bitmap;IILjava/lang/String;)V");
+        // Call the method on the object
+        env->CallVoidMethod(_dw_obj, drawLine, handle, pixmap ? pixmap->bitmap : NULL, x, y, jstr);
+    }
 }
 
 /* Query the width and height of a text string.
@@ -2550,8 +2578,29 @@
  *       x: Pointer to array of X coordinates.
  *       y: Pointer to array of Y coordinates.
  */
-void API dw_draw_polygon( HWND handle, HPIXMAP pixmap, int flags, int npoints, int *x, int *y )
-{
+void API dw_draw_polygon(HWND handle, HPIXMAP pixmap, int flags, int npoints, int *x, int *y)
+{
+    JNIEnv *env;
+
+    if((handle || pixmap) && (env = (JNIEnv *)pthread_getspecific(_dw_env_key)))
+    {
+        jintArray jx = env->NewIntArray(npoints);
+        jintArray jy = env->NewIntArray(npoints);
+
+        if(jx && jy)
+        {
+            // Construct the integer arrays
+            env->SetIntArrayRegion(jx, 0, npoints, x);
+            env->SetIntArrayRegion(jy, 0, npoints, y);
+            // First get the class that contains the method you need to call
+            jclass clazz = _dw_find_class(env, DW_CLASS_NAME);
+            // Get the method that you want to call
+            jmethodID drawPolygon = env->GetMethodID(clazz, "drawPolygon",
+                                                     "(Lorg/dbsoft/dwindows/DWRender;Landroid/graphics/Bitmap;II[I[I)V");
+            // Call the method on the object
+            env->CallVoidMethod(_dw_obj, drawPolygon, handle, pixmap ? pixmap->bitmap : NULL, flags, npoints, jx, jy);
+        }
+    }
 }
 
 /* Draw a rectangle on a window (preferably a render window).
@@ -2576,7 +2625,7 @@
         jmethodID drawLine = env->GetMethodID(clazz, "drawRect",
                                               "(Lorg/dbsoft/dwindows/DWRender;Landroid/graphics/Bitmap;IIII)V");
         // Call the method on the object
-        env->CallVoidMethod(_dw_obj, drawLine, handle, pixmap->bitmap, x, y, width, height);
+        env->CallVoidMethod(_dw_obj, drawLine, handle, pixmap ? pixmap->bitmap : NULL, x, y, width, height);
     }
 }
 
@@ -2595,6 +2644,18 @@
  */
 void API dw_draw_arc(HWND handle, HPIXMAP pixmap, int flags, int xorigin, int yorigin, int x1, int y1, int x2, int y2)
 {
+    JNIEnv *env;
+
+    if((handle || pixmap) && (env = (JNIEnv *)pthread_getspecific(_dw_env_key)))
+    {
+        // First get the class that contains the method you need to call
+        jclass clazz = _dw_find_class(env, DW_CLASS_NAME);
+        // Get the method that you want to call
+        jmethodID drawLine = env->GetMethodID(clazz, "drawArc",
+                                              "(Lorg/dbsoft/dwindows/DWRender;Landroid/graphics/Bitmap;IIIIIII)V");
+        // Call the method on the object
+        env->CallVoidMethod(_dw_obj, drawLine, handle, pixmap ? pixmap->bitmap : NULL, flags, xorigin, yorigin, x1, y1, x2, y2);
+    }
 }
 
 /*