diff options
| -rw-r--r-- | README.Android.txt | 33 | ||||
| -rw-r--r-- | ide/AndroidStudio3/app/app.iml | 2 | ||||
| -rw-r--r-- | ide/AndroidStudio3/app/src/main/cpp/HelloAndroid.cxx | 309 | ||||
| -rw-r--r-- | src/drivers/Android/Fl_Android_Graphics_Driver.H | 62 | ||||
| -rw-r--r-- | src/drivers/Android/Fl_Android_Graphics_Driver.cxx | 101 | ||||
| -rw-r--r-- | src/drivers/Android/Fl_Android_Graphics_Font.H | 15 | ||||
| -rw-r--r-- | src/drivers/Android/Fl_Android_Graphics_Font.cxx | 18 |
7 files changed, 324 insertions, 216 deletions
diff --git a/README.Android.txt b/README.Android.txt index fc3ed0ae7..21f7fcc8f 100644 --- a/README.Android.txt +++ b/README.Android.txt @@ -10,8 +10,9 @@ CONTENTS -------- 1 Building FLTK with Android Studio 3 - 2 Extensions and limitation of FLTK on Android - 3 DOCUMENT HISTORY + 2 Building Apps on an Android device with C4Droid + 3 Extensions and limitation of FLTK on Android + 4 DOCUMENT HISTORY BUILDING FLTK SAMPLE WITH ANDROID STUDIO 3 @@ -33,12 +34,33 @@ device, you are ready to install FLTK. - click "run"; the project should compile and run out of the box +Building Apps on an Android device with C4Droid +----------------------------------------------- + +WORK IN PROGRESS: +C4Droid is a minimal IDE that comes with gcc/g++ and runs directly on your +Android device. C4Droid supports Native Activities, SDL, SDL2, and even Qt. +FLTK uses the Native Activity mechanism, so why not write FLTK apps right +on your phone? + + - compile and test the Android test app in ide/HelloAndroid + - create /sdcard/include/ and /sdcard/lib/ on your Android device + - copy (fltk)/FL/ and its content into /sdcard/include/ + - copy (fltk)/ide/AndroidStudio3/FL/abi-version.h to /sdcard/include/FL/ + - copy (fltk)/ide/AndroidStudio3/./app/.externalNativeBuild/cmake/debug/arm64-v8a/fltk/lib/libfltk.a + to /sdcard/lib/ + - ... change Native Activity settings in c4Droid preferences + - ... remove native glue + - ... add include and library path, add library + - ... add support for (which?) STL library + + Extensions and limitation of FLTK on Android -------------------------------------------- -Android support for FLTK is in a very early stage. As of March 2018, very basic -rendering works, text rendering work, clipping works, window layering works, -and mouse clicks (touch events) are detected. +Android support for FLTK is in an early stage. As of March 2018, most +rendering works, fonts work, bitmaps and pixmaps work, clipping works, window +layering works, and mouse clicks and keyboard events are handled When loading fonts: - font names starting with a $ will have the system font path inserted @@ -53,6 +75,7 @@ Limitations: DOCUMENT HISTORY ---------------- +Mar 29 2018 - matt: many graphics functions ahve been implemented, keyboard Mar 17 2018 - matt: added Android extensions for fonts Mar 12 2018 - matt: started list of limitation that serevs as information to the user as much as a todo list for core developers diff --git a/ide/AndroidStudio3/app/app.iml b/ide/AndroidStudio3/app/app.iml index ffb02d88c..12d8299ac 100644 --- a/ide/AndroidStudio3/app/app.iml +++ b/ide/AndroidStudio3/app/app.iml @@ -96,6 +96,8 @@ <sourceFolder url="file://$MODULE_DIR$/src/test/jni" isTestSource="true" /> <sourceFolder url="file://$MODULE_DIR$/src/test/rs" isTestSource="true" /> <sourceFolder url="file://$MODULE_DIR$/src/test/shaders" isTestSource="true" /> + <excludeFolder url="file://$MODULE_DIR$/build/.DS_Store" /> + <excludeFolder url="file://$MODULE_DIR$/build/intermediates/.DS_Store" /> <excludeFolder url="file://$MODULE_DIR$/build/intermediates/assets" /> <excludeFolder url="file://$MODULE_DIR$/build/intermediates/blame" /> <excludeFolder url="file://$MODULE_DIR$/build/intermediates/check-manifest" /> diff --git a/ide/AndroidStudio3/app/src/main/cpp/HelloAndroid.cxx b/ide/AndroidStudio3/app/src/main/cpp/HelloAndroid.cxx index 38f5f551b..acda5187c 100644 --- a/ide/AndroidStudio3/app/src/main/cpp/HelloAndroid.cxx +++ b/ide/AndroidStudio3/app/src/main/cpp/HelloAndroid.cxx @@ -15,195 +15,159 @@ * */ -#if 0 - - -#elif 1 - +#if 1 + +// +// "$Id: color_chooser.cxx 12655 2018-02-09 14:39:42Z AlbrechtS $" +// +// Color chooser test program for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2018 by Bill Spitzak and others. +// +// This library is free software. Distribution and use rights are outlined in +// the file "COPYING" which should have been included with this file. If this +// file is missing or damaged, see the license at: +// +// http://www.fltk.org/COPYING.php +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// #include <FL/Fl.H> -#include <FL/Fl_Double_Window.H> +#include <FL/Fl_Window.H> #include <FL/Fl_Box.H> -#include <FL/Fl_Hor_Value_Slider.H> -#include <FL/Fl_Toggle_Button.H> -#include <FL/Fl_Input.H> -#include <FL/Fl_Choice.H> -#include <FL/Fl_Pixmap.H> +#include <FL/Fl_Button.H> +#include <FL/fl_show_colormap.H> +#include <FL/Fl_Color_Chooser.H> +#include <FL/Fl_Image.H> +#include <FL/platform.H> #include <FL/fl_draw.H> -#include "/Users/matt/dev/fltk-1.4.svn/test/pixmaps/blast.xpm" - -Fl_Toggle_Button *imageb, *imageovertextb, *imagenexttotextb, *imagebackdropb; -Fl_Toggle_Button *leftb,*rightb,*topb,*bottomb,*insideb,*clipb,*wrapb; -Fl_Box *text; -Fl_Input *input; -Fl_Hor_Value_Slider *fonts; -Fl_Hor_Value_Slider *sizes; -Fl_Double_Window *window; -Fl_Pixmap *img; - -void button_cb(Fl_Widget *,void *) { - int i = 0; - if (leftb->value()) i |= FL_ALIGN_LEFT; - if (rightb->value()) i |= FL_ALIGN_RIGHT; - if (topb->value()) i |= FL_ALIGN_TOP; - if (bottomb->value()) i |= FL_ALIGN_BOTTOM; - if (insideb->value()) i |= FL_ALIGN_INSIDE; - if (clipb->value()) i |= FL_ALIGN_CLIP; - if (wrapb->value()) i |= FL_ALIGN_WRAP; - if (imageovertextb->value()) i |= FL_ALIGN_TEXT_OVER_IMAGE; - if (imagenexttotextb->value()) i |= FL_ALIGN_IMAGE_NEXT_TO_TEXT; - if (imagebackdropb->value()) i |= FL_ALIGN_IMAGE_BACKDROP; - text->align(i); - window->redraw(); -} - -void image_cb(Fl_Widget *,void *) { - if (imageb->value()) - text->image(img); - else - text->image(0); - window->redraw(); -} - -void font_cb(Fl_Widget *,void *) { - text->labelfont(int(fonts->value())); - window->redraw(); -} - -void size_cb(Fl_Widget *,void *) { - text->labelsize(int(sizes->value())); - window->redraw(); -} - -void input_cb(Fl_Widget *,void *) { - text->label(input->value()); - window->redraw(); -} +#include <stdlib.h> +#include <stdio.h> +#if !defined(_WIN32) && !defined(__APPLE__) && !defined(FL_PORTING) && !defined(__ANDROID__) +#include "list_visuals.cxx" +#endif -void normal_cb(Fl_Widget *,void *) { - text->labeltype(FL_NORMAL_LABEL); - window->redraw(); +int width = 100; +int height = 100; +uchar *image; +Fl_Box *hint; + +void make_image() { + image = new uchar[3*width*height]; + uchar *p = image; + for (int y = 0; y < height; y++) { + double Y = double(y)/(height-1); + for (int x = 0; x < width; x++) { + double X = double(x)/(width-1); + *p++ = uchar(255*((1-X)*(1-Y))); // red in upper-left + *p++ = uchar(255*((1-X)*Y)); // green in lower-left + *p++ = uchar(255*(X*Y)); // blue in lower-right + } + } } -void symbol_cb(Fl_Widget *,void *) { - text->labeltype(FL_SYMBOL_LABEL); - if (input->value()[0] != '@') { - input->static_value("@->"); - text->label("@->"); +class Pens : public Fl_Box { + void draw(); +public: + Pens(int X, int Y, int W, int H, const char* L) + : Fl_Box(X,Y,W,H,L) {} +}; +void Pens::draw() { + // use every color in the gray ramp: + for (int i = 0; i < 3*8; i++) { + fl_color((Fl_Color)(FL_GRAY_RAMP+i)); + fl_line(x()+i, y(), x()+i, y()+h()); } - window->redraw(); } -void shadow_cb(Fl_Widget *,void *) { - text->labeltype(FL_SHADOW_LABEL); - window->redraw(); -} +Fl_Color c = FL_GRAY; +#define fullcolor_cell (FL_FREE_COLOR) -void embossed_cb(Fl_Widget *,void *) { - text->labeltype(FL_EMBOSSED_LABEL); - window->redraw(); +void cb1(Fl_Widget *, void *v) { + c = fl_show_colormap(c); + Fl_Box* b = (Fl_Box*)v; + b->color(c); + hint->labelcolor(fl_contrast(FL_BLACK,c)); + b->parent()->redraw(); } -void engraved_cb(Fl_Widget *,void *) { - text->labeltype(FL_ENGRAVED_LABEL); - window->redraw(); +void cb2(Fl_Widget *, void *v) { + uchar r,g,b; + Fl::get_color(c,r,g,b); + if (!fl_color_chooser("New color:",r,g,b,3)) return; + c = fullcolor_cell; + Fl::set_color(fullcolor_cell,r,g,b); + Fl_Box* bx = (Fl_Box*)v; + bx->color(fullcolor_cell); + hint->labelcolor(fl_contrast(FL_BLACK,fullcolor_cell)); + bx->parent()->redraw(); } -Fl_Menu_Item choices[] = { - {"FL_NORMAL_LABEL",0,normal_cb}, - {"FL_SYMBOL_LABEL",0,symbol_cb}, - {"FL_SHADOW_LABEL",0,shadow_cb}, - {"FL_ENGRAVED_LABEL",0,engraved_cb}, - {"FL_EMBOSSED_LABEL",0,embossed_cb}, - {0}}; - -int main(int argc, char **argv) { - img = new Fl_Pixmap(blast_xpm); - - window = new Fl_Double_Window(440,420); - - input = new Fl_Input(70,375,350,25,"Label:"); - input->static_value("The quick brown fox jumped over the lazy dog."); - input->when(FL_WHEN_CHANGED); - input->callback(input_cb); - input->tooltip("label text"); - - sizes= new Fl_Hor_Value_Slider(70,350,350,25,"Size:"); - sizes->align(FL_ALIGN_LEFT); - sizes->bounds(1,64); - sizes->step(1); - sizes->value(14); - sizes->callback(size_cb); - - fonts=new Fl_Hor_Value_Slider(70,325,350,25,"Font:"); - fonts->align(FL_ALIGN_LEFT); - fonts->bounds(0,15); - fonts->step(1); - fonts->value(0); - fonts->callback(font_cb); - - Fl_Group *g = new Fl_Group(70,275,350,50); - imageb = new Fl_Toggle_Button(70,275,50,25,"image"); - imageb->callback(image_cb); - imageb->tooltip("show image"); - - imageovertextb = new Fl_Toggle_Button(120,275,50,25,"T o I"); - imageovertextb->callback(button_cb); - imageovertextb->tooltip("FL_ALIGN_TEXT_OVER_IMAGE"); - - imagenexttotextb = new Fl_Toggle_Button(170,275,50,25,"I | T"); - imagenexttotextb->callback(button_cb); - imagenexttotextb->tooltip("FL_ALIGN_IMAGE_NEXT_TO_TEXT"); - - imagebackdropb = new Fl_Toggle_Button(220,275,50,25,"back"); - imagebackdropb->callback(button_cb); - imagebackdropb->tooltip("FL_ALIGN_IMAGE_BACKDROP"); - - leftb = new Fl_Toggle_Button(70,300,50,25,"left"); - leftb->callback(button_cb); - leftb->tooltip("FL_ALIGN_LEFT"); - - rightb = new Fl_Toggle_Button(120,300,50,25,"right"); - rightb->callback(button_cb); - rightb->tooltip("FL_ALIGN_RIGHT"); - - topb = new Fl_Toggle_Button(170,300,50,25,"top"); - topb->callback(button_cb); - topb->tooltip("FL_ALIGN_TOP"); - - bottomb = new Fl_Toggle_Button(220,300,50,25,"bottom"); - bottomb->callback(button_cb); - bottomb->tooltip("FL_ALIGN_BOTTOM"); - - insideb = new Fl_Toggle_Button(270,300,50,25,"inside"); - insideb->callback(button_cb); - insideb->tooltip("FL_ALIGN_INSIDE"); - - wrapb = new Fl_Toggle_Button(320,300,50,25,"wrap"); - wrapb->callback(button_cb); - wrapb->tooltip("FL_ALIGN_WRAP"); - - clipb = new Fl_Toggle_Button(370,300,50,25,"clip"); - clipb->callback(button_cb); - clipb->tooltip("FL_ALIGN_CLIP"); - - g->resizable(insideb); - g->end(); - - Fl_Choice *c = new Fl_Choice(70,250,200,25); - c->menu(choices); - - text = new Fl_Box(FL_FRAME_BOX,120,75,200,100,input->value()); - text->align(FL_ALIGN_CENTER); - - window->resizable(text); - window->end(); - window->show(argc,argv); +int main(int argc, char ** argv) { + Fl::set_color(fullcolor_cell,145,159,170); + Fl_Window window(400,400); + Fl_Box box(30,30,340,340); + box.box(FL_THIN_DOWN_BOX); + c = fullcolor_cell; + box.color(c); + Fl_Box hintbox(40,40,320,30,"Pick background color with buttons:"); + hintbox.align(FL_ALIGN_INSIDE); + hint = &hintbox; + Fl_Button b1(120,80,180,30,"fl_show_colormap()"); + b1.callback(cb1,&box); + Fl_Button b2(120,120,180,30,"fl_color_chooser()"); + b2.callback(cb2,&box); + Fl_Box image_box(160,190,width,height,0); + make_image(); + (new Fl_RGB_Image(image, width, height))->label(&image_box); + Fl_Box b(160,310,120,30,"Example of fl_draw_image()"); + Pens p(60,180,3*8,120,"lines"); + p.align(FL_ALIGN_TOP); + int i = 1; + if (!Fl::args(argc,argv,i) || i < argc-1) { + printf("usage: %s <switches> visual-number\n" + " - : default visual\n" + " r : call Fl::visual(FL_RGB)\n" + " c : call Fl::own_colormap()\n",argv[0]); +#if !defined(_WIN32) && !defined(__APPLE__) && !defined(FL_PORTING) && !defined(__ANDROID__) + printf(" # : use this visual with an empty colormap:\n"); + list_visuals(); +#endif + puts(Fl::help); + exit(1); + } + if (i!=argc) { + if (argv[i][0] == 'r') { + if (!Fl::visual(FL_RGB)) printf("Fl::visual(FL_RGB) returned false.\n"); + } else if (argv[i][0] == 'c') { + Fl::own_colormap(); + } else if (argv[i][0] != '-') { +#if !defined(_WIN32) && !defined(__APPLE__) && !defined(FL_PORTING) && !defined(__ANDROID__) + int visid = atoi(argv[i]); + fl_open_display(); + XVisualInfo templt; int num; + templt.visualid = visid; + fl_visual = XGetVisualInfo(fl_display, VisualIDMask, &templt, &num); + if (!fl_visual) Fl::fatal("No visual with id %d",visid); + fl_colormap = XCreateColormap(fl_display, RootWindow(fl_display,fl_screen), + fl_visual->visual, AllocNone); + fl_xpixel(FL_BLACK); // make sure black is allocated +#else + Fl::fatal("Visual id's not supported on Windows or MacOS."); +#endif + } + } + window.show(argc,argv); return Fl::run(); } - +// +// End of "$Id: color_chooser.cxx 12655 2018-02-09 14:39:42Z AlbrechtS $". +// #else @@ -359,7 +323,8 @@ test/cairo_test.cxx test/pixmap.cxx test/checkers.cxx test/pixmap_browser.cxx test/clock.cxx test/resizebox.cxx test/colbrowser.cxx test/rotated_text.cxx -test/color_chooser.cxx test/scroll.cxx + * test/color_chooser.cxx: - can't draw 'on the fly' yet +test/scroll.cxx test/connect.cxx test/shape.cxx test/cube.cxx test/subwindow.cxx test/cursor.cxx test/sudoku.cxx @@ -386,6 +351,6 @@ test/image.cxx test/unittest_viewport.cxx test/input.cxx test/unittests.cxx test/input_choice.cxx test/utf8.cxx test/keyboard.cxx test/windowfocus.cxx - * test/label.cxx : - pixmap + * test/label.cxx : + 'label' works */
\ No newline at end of file diff --git a/src/drivers/Android/Fl_Android_Graphics_Driver.H b/src/drivers/Android/Fl_Android_Graphics_Driver.H index 08f9de674..198d32937 100644 --- a/src/drivers/Android/Fl_Android_Graphics_Driver.H +++ b/src/drivers/Android/Fl_Android_Graphics_Driver.H @@ -53,24 +53,23 @@ protected: // - excluded by #if/#endif means that we have not implemneted this yet // - methods marked with // super: use the implemnetation of the super class // - virtual ... override functions are implemented for Android -#if 0 private: // some platforms may need to reimplement this - virtual void set_current_(); + // This is called from the surface device, see: end_current_() + // super: virtual void set_current_(); protected: - float scale_; // scale between user and graphical coordinates: graphical = user * scale_ /** Sets the current value of the scaling factor */ - virtual void scale(float f) { scale_ = f; } + // super: virtual void scale(float f) { scale_ = f; } // we do not support any scaling at this point protected: - virtual void global_gc(); -#endif + // set fl_gc, which we do not use in the Android port at this point + // super: virtual void global_gc(); /** Support function for Fl_Pixmap drawing */ virtual fl_uintptr_t cache(Fl_Pixmap *img) override; /** Support function for Fl_Bitmap drawing */ virtual fl_uintptr_t cache(Fl_Bitmap *img) override; -#if 0 /** Support function for Fl_RGB_Image drawing */ - virtual void uncache(Fl_RGB_Image *img, fl_uintptr_t &id_, fl_uintptr_t &mask_) { } + virtual void uncache(Fl_RGB_Image *img, fl_uintptr_t &id_, fl_uintptr_t &mask_) override; +#if 0 // --- implementation is in src/drivers/xxx/Fl_xxx_Graphics_Driver_image.cxx /** see fl_draw_image(const uchar* buf, int X,int Y,int W,int H, int D, int L) */ virtual void draw_image(const uchar* buf, int X,int Y,int W,int H, int D=3, int L=0) {} @@ -80,13 +79,9 @@ protected: virtual void draw_image(Fl_Draw_Image_Cb cb, void* data, int X,int Y,int W,int H, int D=3) {} /** see fl_draw_image_mono(Fl_Draw_Image_Cb cb, void* data, int X,int Y,int W,int H, int D) */ virtual void draw_image_mono(Fl_Draw_Image_Cb cb, void* data, int X,int Y,int W,int H, int D=1) {} - /** \brief Draws an Fl_RGB_Image object using this graphics driver. - * - Specifies a bounding box for the image, with the origin (upper left-hand corner) of - the image offset by the cx and cy arguments. - */ - virtual void draw(Fl_RGB_Image * rgb,int XP, int YP, int WP, int HP, int cx, int cy) {} #endif + /** \brief Draws an Fl_RGB_Image object using this graphics driver. */ + virtual void draw(Fl_RGB_Image * rgb,int XP, int YP, int WP, int HP, int cx, int cy) override; /** \brief Draws an Fl_Pixmap object using this graphics driver. * Specifies a bounding box for the image, with the origin (upper left-hand corner) of @@ -106,14 +101,9 @@ protected: virtual Fl_Bitmask create_bitmask(int w, int h, const uchar *array) {return 0; } /** Support function for image drawing */ virtual void delete_bitmask(Fl_Bitmask bm) {} - /** For internal library use only */ - static void change_image_size(Fl_Image *img, int W, int H) { - img->w(W); - img->h(H); - } - // Support function for image drawing - virtual void uncache_pixmap(fl_uintptr_t p); #endif + // Support function for image drawing + virtual void uncache_pixmap(fl_uintptr_t p) override; public: /** Constructor, C++11 initialises member variables in-line */ Fl_Android_Graphics_Driver(); @@ -267,16 +257,19 @@ public: /** Support for PostScript drawing */ virtual float scale_font_for_PostScript(Fl_Font_Descriptor *desc, int s) override { return float(s); } // default implementation may be enough -#if 0 - /** Support for PostScript drawing */ - virtual float scale_bitmap_for_PostScript() { return 2; } - virtual void set_spot(int font, int size, int X, int Y, int W, int H, Fl_Window *win); - virtual void reset_spot(); + /** Support for PostScript drawing - no documentation found on this call*/ + // super: virtual float scale_bitmap_for_PostScript() { return 2; } + // super: virtual void set_spot(int font, int size, int X, int Y, int W, int H, Fl_Window *win); + // super: virtual void reset_spot(); // each platform implements these 3 functions its own way - virtual void add_rectangle_to_region(Fl_Region r, int x, int y, int w, int h); - virtual Fl_Region XRectangleRegion(int x, int y, int w, int h); - virtual void XDestroyRegion(Fl_Region r); -#endif + /* TODO: Android: we can implement this to have a redraw region based on Fl::damage + * calls. Currently, we do not implement damage regions, but we can probably + * implement this using our clipping regions. This may become neccesary when + * we allow desktop-style window movement. + */ + // super: virtual void add_rectangle_to_region(Fl_Region r, int x, int y, int w, int h); + // super: virtual Fl_Region XRectangleRegion(int x, int y, int w, int h); + // super: virtual void XDestroyRegion(Fl_Region r); /** Support for Fl::get_font_name() */ virtual const char* get_font_name(Fl_Font fnum, int* ap) override; /** Support for Fl::get_font_sizes() */ @@ -291,13 +284,12 @@ public: virtual const char *font_name(int num) override; /** Support for Fl::set_font() */ virtual void font_name(int num, const char *name) override; -#if 0 // Draws an Fl_Image scaled to width W & height H - virtual int draw_scaled(Fl_Image *img, int X, int Y, int W, int H); + // TODO: we don't seem to need this until we introduce a scaling graphis driver + // super: virtual int draw_scaled(Fl_Image *img, int X, int Y, int W, int H); /** Support function for fl_overlay_rect() and scaled GUI. Defaut implementation may be enough */ - virtual bool overlay_rect_unscaled(); -#endif + // super: virtual bool overlay_rect_unscaled(); /** Support function for fl_overlay_rect() and scaled GUI. Defaut implementation may be enough */ // super: virtual void overlay_rect(int x, int y, int w , int h) { loop(x, y, x+w-1, y, x+w-1, y+h-1, x, y+h-1); } @@ -305,7 +297,7 @@ public: // --- start of Android additions -------------------------------------------- // start drawing with this driver into the given window - // TODO: how is this different to Fl_Graphics_Driver::set_current_() above + // The virtual call `set_current_()` changes surface, not windows void make_current(Fl_Window*); protected: diff --git a/src/drivers/Android/Fl_Android_Graphics_Driver.cxx b/src/drivers/Android/Fl_Android_Graphics_Driver.cxx index 7b74c0c01..a53cb7795 100644 --- a/src/drivers/Android/Fl_Android_Graphics_Driver.cxx +++ b/src/drivers/Android/Fl_Android_Graphics_Driver.cxx @@ -1031,10 +1031,10 @@ fl_uintptr_t Fl_Android_Graphics_Driver::cache(Fl_Pixmap *img) const uchar *src = rgba + yy*rowBytes; uint32_t *dst = cache->pWords + yy*cache->pStride; for (int xx=0; xx<w; xx++) { - uint32_t c = ((((src[0] << 8) & 0xf800) | - ((src[1] << 3) & 0x07e0) | - ((src[2] >> 3) & 0x001f) ) << 16) | src[3]; // FIXME: alpha - *dst++ = c; +// uint32_t c = ((((src[0] << 8) & 0xf800) | +// ((src[1] << 3) & 0x07e0) | +// ((src[2] >> 3) & 0x001f) ) << 16) | src[3]; // FIXME: alpha + *dst++ = Fl_Android_565A_Map::toRGBA(src[0],src[1], src[2], src[3]); src+=4; } } @@ -1044,6 +1044,86 @@ fl_uintptr_t Fl_Android_Graphics_Driver::cache(Fl_Pixmap *img) } +void Fl_Android_Graphics_Driver::uncache_pixmap(fl_uintptr_t p) +{ + Fl_Android_565A_Map *img = (Fl_Android_565A_Map*)p; + delete img; +} + + +void Fl_Android_Graphics_Driver::draw(Fl_RGB_Image *img, int XP, int YP, int WP, int HP, int cx, int cy) +{ + int X, Y, W, H; + // Don't draw an empty image... + if (!img->d() || !img->array) { + Fl_Graphics_Driver::draw_empty(img, XP, YP); + return; + } + if (start_image(img, XP, YP, WP, HP, cx, cy, X, Y, W, H)) { + return; + } + Fl_Android_565A_Map *cgimg = (Fl_Android_565A_Map*)*Fl_Graphics_Driver::id(img); + if (!cgimg) { + int w = img->w(), h = img->h(), d = img->d(), stride = w*d + img->ld(); + cgimg = new Fl_Android_565A_Map(w, h); + *Fl_Graphics_Driver::id(img) = (fl_uintptr_t)cgimg; + if (d==1) { // grayscale + for (int iy=0; iy<h; iy++) { + const uchar *src = img->array + iy*stride; + uint32_t *dst = cgimg->pWords + iy*cgimg->pStride; + for (int ix=0; ix<w; ix++) { + uchar l = *src++; + uint32_t rgba = Fl_Android_565A_Map::toRGBA(l, l, l, 255); + *dst++ = rgba; + } + } + } else if (d==2) { // gray + alpha + for (int iy=0; iy<h; iy++) { + const uchar *src = img->array + iy*stride; + uint32_t *dst = cgimg->pWords + iy*cgimg->pStride; + for (int ix=0; ix<w; ix++) { + uchar l = *src++, a = *src++; + uint32_t rgba = Fl_Android_565A_Map::toRGBA(l, l, l, a); + *dst++ = rgba; + } + } + } else if (d==3) { // rgb + for (int iy=0; iy<h; iy++) { + const uchar *src = img->array + iy*stride; + uint32_t *dst = cgimg->pWords + iy*cgimg->pStride; + for (int ix=0; ix<w; ix++) { + uchar r = *src++, g = *src++, b = *src++; + uint32_t rgba = Fl_Android_565A_Map::toRGBA(r, g, b, 255); + *dst++ = rgba; + } + } + } else if (d==4) { // rgb + alpha + for (int iy=0; iy<h; iy++) { + const uchar *src = img->array + iy*stride; + uint32_t *dst = cgimg->pWords + iy*cgimg->pStride; + for (int ix=0; ix<w; ix++) { + uchar r = *src++, g = *src++, b = *src++, a = *src++; + uint32_t rgba = Fl_Android_565A_Map::toRGBA(r, g, b, a); + *dst++ = rgba; + } + } + } + } + if (cgimg) { + for (const auto &it: pClippingRegion.overlapping(Fl_Rect_Region(X, Y, W, H))) { + draw(XP, YP, cgimg, it->clipped_rect()); + } + } +} + + +void Fl_Android_Graphics_Driver::uncache(Fl_RGB_Image*, fl_uintptr_t &id_, fl_uintptr_t&) +{ + Fl_Android_565A_Map *cgimg = (Fl_Android_565A_Map*)id_; + delete cgimg; +} + + void Fl_Android_Graphics_Driver::set_color(Fl_Color i, unsigned int c) { if (i>255) return; @@ -1056,6 +1136,19 @@ void Fl_Android_Graphics_Driver::color(uchar r, uchar g, uchar b) color( (((Fl_Color)r)<<24)|(((Fl_Color)g)<<16)|(((Fl_Color)b)<<8) ); } +/** + * Draw a rectangle that may be dithered if we are in colormap mode (which in + * the year 2018 is as likely has a user with a berstein colored tube TV). + * FIXME: This function should be virtual as well, or should not exist at all. + */ +void fl_rectf(int x, int y, int w, int h, uchar r, uchar g, uchar b) { +#if USE_COLORMAP + // ... +#endif + fl_color(r,g,b); + fl_rectf(x,y,w,h); +} + // // End of "$Id$". diff --git a/src/drivers/Android/Fl_Android_Graphics_Font.H b/src/drivers/Android/Fl_Android_Graphics_Font.H index 4bab47786..358af6fa0 100644 --- a/src/drivers/Android/Fl_Android_Graphics_Font.H +++ b/src/drivers/Android/Fl_Android_Graphics_Font.H @@ -23,7 +23,10 @@ #include "Fl_Android_Graphics_Driver.H" // We violate FLTKs avoidance of STL because we live in a defined driver space +#define FL_ALLOW_STL 1 +#ifdef FL_ALLOW_STL #include <map> +#endif #include "stb_truetype.h" @@ -31,6 +34,8 @@ /** * A bytemap is an array of bytes, used as an alpha channel when redering glyphs * in a given color. + * TODO: reate a class for RGB only and for grayscale and grayscale with alpha + * TODO: derive all this from a baseclass, so we can create the correct class for the required image */ class Fl_Android_Bytemap { @@ -58,6 +63,12 @@ public: Fl_Android_565A_Map(); Fl_Android_565A_Map(int w, int h); ~Fl_Android_565A_Map(); + static inline uint32_t toRGBA(uchar r, uchar g, uchar b, uchar a) + { + return ((((r << 8) & 0xf800) | + ((g << 3) & 0x07e0) | + ((b >> 3) & 0x001f)) << 16) | a; + } public: int pWidth = 0, pHeight = 0, pStride = 0; @@ -98,7 +109,11 @@ public: */ class Fl_Android_Font_Descriptor : public Fl_Font_Descriptor { +#ifdef FL_ALLOW_STL typedef std::map<uint32_t, Fl_Android_Bytemap*> BytemapTable; +#else + typedef Fl_Android_Bytemap* BytemapTable[256]; +#endif private: Fl_Android_Font_Source *pFontSource; Fl_Font pFontIndex; diff --git a/src/drivers/Android/Fl_Android_Graphics_Font.cxx b/src/drivers/Android/Fl_Android_Graphics_Font.cxx index 18ad02e2c..f15a0c585 100644 --- a/src/drivers/Android/Fl_Android_Graphics_Font.cxx +++ b/src/drivers/Android/Fl_Android_Graphics_Font.cxx @@ -476,10 +476,16 @@ Fl_Android_Font_Descriptor::Fl_Android_Font_Descriptor(const char *fname, Fl_And */ Fl_Android_Font_Descriptor::~Fl_Android_Font_Descriptor() { +#ifdef FL_ALLOW_STL // Life is easy in C++11. for (auto &i: pBytemapTable) { delete i.second; i.second = nullptr; } +#else + for (int i=0; i<256; i++) { + if (pBytemapTable[i]) delete pBytemapTable[i]; + } +#endif } /* @@ -508,6 +514,7 @@ float Fl_Android_Font_Descriptor::get_advance(uint32_t c) Fl_Android_Bytemap *Fl_Android_Font_Descriptor::get_bytemap(uint32_t c) { Fl_Android_Bytemap *bm = 0; +#ifdef FL_ALLOW_STL auto it = pBytemapTable.find(c); if (it==pBytemapTable.end()) { bm = pFontSource->get_bytemap(c, size); @@ -516,6 +523,17 @@ Fl_Android_Bytemap *Fl_Android_Font_Descriptor::get_bytemap(uint32_t c) } else { bm = it->second; } +#else + if (c<256) { + if (pBytemapTable[c]) { + bm = pBytemapTable[c]; + } else { + bm = pFontSource->get_bytemap(c, size); + if (bm) + pBytemapTable[c] = bm; + } + } +#endif return bm; } |
