mirror of https://github.com/fltk/fltk
Android: Drawing RGB image data (and probaly rgba and grayscale as well). Testing unsing test/color_chooser.cxx
git-svn-id: file:///fltk/svn/fltk/branches/branch-1.4@12817 ea41ed52-d2ee-0310-a9c1-e6b18d33e121
This commit is contained in:
parent
e4916d617e
commit
936fbd096f
|
@ -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
|
||||
|
|
|
@ -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" />
|
||||
|
|
|
@ -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"
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#if !defined(_WIN32) && !defined(__APPLE__) && !defined(FL_PORTING) && !defined(__ANDROID__)
|
||||
#include "list_visuals.cxx"
|
||||
#endif
|
||||
|
||||
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;
|
||||
int width = 100;
|
||||
int height = 100;
|
||||
uchar *image;
|
||||
Fl_Box *hint;
|
||||
|
||||
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();
|
||||
}
|
||||
|
||||
void normal_cb(Fl_Widget *,void *) {
|
||||
text->labeltype(FL_NORMAL_LABEL);
|
||||
window->redraw();
|
||||
}
|
||||
|
||||
void symbol_cb(Fl_Widget *,void *) {
|
||||
text->labeltype(FL_SYMBOL_LABEL);
|
||||
if (input->value()[0] != '@') {
|
||||
input->static_value("@->");
|
||||
text->label("@->");
|
||||
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
|
||||
}
|
||||
}
|
||||
window->redraw();
|
||||
}
|
||||
|
||||
void shadow_cb(Fl_Widget *,void *) {
|
||||
text->labeltype(FL_SHADOW_LABEL);
|
||||
window->redraw();
|
||||
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());
|
||||
}
|
||||
}
|
||||
|
||||
void embossed_cb(Fl_Widget *,void *) {
|
||||
text->labeltype(FL_EMBOSSED_LABEL);
|
||||
window->redraw();
|
||||
Fl_Color c = FL_GRAY;
|
||||
#define fullcolor_cell (FL_FREE_COLOR)
|
||||
|
||||
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
|
||||
|
||||
*/
|
|
@ -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:
|
||||
|
|
|
@ -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$".
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue