Android: Implemented font changing ( Fl::set_font(ix, name); )

and other font stuff. Fixed horizontal and vertical line
         drawing to include last pixel. Added stippling to focus rect.
         Added point drawing (slooow).

git-svn-id: file:///fltk/svn/fltk/branches/branch-1.4@12774 ea41ed52-d2ee-0310-a9c1-e6b18d33e121
This commit is contained in:
Matthias Melcher
2018-03-18 20:04:43 +00:00
parent 6dbe7ca8ed
commit c3573d16f3
4 changed files with 207 additions and 79 deletions
@@ -55,7 +55,7 @@ void hello_cb(void*)
int main(int argc, char **argv)
{
Fl::scheme("gleam");
// Fl::scheme("gleam");
win1 = new Fl_Window(20+50, 10, 200, 200, "back");
win1->color(FL_RED);
win1->box(FL_DOWN_BOX);
@@ -83,11 +83,18 @@ int main(int argc, char **argv)
btn->labelfont(FL_TIMES_BOLD_ITALIC);
btn->labelsize(30);
btn = new MyButton((win->w()-280)/2, 200+2*40, 280, 35, "Hello, Android!");
btn = new MyButton((win->w()-280)/2, 200+2*40, 280, 35, "Hello, Font!");
btn->labelfont(FL_COURIER_BOLD_ITALIC);
btn->labelsize(30);
btn->callback(
[](Fl_Widget *w, void*) {
Fl::set_font(FL_COURIER_BOLD_ITALIC, "$DancingScript-Regular.ttf");
w->redraw();
}
);
btn = new MyButton((win->w()-280)/2, 200+3*40, 280, 35, "Hello, Android!");
btn->box(FL_BORDER_BOX);
btn->labelfont(FL_SCREEN);
btn->labelsize(30);
@@ -39,44 +39,16 @@ class Fl_Android_Bytemap;
This class is implemented only on the Windows platform.
*/
class FL_EXPORT Fl_Android_Graphics_Driver : public Fl_Scalable_Graphics_Driver {
#if 0
private:
BOOL alpha_blend_(int x, int y, int w, int h, HDC src_gc, int srcx, int srcy, int srcw, int srch);
int depth; // to support translation
POINT *origins; // to support translation
void set_current_();
protected:
HDC gc_;
int numcount;
int counts[20];
uchar **mask_bitmap_;
uchar **mask_bitmap() {return mask_bitmap_;}
void mask_bitmap(uchar **value) { mask_bitmap_ = value; }
int p_size;
POINT *p;
#endif
class FL_EXPORT Fl_Android_Graphics_Driver : public Fl_Scalable_Graphics_Driver
{
public:
Fl_Android_Graphics_Driver();
virtual ~Fl_Android_Graphics_Driver() override;
#if 0
Fl_GDI_Graphics_Driver() {mask_bitmap_ = NULL; gc_ = NULL; p_size = 0; p = NULL; depth = -1; origins = NULL;}
virtual ~Fl_GDI_Graphics_Driver() { if (p) free(p); delete[] origins;}
virtual int has_feature(driver_feature mask) { return mask & NATIVE; }
char can_do_alpha_blending();
virtual void gc(void *ctxt) { gc_ = (HDC)ctxt; global_gc(); }
virtual void *gc() {return gc_;}
// --- bitmap stuff
Fl_Bitmask create_bitmask(int w, int h, const uchar *array);
void delete_bitmask(Fl_Bitmask bm);
#endif
void make_current(Fl_Window*);
// --- text and font stuff
virtual void draw_unscaled(const char* str, int n, int x, int y) override;
#if 0
virtual void draw_unscaled(int angle, const char *str, int n, int x, int y);
virtual void rtl_draw_unscaled(const char* str, int n, int x, int y);
#endif
virtual double width_unscaled(const char *str, int n) override;
virtual double width_unscaled(unsigned int c) override;
virtual Fl_Fontsize size_unscaled() override;
@@ -84,7 +56,46 @@ public:
virtual int height_unscaled() override;
virtual int descent_unscaled() override;
virtual void font_unscaled(Fl_Font face, Fl_Fontsize size) override;
virtual const char *get_font_name(Fl_Font fnum, int* ap) override;
virtual const char *font_name(int num) override;
virtual int get_font_sizes(Fl_Font fnum, int*& sizep) override;
virtual Fl_Font set_fonts(const char *name) override;
virtual void font_name(int num, const char *name) override;
// --- line drawinf stuff
virtual void rectf_unscaled(float x, float y, float w, float h) override;
void rectf_unclipped(float x, float y, float w, float h);
virtual void point_unscaled(float x, float y) override;
void rect_unscaled(float x, float y, float w, float h);
virtual void xyline_unscaled(float x, float y, float x1) override;
void xyline_unclipped(float x, float y, float x1);
virtual void yxline_unscaled(float x, float y, float y1) override;
void yxline_unclipped(float x, float y, float y1);
// --- clipping
virtual void push_clip(int x, int y, int w, int h) override;
virtual int clip_box(int x, int y, int w, int h, int &X, int &Y, int &W, int &H) override;
virtual int not_clipped(int x, int y, int w, int h) override;
virtual void push_no_clip() override;
virtual void pop_clip() override;
virtual void restore_clip() override;
virtual void clip_region(Fl_Region r) override;
virtual Fl_Region clip_region() override;
virtual void line_style_unscaled(int style, float width, char* dashes) override;
// --- matrix based drawing
// virtual void line_unscaled(float x, float y, float x1, float y1) override;
#if 0
virtual int has_feature(driver_feature mask) { return mask & NATIVE; }
char can_do_alpha_blending();
// --- bitmap stuff
Fl_Bitmask create_bitmask(int w, int h, const uchar *array);
void delete_bitmask(Fl_Bitmask bm);
virtual void draw_unscaled(int angle, const char *str, int n, int x, int y);
virtual void rtl_draw_unscaled(const char* str, int n, int x, int y);
void draw_unscaled(Fl_Pixmap *pxm, float s, int XP, int YP, int WP, int HP, int cx, int cy);
void draw_unscaled(Fl_Bitmap *pxm, float s, int XP, int YP, int WP, int HP, int cx, int cy);
void draw_unscaled(Fl_RGB_Image *img, float s, int XP, int YP, int WP, int HP, int cx, int cy);
@@ -97,15 +108,7 @@ public:
virtual void uncache_pixmap(fl_uintptr_t p);
fl_uintptr_t cache(Fl_Bitmap *img, int w, int h, const uchar *array);
void uncache(Fl_RGB_Image *img, fl_uintptr_t &id_, fl_uintptr_t &mask_);
virtual double width_unscaled(const char *str, int n);
virtual double width_unscaled(unsigned int c);
void text_extents_unscaled(const char*, int n, int& dx, int& dy, int& w, int& h);
int height_unscaled();
int descent_unscaled();
Fl_Fontsize size_unscaled();
#if ! defined(FL_DOXYGEN)
void copy_offscreen_with_alpha(int x,int y,int w,int h,HBITMAP bitmap,int srcx,int srcy);
#endif
virtual void copy_offscreen(int x, int y, int w, int h, Fl_Offscreen pixmap, int srcx, int srcy);
void add_rectangle_to_region(Fl_Region r, int x, int y, int w, int h);
Fl_Region XRectangleRegion(int x, int y, int w, int h);
@@ -118,36 +121,12 @@ protected:
void transformed_vertex0(float x, float y);
void fixloop();
// --- implementation is in src/fl_rect.cxx which includes src/cfg_gfx/gdi_rect.cxx
virtual void point_unscaled(float x, float y);
void rect_unscaled(float x, float y, float w, float h);
void focus_rect(int x, int y, int w, int h);
#endif
virtual void rectf_unscaled(float x, float y, float w, float h) override;
void rectf_unclipped(float x, float y, float w, float h);
#if 0
virtual void line_unscaled(float x, float y, float x1, float y1);
virtual void line_unscaled(float x, float y, float x1, float y1, float x2, float y2);
#endif
virtual void xyline_unscaled(float x, float y, float x1) override;
void xyline_unclipped(float x, float y, float x1);
virtual void yxline_unscaled(float x, float y, float y1) override;
void yxline_unclipped(float x, float y, float y1);
#if 0
virtual void loop_unscaled(float x0, float y0, float x1, float y1, float x2, float y2);
virtual void loop_unscaled(float x0, float y0, float x1, float y1, float x2, float y2, float x3, float y3);
virtual void polygon_unscaled(float x0, float y0, float x1, float y1, float x2, float y2);
virtual void polygon_unscaled(float x0, float y0, float x1, float y1, float x2, float y2, float x3, float y3);
#endif
// --- clipping
virtual void push_clip(int x, int y, int w, int h) override;
virtual int clip_box(int x, int y, int w, int h, int &X, int &Y, int &W, int &H) override;
virtual int not_clipped(int x, int y, int w, int h) override;
virtual void push_no_clip() override;
virtual void pop_clip() override;
virtual void restore_clip() override;
virtual void clip_region(Fl_Region r) override;
virtual Fl_Region clip_region() override;
#if 0
virtual Fl_Region scale_clip(float f);
// --- implementation is in src/fl_vertex.cxx which includes src/cfg_gfx/xxx_rect.cxx
void begin_complex_polygon();
@@ -173,28 +152,26 @@ protected:
void free_color(Fl_Color i, int overlay);
void set_spot(int font, int size, int X, int Y, int W, int H, Fl_Window *win);
void reset_spot();
virtual Fl_Font set_fonts(const char *name);
virtual int get_font_sizes(Fl_Font fnum, int*& sizep);
virtual const char* get_font_name(Fl_Font fnum, int* ap);
virtual const char *font_name(int num);
virtual void font_name(int num, const char *name);
void global_gc();
virtual void overlay_rect(int x, int y, int w , int h);
#endif
protected:
static uint16_t make565(Fl_Color crgba);
void render_bytemap(int x, int y, Fl_Android_Bytemap *bm, Fl_Rect_Region &r);
int render_letter(int xx, int yy, uint32_t c, Fl_Rect_Region &r);
void make_current(Fl_Window*);
int32_t pStride;
uint16_t *pBits;
int pLineStyle = 0;
// Clipping region of the current window in window coordinates (see: pStride and pBits)
Fl_Rect_Region pWindowRegion;
// clipping region of the window minus overlapping other windows
Fl_Complex_Region pDesktopWindowRegion;
// Final clipping region for all graphics calls to this class.
@@ -142,15 +142,24 @@ void Fl_Android_Graphics_Driver::xyline_unscaled(float x, float y, float x1)
void Fl_Android_Graphics_Driver::xyline_unclipped(float x, float y, float x1)
{
uint16_t cc = make565(color());
float w = x1-x;
float w;
if (x1>x) {
w = x1-x+1;
} else {
w = x-x1+1;
x = x1;
}
int32_t sx = 1;
int32_t ss = pStride;
uint16_t *bits = pBits;
uint32_t xx = (uint32_t)x;
uint32_t yy = (uint32_t)y;
uint32_t ww = (uint32_t)w;
uint16_t *d = bits + yy*ss + xx;
if ((pLineStyle&0xff)==FL_DOT) { ww = ww/2; sx = sx*2; }
for (uint32_t ix = ww; ix>0; --ix) {
*d++ = cc;
*d = cc;
d+=sx;
}
}
@@ -158,9 +167,9 @@ void Fl_Android_Graphics_Driver::yxline_unscaled(float x, float y, float y1)
{
float h;
if (y1>y) {
h = y1-y;
h = y1-y+1;
} else {
h = y-y1;
h = y-y1+1;
y = y1;
}
for (const auto &it: pClippingRegion.overlapping(Fl_Rect_Region(x, y, 1, h))) {
@@ -179,6 +188,7 @@ void Fl_Android_Graphics_Driver::yxline_unclipped(float x, float y, float y1)
uint32_t yy = (uint32_t)y;
uint32_t hh = (uint32_t)h;
uint16_t *d = bits + yy*ss + xx;
if ((pLineStyle&0xff)==FL_DOT) { hh = hh/2; ss = ss*2; }
for (uint32_t iy = hh; iy>0; --iy) {
*d = cc;
d += ss;
@@ -186,6 +196,39 @@ void Fl_Android_Graphics_Driver::yxline_unclipped(float x, float y, float y1)
}
void Fl_Android_Graphics_Driver::rect_unscaled(float x, float y, float w, float h)
{
xyline(x, y, x+w-1);
yxline(x, y, y+h-1);
yxline(x+w-1, y, y+h-1);
xyline(x, y+h-1, x+w-1);
}
void Fl_Android_Graphics_Driver::line_style_unscaled(int style, float width, char* dashes)
{
pLineStyle = style;
// TODO: finish this!
}
void Fl_Android_Graphics_Driver::point_unscaled(float x, float y)
{
// drawing a single point is insanely inefficient because we need to walk the
// entire clipping region every time to see if the point needs to be drawn.
for (const auto &it: pClippingRegion.overlapping(Fl_Rect_Region(x, y, 1, 1))) {
Fl_Rect_Region &s = it->clipped_rect();
uint16_t cc = make565(color());
int32_t ss = pStride;
uint16_t *bits = pBits;
uint32_t xx = (uint32_t)x;
uint32_t yy = (uint32_t)y;
uint16_t *d = bits + yy*ss + xx;
*d = cc;
}
}
#if 0
@@ -418,7 +418,16 @@ void Fl_Android_Graphics_Driver::font_unscaled(Fl_Font fnum, Fl_Fontsize size) {
font_ = fnum;
}
/**
* Render a bytemap to the screen using the current fl_color.
*
* Bytes are seen as alpha values for the RGB color set by fl_color. For better
* performance, alpha is only rendered in 5 steps. All rendering is offset as
* described in the bytemap, and clipped to the clipping region.
* @param xx, yy bottom left position of the bytemap (baseline for text)
* @param bm bytemap including offsets and size
* @param r clipping rectangle
*/
void Fl_Android_Graphics_Driver::render_bytemap(int xx, int yy, Fl_Android_Bytemap *bm, Fl_Rect_Region &r)
{
xx += bm->pXOffset; yy += bm->pYOffset;
@@ -475,7 +484,6 @@ void Fl_Android_Graphics_Driver::render_bytemap(int xx, int yy, Fl_Android_Bytem
}
/**
* Copy a single letter to the screen.
* @param xx, yy position of character on screen
@@ -594,7 +602,99 @@ int Fl_Android_Graphics_Driver::descent_unscaled()
return fd->descent;
}
/**
* Get a human-readable string describing the family of this face.
* @param fnum index into font table
* @param ap[out] returns if the face is bold or italic or both.
* @return pointer to a string; don't free, don't write
*/
const char *Fl_Android_Graphics_Driver::get_font_name(Fl_Font fnum, int* ap)
{
const char *name = fl_fonts[fnum].name;
if (ap) {
*ap = 0;
if (strstr(name, "BoldItalic")) *ap = FL_BOLD_ITALIC;
else if (strstr(name, "Bold")) *ap = FL_BOLD;
else if (strstr(name, "Italic")) *ap = FL_ITALIC;
}
return name;
}
/**
* Gets the string for this face.
* @param num index into font table
* @return pointer to a string; don't free, don't write
*/
const char *Fl_Android_Graphics_Driver::font_name(int num)
{
// TODO: we should probably beatify the font name, remove file path and
// extension, and save the result in fl_fonts[num].fontname ...
return fl_fonts[num].name;
}
/**
* Return an array of sizes in sizep.
* @param fnum index into font table
* @param sizep[out] a static array that contains the single value 0, indicating
* that all fonts are arbitrarily resizable.
* @return 1, because our array has a size of 1
*/
int Fl_Android_Graphics_Driver::get_font_sizes(Fl_Font fnum, int*& sizep)
{
static int sSizes[] = { 0 };
sizep = sSizes;
return 1;
}
/**
* FLTK will open the display, and add every fonts on the server to the face table.
* TODO: This is not supported under Android.
* @param name basically a wildcard for finding fonts
* @return number of fonts found
*/
Fl_Font Fl_Android_Graphics_Driver::set_fonts(const char *name)
{
return 16;
}
/**
* Changes a face.
* @param num index of the font
* @param name Path to font file, prepend $ for system fonts, @ for font assets.
* The string pointer is simply stored, the string is not copied, so the
* string must be in static memory.
*/
void Fl_Android_Graphics_Driver::font_name(int num, const char *name)
{
Fl_Fontdesc *s = fl_fonts + num;
// if the same font is requested, do nothing
if (s && s->name && name && strcmp(s->name, name)==0) {
s->name = name;
return;
}
// if a font is loaded, delete the all descriptors, caches, and the source
Fl_Android_Font_Descriptor *desc = (Fl_Android_Font_Descriptor*)s->first;
if (desc) {
Fl_Android_Font_Source *src = desc->get_font_source();
while (desc) {
auto nDesc = (Fl_Android_Font_Descriptor*)desc->next;
delete desc; desc = nDesc;
}
delete src; src = nullptr;
}
s->name = nullptr;
s->fontname[0] = 0;
s->first = nullptr;
// set the new font name
if (name) {
// the next time the font is used, it will be loaded and initialized
s->name = name;
s->fontname[0] = 0;
}
}
#if 0
@@ -708,6 +808,7 @@ int Fl_Quartz_Graphics_Driver::get_font_sizes(Fl_Font fnum, int*& sizep) {
return cnt;
}
#endif
//