mirror of
https://github.com/fltk/fltk.git
synced 2026-05-24 16:36:37 +08:00
Android: added text clipping in all its uglyness.
Next: intersetcing a complex clipping region with a rectangle git-svn-id: file:///fltk/svn/fltk/branches/branch-1.4@12769 ea41ed52-d2ee-0310-a9c1-e6b18d33e121
This commit is contained in:
@@ -68,9 +68,10 @@ int main(int argc, char **argv)
|
||||
btn2 = new Fl_Button(10, 10, 480, 100, "-@circle;-");
|
||||
btn2->color(FL_BLUE);
|
||||
|
||||
btn = new MyButton((win->w()-280)/2, 200-45, 280, 80, "Hello, Android!\nWhere were you?");
|
||||
btn = new MyButton((win->w()-280)/2, 200-45, 280, 80, "Hello, Android!\nWhere have you been so long?");
|
||||
btn->color(FL_LIGHT2);
|
||||
btn->labelsize(30);
|
||||
btn->align(FL_ALIGN_CLIP);
|
||||
btn->callback(
|
||||
[](Fl_Widget*, void*) {
|
||||
Fl::add_timeout(1.0, hello_cb, NULL);
|
||||
|
||||
@@ -280,6 +280,8 @@ void Fl_Complex_Region::set(const Fl_Complex_Region &r)
|
||||
*/
|
||||
int Fl_Complex_Region::intersect_with(const Fl_Rect_Region &r)
|
||||
{
|
||||
set(r);
|
||||
return LESS;
|
||||
delete pSubregion; pSubregion = 0;
|
||||
// FIXME: handle complex regions!
|
||||
int ret = Fl_Rect_Region::intersect_with(r);
|
||||
|
||||
@@ -27,11 +27,12 @@
|
||||
|
||||
#include <FL/Fl_Graphics_Driver.H>
|
||||
#include "Fl_Android_Graphics_Clipping.H"
|
||||
#include "Fl_Android_Graphics_Font.H"
|
||||
#include <limits.h>
|
||||
|
||||
|
||||
class Fl_Android_Window_Driver;
|
||||
|
||||
class Fl_Android_Bytemap;
|
||||
|
||||
/**
|
||||
\brief The Windows-specific graphics driver class.
|
||||
@@ -184,7 +185,8 @@ protected:
|
||||
|
||||
static uint16_t make565(Fl_Color crgba);
|
||||
|
||||
int render_letter(int xx, int yy, uint32_t c);
|
||||
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;
|
||||
|
||||
@@ -97,7 +97,7 @@ uint16_t Fl_Android_Graphics_Driver::make565(Fl_Color crgba)
|
||||
void Fl_Android_Graphics_Driver::rectf_unscaled(float x, float y, float w, float h)
|
||||
{
|
||||
for (const auto &it: pClippingRegion.overlapping(Fl_Rect_Region(x, y, w, h))) {
|
||||
Fl_Rect_Region s(it->clipped_rect());
|
||||
Fl_Rect_Region &s = it->clipped_rect();
|
||||
rectf_unclipped(s.x(), s.y(), s.w(), s.h());
|
||||
}
|
||||
}
|
||||
@@ -133,7 +133,7 @@ void Fl_Android_Graphics_Driver::xyline_unscaled(float x, float y, float x1)
|
||||
x = x1;
|
||||
}
|
||||
for (const auto &it: pClippingRegion.overlapping(Fl_Rect_Region(x, y, w, 1))) {
|
||||
Fl_Rect_Region s(it->clipped_rect());
|
||||
Fl_Rect_Region &s = it->clipped_rect();
|
||||
xyline_unclipped(s.x(), s.y(), s.right());
|
||||
}
|
||||
}
|
||||
@@ -164,7 +164,7 @@ void Fl_Android_Graphics_Driver::yxline_unscaled(float x, float y, float y1)
|
||||
y = y1;
|
||||
}
|
||||
for (const auto &it: pClippingRegion.overlapping(Fl_Rect_Region(x, y, 1, h))) {
|
||||
Fl_Rect_Region s(it->clipped_rect());
|
||||
Fl_Rect_Region &s = it->clipped_rect();
|
||||
yxline_unclipped(s.x(), s.y(), s.bottom());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -416,33 +416,35 @@ void Fl_Android_Graphics_Driver::font_unscaled(Fl_Font fnum, Fl_Fontsize size) {
|
||||
font_ = fnum;
|
||||
}
|
||||
|
||||
/**
|
||||
* Copy a single letter to the screen.
|
||||
* @param xx, yy position of character on screen
|
||||
* @param c unicode character
|
||||
* @return x position of next character on screen
|
||||
*/
|
||||
int Fl_Android_Graphics_Driver::render_letter(int xx, int yy, uint32_t c)
|
||||
|
||||
void Fl_Android_Graphics_Driver::render_bytemap(int xx, int yy, Fl_Android_Bytemap *bm, Fl_Rect_Region &r)
|
||||
{
|
||||
int oxx = xx;
|
||||
|
||||
// find the font descriptor
|
||||
Fl_Android_Font_Descriptor *fd = (Fl_Android_Font_Descriptor*)font_descriptor();
|
||||
if (!fd) return xx; // this should not happen
|
||||
|
||||
Fl_Android_Bytemap *bm = fd->get_bytemap(c);
|
||||
if (!bm) return oxx;
|
||||
|
||||
// rrrr.rggg.gggb.bbbb
|
||||
xx += bm->pXOffset; yy += bm->pYOffset;
|
||||
|
||||
if (xx>r.right()) return;
|
||||
if (yy>r.bottom()) return;
|
||||
if (xx+bm->pWidth < r.left()) return;
|
||||
if (yy+bm->pHeight < r.top()) return;
|
||||
|
||||
uint16_t cc = make565(fl_color()), cc12 = (cc&0xf7de)>>1, cc14 = (cc12&0xf7de)>>1, cc34 = cc12+cc14;
|
||||
int32_t ss = pStride;
|
||||
uint16_t *bits = pBits;
|
||||
uint32_t ww = bm->pWidth;
|
||||
uint32_t hh = bm->pHeight;
|
||||
unsigned char *srcBytes = bm->pBytes;
|
||||
|
||||
int dx = r.left()-xx;
|
||||
int dy = r.top()-yy;
|
||||
int dr = (xx+ww)-r.right();
|
||||
int db = (yy+hh)-r.bottom();
|
||||
if (dx>0) { xx+=dx; ww-=dx; srcBytes+=dx; }
|
||||
if (dy>0) { yy+=dy; hh-=dy; srcBytes+=dy*bm->pStride; }
|
||||
if (dr>0) { ww-=dr; }
|
||||
if (db>0) { hh-=db; }
|
||||
|
||||
for (uint32_t iy = 0; iy<hh; ++iy) {
|
||||
uint16_t *d = bits + (yy+iy)*ss + xx;
|
||||
unsigned char *s = bm->pBytes + iy*bm->pStride;
|
||||
unsigned char *s = srcBytes + iy*bm->pStride;
|
||||
for (uint32_t ix = 0; ix<ww; ++ix) {
|
||||
#if 1
|
||||
// 5 step antialiasing
|
||||
@@ -468,6 +470,29 @@ int Fl_Android_Graphics_Driver::render_letter(int xx, int yy, uint32_t c)
|
||||
d++;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Copy a single letter to the screen.
|
||||
* @param xx, yy position of character on screen
|
||||
* @param c unicode character
|
||||
* @return x position of next character on screen
|
||||
*/
|
||||
int Fl_Android_Graphics_Driver::render_letter(int xx, int yy, uint32_t c, Fl_Rect_Region &r)
|
||||
{
|
||||
int oxx = xx;
|
||||
|
||||
// find the font descriptor
|
||||
Fl_Android_Font_Descriptor *fd = (Fl_Android_Font_Descriptor*)font_descriptor();
|
||||
if (!fd) return xx; // this should not happen
|
||||
|
||||
Fl_Android_Bytemap *bm = fd->get_bytemap(c);
|
||||
if (!bm) return oxx;
|
||||
|
||||
render_bytemap(xx, yy, bm, r);
|
||||
|
||||
return oxx + bm->pAdvance;
|
||||
}
|
||||
|
||||
@@ -480,21 +505,29 @@ int Fl_Android_Graphics_Driver::render_letter(int xx, int yy, uint32_t c)
|
||||
void Fl_Android_Graphics_Driver::draw_unscaled(const char* str, int n, int x, int y)
|
||||
{
|
||||
if (str) {
|
||||
const char *e = str+n;
|
||||
for (int i=0; i<n; ) {
|
||||
int incr = 1;
|
||||
unsigned uniChar = fl_utf8decode(str + i, e, &incr);
|
||||
int x1 = x;
|
||||
x = render_letter(x, y, uniChar);
|
||||
int dx, dy, w, h;
|
||||
text_extents_unscaled(str, n, dx, dy, w, h);
|
||||
pClippingRegion.print("<---- clip text to this");
|
||||
Fl_Rect_Region(x+dx, y+dy, w, h).print(str);
|
||||
for (const auto &it: pClippingRegion.overlapping(Fl_Rect_Region(x+dx, y+dy, w, h))) {
|
||||
Fl_Rect_Region &r = it->clipped_rect();
|
||||
r.print("Clip");
|
||||
const char *e = str + n;
|
||||
for (int i = 0; i < n;) {
|
||||
int incr = 1;
|
||||
unsigned uniChar = fl_utf8decode(str + i, e, &incr);
|
||||
int x1 = x;
|
||||
x = render_letter(x, y, uniChar, r);
|
||||
#if 0
|
||||
// use this to make the character baseline visible
|
||||
Fl_Color old = fl_color();
|
||||
fl_color(FL_RED);
|
||||
fl_xyline(x1, y, x);
|
||||
fl_yxline(x1, y-5, y+5);
|
||||
fl_color(old);
|
||||
// use this to make the character baseline visible
|
||||
Fl_Color old = fl_color();
|
||||
fl_color(FL_RED);
|
||||
fl_xyline(x1, y, x);
|
||||
fl_yxline(x1, y-5, y+5);
|
||||
fl_color(old);
|
||||
#endif
|
||||
i += incr;
|
||||
i += incr;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -535,10 +568,10 @@ Fl_Fontsize Fl_Android_Graphics_Driver::size_unscaled()
|
||||
|
||||
void Fl_Android_Graphics_Driver::text_extents_unscaled(const char *str, int n, int &dx, int &dy, int &w, int &h)
|
||||
{
|
||||
dx = 0;
|
||||
dy = descent_unscaled();
|
||||
w = width_unscaled(str, n);
|
||||
h = height_unscaled();
|
||||
dx = 0;
|
||||
dy = descent_unscaled() - h;
|
||||
}
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user