# HG changeset patch # User bsmith@81767d24-ef19-dc11-ae90-00e081727c95 # Date 1620991740 0 # Node ID dbd15c13f5bb2ae70d09cd89334ad6a4c552a4b4 # Parent 897d94c203652edd7c67c84d8e7c839f0fc6c876 Android: Implement most of the font functions and control/widget color. Add an Android section in dwtest for picking fonts and folders. Minor update to the readme. diff -r 897d94c20365 -r dbd15c13f5bb android/DWindows.kt --- a/android/DWindows.kt Thu May 13 22:52:11 2021 +0000 +++ b/android/DWindows.kt Fri May 14 11:29:00 2021 +0000 @@ -240,6 +240,8 @@ class DWRender(context: Context) : View(context) { var cachedCanvas: Canvas? = null + var typeface: Typeface? = null + var fontsize: Float? = null override fun onSizeChanged(width: Int, height: Int, oldWidth: Int, oldHeight: Int) { super.onSizeChanged(width, height, oldWidth, oldHeight) @@ -686,6 +688,89 @@ } } + fun typefaceFromFontName(fontname: String?): Typeface? + { + if(fontname != null) { + val bold: Boolean = fontname.contains(" Bold") + val italic: Boolean = fontname.contains(" Italic") + val font = fontname.substringAfter('.') + var fontFamily = font + var typeface: Typeface? = null + + if (bold && font != null) { + fontFamily = font.substringBefore(" Bold") + } else if (italic && font != null) { + fontFamily = font.substringBefore(" Italic") + } + + if (fontFamily != null) { + var style: Int = Typeface.NORMAL + if (bold && italic) { + style = Typeface.BOLD_ITALIC + } else if (bold) { + style = Typeface.BOLD + } else if (italic) { + style = Typeface.ITALIC + } + typeface = Typeface.create(fontFamily, style) + } + return typeface + } + return Typeface.DEFAULT + } + + fun windowSetFont(window: View, fontname: String?) { + var typeface: Typeface? = typefaceFromFontName(fontname) + var size: Float? = null + + if(fontname != null) { + size = fontname.substringBefore('.').toFloatOrNull() + } + + if(typeface != null) { + waitOnUiThread { + if (window is TextView) { + var textview: TextView = window + textview.typeface = typeface + if(size != null) { + textview.textSize = size + } + } else if (window is Button) { + var button: Button = window + button.typeface = typeface + if(size != null) { + button.textSize = size + } + } else if(window is DWRender) { + var render: DWRender = window + render.typeface = typeface + if(size != null) { + render.fontsize = size + } + } + } + } + } + + fun windowSetColor(window: View, falpha: Int, fred: Int, fgreen: Int, fblue: Int, + balpha: Int, bred: Int, bgreen: Int, bblue: Int) { + + waitOnUiThread { + if (window is TextView) { + var textview: TextView = window + textview.setTextColor(Color.rgb(fred, fgreen, fblue)) + textview.setBackgroundColor(Color.rgb(bred, bgreen, bblue)) + } else if (window is Button) { + var button: Button = window + button.setTextColor(Color.rgb(fred, fgreen, fblue)) + button.setBackgroundColor(Color.rgb(bred, bgreen, bblue)) + } else if(window is LinearLayout) { + var box: LinearLayout = window + box.setBackgroundColor(Color.rgb(bred, bgreen, bblue)) + } + } + } + fun windowSetText(window: View, text: String) { waitOnUiThread { if (window is TextView) { @@ -2095,15 +2180,75 @@ } } - fun drawText(render: DWRender?, bitmap: Bitmap?, x: Int, y: Int, text:String) + fun fontTextExtentsGet(render: DWRender?, bitmap: Bitmap?, text:String, typeface: Typeface?, fontsize: Int, window: View?): Long + { + var dimensions: Long = 0 + + waitOnUiThread { + var rect = Rect() + + if (render != null) { + if (render.typeface != null) { + paint.typeface = render.typeface + if (render.fontsize != null && render.fontsize!! > 0F) { + paint.textSize = render.fontsize!! + } + } + } else if (bitmap != null) { + if (typeface != null) { + paint.typeface = typeface + if (fontsize > 0) { + paint.textSize = fontsize.toFloat() + } + } else if (window != null && window is DWRender) { + val secondary: DWRender = window as DWRender + + if (secondary.typeface != null) { + paint.typeface = secondary.typeface + if (secondary.fontsize != null && secondary.fontsize!! > 0F) { + paint.textSize = secondary.fontsize!! + } + } + } + } + paint.getTextBounds(text, 0, text.length, rect) + val textheight = rect.bottom - rect.top + val textwidth = rect.right - rect.left + dimensions = textwidth.toLong() or (textheight.toLong() shl 32) + } + return dimensions + } + + fun drawText(render: DWRender?, bitmap: Bitmap?, x: Int, y: Int, text:String, typeface: Typeface?, fontsize: Int, window: View?) { waitOnUiThread { var canvas: Canvas? = null - if(render != null) { + if(render != null && render.cachedCanvas != null) { canvas = render.cachedCanvas + if(render.typeface != null) { + paint.typeface = render.typeface + if(render.fontsize != null && render.fontsize!! > 0F) { + paint.textSize = render.fontsize!! + } + } } else if(bitmap != null) { canvas = Canvas(bitmap) + if(typeface != null) { + paint.typeface = typeface + if(fontsize > 0) { + paint.textSize = fontsize.toFloat() + } + } else if(window != null && window is DWRender) { + val secondary: DWRender = window as DWRender + + if(secondary.typeface != null) { + paint.typeface = secondary.typeface + if(secondary.fontsize != null && secondary.fontsize!! > 0F) { + paint.textSize = secondary.fontsize!! + } + } + } } if(canvas != null) { diff -r 897d94c20365 -r dbd15c13f5bb android/dw.cpp --- a/android/dw.cpp Thu May 13 22:52:11 2021 +0000 +++ b/android/dw.cpp Fri May 14 11:29:00 2021 +0000 @@ -2575,9 +2575,10 @@ 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"); + "(Lorg/dbsoft/dwindows/DWRender;Landroid/graphics/Bitmap;IILjava/lang/String;Landroid/graphics/Typeface;ILandroid/view/View;)V"); // Call the method on the object - env->CallVoidMethod(_dw_obj, drawLine, handle, pixmap ? pixmap->bitmap : NULL, x, y, jstr); + env->CallVoidMethod(_dw_obj, drawLine, handle, pixmap ? pixmap->bitmap : nullptr, x, y, jstr, + pixmap ? pixmap->typeface : nullptr, pixmap ? pixmap->fontsize : 0, pixmap ? pixmap->handle : nullptr); } } @@ -2591,6 +2592,27 @@ */ void API dw_font_text_extents_get(HWND handle, HPIXMAP pixmap, const char *text, int *width, int *height) { + JNIEnv *env; + + if((handle || pixmap) && text && (width || height) && (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); + jclass clazz = env->FindClass(DW_CLASS_NAME); + // Get the method that you want to call + jmethodID fontTextExtentsGet = env->GetMethodID(clazz, "fontTextExtentsGet", + "(Lorg/dbsoft/dwindows/DWRender;Landroid/graphics/Bitmap;Ljava/lang/String;Landroid/graphics/Typeface;ILandroid/view/View;)J"); + // Call the method on the object + jlong dimensions = env->CallLongMethod(_dw_obj, fontTextExtentsGet, handle, pixmap ? pixmap->bitmap : nullptr, jstr, + pixmap ? pixmap->typeface : nullptr, pixmap ? pixmap->fontsize : 0, pixmap ? pixmap->handle : nullptr); + + if(width) + *width = dimensions & 0xFFFF; + if(height) + *height = (dimensions >> 32) & 0xFFFF; + } } /* Draw a polygon on a window (preferably a render window). @@ -3586,6 +3608,29 @@ */ int API dw_pixmap_set_font(HPIXMAP pixmap, const char *fontname) { + JNIEnv *env; + + if(pixmap && (env = (JNIEnv *)pthread_getspecific(_dw_env_key))) + { + // Construct a string + jstring jstr = env->NewStringUTF(fontname); + // 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 typefaceFromFontName = env->GetMethodID(clazz, "typefaceFromFontName", + "(Ljava/lang/String;)Landroid/graphics/Typeface;"); + // Call the method on the object + jobject typeface = env->NewGlobalRef(env->CallObjectMethod(_dw_obj, typefaceFromFontName, jstr)); + if(typeface) + { + jobject oldtypeface = pixmap->typeface; + pixmap->typeface = typeface; + if(oldtypeface) + env->DeleteGlobalRef(oldtypeface); + pixmap->fontsize = atoi(fontname); + } + return DW_ERROR_NONE; + } return DW_ERROR_GENERAL; } @@ -4395,6 +4440,24 @@ */ int API dw_window_set_color(HWND handle, ULONG fore, ULONG back) { + JNIEnv *env; + + if(handle && (env = (JNIEnv *)pthread_getspecific(_dw_env_key))) + { + unsigned long _fore = _dw_get_color(fore); + unsigned long _back = _dw_get_color(back); + + // 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 windowSetColor = env->GetMethodID(clazz, "windowSetColor", + "(Landroid/view/View;IIIIIIII)V"); + // Call the method on the object + env->CallVoidMethod(_dw_obj, windowSetColor, handle, + 0, (jint)DW_RED_VALUE(_fore), (jint)DW_GREEN_VALUE(_fore), (jint)DW_BLUE_VALUE(_fore), + 0, (jint)DW_RED_VALUE(_back), (jint)DW_GREEN_VALUE(_back), (jint)DW_BLUE_VALUE(_back)); + return DW_ERROR_NONE; + } return DW_ERROR_GENERAL; } @@ -4491,6 +4554,21 @@ */ int API dw_window_set_font(HWND handle, const char *fontname) { + JNIEnv *env; + + if(handle && (env = (JNIEnv *)pthread_getspecific(_dw_env_key))) + { + // Construct a string + jstring jstr = env->NewStringUTF(fontname); + // 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 windowHideShow = env->GetMethodID(clazz, "windowSetFont", + "(Landroid/view/View;Ljava/lang/String;)V"); + // Call the method on the object + env->CallVoidMethod(_dw_obj, windowHideShow, handle, jstr); + return DW_ERROR_NONE; + } return DW_ERROR_GENERAL; } diff -r 897d94c20365 -r dbd15c13f5bb dwtest.c --- a/dwtest.c Thu May 13 22:52:11 2021 +0000 +++ b/dwtest.c Fri May 14 11:29:00 2021 +0000 @@ -29,6 +29,10 @@ #define FIXEDFONT "9.Monaco" #define FOLDER_ICON_NAME "folder" #define FILE_ICON_NAME "file" +#elif defined(__ANDROID__) +#define FIXEDFONT "10.Monospace" +#define FOLDER_ICON_NAME "folder" +#define FILE_ICON_NAME "file" #elif GTK_MAJOR_VERSION > 1 #define FIXEDFONT "10.monospace" #define FOLDER_ICON_NAME "gtk/folder" diff -r 897d94c20365 -r dbd15c13f5bb readme.txt --- a/readme.txt Thu May 13 22:52:11 2021 +0000 +++ b/readme.txt Fri May 14 11:29:00 2021 +0000 @@ -86,7 +86,7 @@ Added new function dw_window_compare() to check if two window handles reference the same object. Necessary in the Android port since handles passed to callbacks are local references, so they don't - match the handles saved during window creation. + always match the handles saved during window creation. Added support for dw_window_set_font() with a NULL font parameter. This resets the font used on the widget to the default font. Fixed GTK warnings on GTK3 caused by using Pango style font syntax.