summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMatthias Melcher <fltk@matthiasm.com>2018-03-26 21:28:18 +0000
committerMatthias Melcher <fltk@matthiasm.com>2018-03-26 21:28:18 +0000
commit3b7e1a5ec69d606488f5adf5ca15bf9baf67818f (patch)
tree938156a6055f58590e6d77e5f0a6adcd90ac99fc
parent5040bbff1f11f83baa424021b4c75ad7a6e053f8 (diff)
Android: Draws Fl_Bitmap.
git-svn-id: file:///fltk/svn/fltk/branches/branch-1.4@12807 ea41ed52-d2ee-0310-a9c1-e6b18d33e121
-rw-r--r--FL/platform_types.h8
-rw-r--r--ide/AndroidStudio3/app/src/main/cpp/HelloAndroid.cxx43
-rw-r--r--src/drivers/Android/Fl_Android_Graphics_Driver.H5
-rw-r--r--src/drivers/Android/Fl_Android_Graphics_Driver.cxx266
-rw-r--r--src/drivers/Android/Fl_Android_Graphics_Font.H6
-rw-r--r--src/drivers/Android/Fl_Android_Graphics_Font.cxx12
6 files changed, 87 insertions, 253 deletions
diff --git a/FL/platform_types.h b/FL/platform_types.h
index 9f6ed1e44..d90e37afa 100644
--- a/FL/platform_types.h
+++ b/FL/platform_types.h
@@ -72,6 +72,12 @@ typedef opaque GLContext; /**< an OpenGL graphics context, into which all OpenGL
typedef intptr_t fl_intptr_t;
typedef uintptr_t fl_uintptr_t;
+#elif defined(__ANDROID__)
+
+#include <sys/stat.h>
+typedef intptr_t fl_intptr_t;
+typedef uintptr_t fl_uintptr_t;
+
#else /* ! _WIN64 */
typedef long fl_intptr_t;
@@ -125,10 +131,10 @@ typedef unsigned long Fl_Offscreen;
typedef unsigned long Fl_Bitmask;
typedef int FL_SOCKET;
typedef struct __GLXcontextRec *GLContext;
-#include <sys/stat.h>
#include <sys/types.h>
#include <dirent.h>
+
#elif defined(FL_PORTING)
# pragma message "FL_PORTING: define OS-dependent types"
typedef void* Fl_Offscreen;
diff --git a/ide/AndroidStudio3/app/src/main/cpp/HelloAndroid.cxx b/ide/AndroidStudio3/app/src/main/cpp/HelloAndroid.cxx
index 6d7c055f2..e0623f172 100644
--- a/ide/AndroidStudio3/app/src/main/cpp/HelloAndroid.cxx
+++ b/ide/AndroidStudio3/app/src/main/cpp/HelloAndroid.cxx
@@ -89,7 +89,44 @@ int main(int argc, char **argv)
#elif 1
+#include <stdlib.h>
+#include <FL/Fl.H>
+#include <FL/Fl_Double_Window.H>
+#include <FL/Fl_Adjuster.H>
+#include <FL/Fl_Box.H>
+
+void adjcb(Fl_Widget *o, void *v) {
+ Fl_Adjuster *a = (Fl_Adjuster*)o;
+ Fl_Box *b = (Fl_Box *)v;
+ a->format((char *)(b->label()));
+ b->redraw();
+}
+
+int main(int argc, char ** argv) {
+ Fl_Double_Window window(320,100,argv[0]);
+
+ char buf1[100];
+ Fl_Box b1(FL_DOWN_BOX,20,30,80,25,buf1);
+ b1.color(FL_WHITE);
+ Fl_Adjuster a1(20+80,30,3*25,25);
+ a1.callback(adjcb,&b1);
+ adjcb(&a1,&b1);
+
+ char buf2[100];
+ Fl_Box b2(FL_DOWN_BOX,20+80+4*25,30,80,25,buf2);
+ b2.color(FL_WHITE);
+ Fl_Adjuster a2(b2.x()+b2.w(),10,25,3*25);
+ a2.callback(adjcb,&b2);
+ adjcb(&a2,&b2);
+
+ window.resizable(window);
+ window.end();
+ window.show(argc, argv);
+ return Fl::run();
+}
+
+#elif 0
#include <FL/Fl.H>
@@ -411,7 +448,7 @@ int xmain(int argc, char **argv)
test/CubeMain.cxx test/line_style.cxx
test/CubeView.cxx test/list_visuals.cxx
- * test/adjuster.cxx : - missing bitmap drawing
+ * test/adjuster.cxx : + 'adjuster' works
test/mandelbrot.cxx
test/animated.cxx test/menubar.cxx
* test/arc.cxx : + 'arc' works as expected
@@ -420,7 +457,7 @@ test/ask.cxx
* test/minimum.cxx : + 'minimum' works
test/bitmap.cxx test/native-filechooser.cxx
test/blocks.cxx test/navigation.cxx
- * test/boxtype.cxx : + 'boxtype': works
+ * test/boxtype.cxx : + 'boxtype' works
test/offscreen.cxx
test/browser.cxx test/output.cxx
test/button.cxx test/overlay.cxx
@@ -456,6 +493,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, keyboard events
+ * test/label.cxx : - pixmap
*/ \ 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 eebd05db1..e6b4991a2 100644
--- a/src/drivers/Android/Fl_Android_Graphics_Driver.H
+++ b/src/drivers/Android/Fl_Android_Graphics_Driver.H
@@ -118,6 +118,10 @@ public:
// --- matrix based drawing
// virtual void line_unscaled(float x, float y, float x1, float y1) override;
+ // --- image drawing
+
+ virtual void draw_unscaled(Fl_Bitmap *pxm, float s, int XP, int YP, int WP, int HP, int cx, int cy) override;
+ virtual fl_uintptr_t cache(Fl_Bitmap *img) override;
#if 0
virtual int has_feature(driver_feature mask) { return mask & NATIVE; }
@@ -128,7 +132,6 @@ public:
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);
int draw_scaled(Fl_Image *img, int XP, int YP, int WP, int HP);
virtual void draw_image_unscaled(const uchar* buf, int X,int Y,int W,int H, int D=3, int L=0);
diff --git a/src/drivers/Android/Fl_Android_Graphics_Driver.cxx b/src/drivers/Android/Fl_Android_Graphics_Driver.cxx
index 2198735b9..c727a9d0e 100644
--- a/src/drivers/Android/Fl_Android_Graphics_Driver.cxx
+++ b/src/drivers/Android/Fl_Android_Graphics_Driver.cxx
@@ -904,264 +904,42 @@ void Fl_Android_Graphics_Driver::ellipse_unscaled(double xt, double yt, double r
}
-#if 0
-
-// Code used to switch output to an off-screen window. See macros in
-// win32.H which save the old state in local variables.
-
-typedef struct { BYTE a; BYTE b; BYTE c; BYTE d; } FL_BLENDFUNCTION;
-typedef BOOL (WINAPI* fl_alpha_blend_func)
-(HDC,int,int,int,int,HDC,int,int,int,int,FL_BLENDFUNCTION);
-static fl_alpha_blend_func fl_alpha_blend = NULL;
-static FL_BLENDFUNCTION blendfunc = { 0, 0, 255, 1};
-
-/* Reference to the current device context
- For back-compatibility only. The preferred procedure to get this reference is
- Fl_Surface_Device::surface()->driver()->gc().
- */
-HDC fl_gc = 0;
-
-void Fl_GDI_Graphics_Driver::global_gc()
+void Fl_Android_Graphics_Driver::draw_unscaled(Fl_Bitmap *bm, float s, int XP, int YP, int WP, int HP, int cx, int cy)
{
- fl_gc = (HDC)gc();
-}
-
-/*
- * This function checks if the version of Windows that we
- * curently run on supports alpha blending for bitmap transfers
- * and finds the required function if so.
- */
-char Fl_GDI_Graphics_Driver::can_do_alpha_blending() {
- static char been_here = 0;
- static char can_do = 0;
- // do this test only once
- if (been_here) return can_do;
- been_here = 1;
- // load the library that implements alpha blending
- HMODULE hMod = LoadLibrary("MSIMG32.DLL");
- // give up if that doesn't exist (Win95?)
- if (!hMod) return 0;
- // now find the blending function inside that dll
- fl_alpha_blend = (fl_alpha_blend_func)GetProcAddress(hMod, "AlphaBlend");
- // give up if we can't find it (Win95)
- if (!fl_alpha_blend) return 0;
- // we have the call, but does our display support alpha blending?
- // get the desktop's device context
- HDC dc = GetDC(0L);
- if (!dc) return 0;
- // check the device capabilities flags. However GetDeviceCaps
- // does not return anything useful, so we have to do it manually:
-
- HBITMAP bm = CreateCompatibleBitmap(dc, 1, 1);
- HDC new_gc = CreateCompatibleDC(dc);
- int save = SaveDC(new_gc);
- SelectObject(new_gc, bm);
- /*COLORREF set = */ SetPixel(new_gc, 0, 0, 0x01010101);
- BOOL alpha_ok = fl_alpha_blend(dc, 0, 0, 1, 1, new_gc, 0, 0, 1, 1, blendfunc);
- RestoreDC(new_gc, save);
- DeleteDC(new_gc);
- DeleteObject(bm);
- ReleaseDC(0L, dc);
-
- if (alpha_ok) can_do = 1;
- return can_do;
-}
-
-HDC fl_makeDC(HBITMAP bitmap) {
- HDC new_gc = CreateCompatibleDC((HDC)Fl_Graphics_Driver::default_driver().gc());
- SetTextAlign(new_gc, TA_BASELINE|TA_LEFT);
- SetBkMode(new_gc, TRANSPARENT);
-#if USE_COLORMAP
- if (fl_palette) SelectPalette(new_gc, fl_palette, FALSE);
-#endif
- SelectObject(new_gc, bitmap);
- return new_gc;
-}
-
-void Fl_GDI_Graphics_Driver::copy_offscreen(int x, int y, int w, int h, Fl_Offscreen bitmap, int srcx, int srcy) {
- HDC new_gc = CreateCompatibleDC(gc_);
- int save = SaveDC(new_gc);
- SelectObject(new_gc, bitmap);
- BitBlt(gc_, x*scale_, y*scale_, w*scale_, h*scale_, new_gc, srcx*scale_, srcy*scale_, SRCCOPY);
- RestoreDC(new_gc, save);
- DeleteDC(new_gc);
-}
-
-BOOL Fl_GDI_Graphics_Driver::alpha_blend_(int x, int y, int w, int h, HDC src_gc, int srcx, int srcy, int srcw, int srch) {
- return fl_alpha_blend(gc_, x, y, w, h, src_gc, srcx, srcy, srcw, srch, blendfunc);
-}
-
-#if ! defined(FL_DOXYGEN)
-void Fl_GDI_Graphics_Driver::copy_offscreen_with_alpha(int x,int y,int w,int h,HBITMAP bitmap,int srcx,int srcy) {
- HDC new_gc = CreateCompatibleDC(gc_);
- int save = SaveDC(new_gc);
- SelectObject(new_gc, bitmap);
- BOOL alpha_ok = 0;
- // first try to alpha blend
- if ( can_do_alpha_blending() ) {
- alpha_ok = alpha_blend_(x, y, w, h, new_gc, srcx, srcy, w, h);
- }
- // if that failed (it shouldn't), still copy the bitmap over, but now alpha is 1
- if (!alpha_ok) {
- BitBlt(gc_, x, y, w, h, new_gc, srcx, srcy, SRCCOPY);
- }
- RestoreDC(new_gc, save);
- DeleteDC(new_gc);
-}
-
-void Fl_GDI_Graphics_Driver::translate_all(int x, int y) {
- const int stack_height = 10;
- if (depth == -1) {
- origins = new POINT[stack_height];
- depth = 0;
- }
- if (depth >= stack_height) {
- Fl::warning("Fl_Copy/Image_Surface: translate stack overflow!");
- depth = stack_height - 1;
+ int X, Y, W, H;
+ if (Fl_Graphics_Driver::prepare(bm, XP, YP, WP, HP, cx, cy, X, Y, W, H)) {
+ return;
}
- GetWindowOrgEx((HDC)gc(), origins+depth);
- SetWindowOrgEx((HDC)gc(), origins[depth].x - x*scale_, origins[depth].y - y*scale_, NULL);
- depth++;
-}
-
-void Fl_GDI_Graphics_Driver::untranslate_all() {
- if (depth > 0) depth--;
- SetWindowOrgEx((HDC)gc(), origins[depth].x, origins[depth].y, NULL);
-}
-#endif
-
-void Fl_GDI_Graphics_Driver::add_rectangle_to_region(Fl_Region r, int X, int Y, int W, int H) {
- Fl_Region R = XRectangleRegion(X, Y, W, H);
- CombineRgn(r, r, R, RGN_OR);
- XDestroyRegion(R);
-}
-
-void Fl_GDI_Graphics_Driver::transformed_vertex0(float x, float y) {
- if (!n || x != p[n-1].x || y != p[n-1].y) {
- if (n >= p_size) {
- p_size = p ? 2*p_size : 16;
- p = (POINT*)realloc((void*)p, p_size*sizeof(*p));
+ if (*Fl_Graphics_Driver::id(bm)) {
+ Fl_Android_Bytemap *cache = (Fl_Android_Bytemap*)*Fl_Graphics_Driver::id(bm);
+ for (const auto &it: pClippingRegion.overlapping(Fl_Rect_Region(X, Y, W, H))) {
+ render_bytemap(XP, YP, cache, it->clipped_rect());
}
- p[n].x = x;
- p[n].y = y;
- n++;
}
}
-void Fl_GDI_Graphics_Driver::fixloop() { // remove equal points from closed path
- while (n>2 && p[n-1].x == p[0].x && p[n-1].y == p[0].y) n--;
-}
-
-Fl_Region Fl_GDI_Graphics_Driver::XRectangleRegion(int x, int y, int w, int h) {
- if (Fl_Surface_Device::surface() == Fl_Display_Device::display_device()) return CreateRectRgn(x,y,x+w,y+h);
- // because rotation may apply, the rectangle becomes a polygon in device coords
- POINT pt[4] = { {x, y}, {x + w, y}, {x + w, y + h}, {x, y + h} };
- LPtoDP((HDC)fl_graphics_driver->gc(), pt, 4);
- return CreatePolygonRgn(pt, 4, ALTERNATE);
-}
-
-void Fl_GDI_Graphics_Driver::XDestroyRegion(Fl_Region r) {
- DeleteObject(r);
-}
-
-
-typedef BOOL(WINAPI* flTypeImmAssociateContextEx)(HWND, HIMC, DWORD);
-extern flTypeImmAssociateContextEx flImmAssociateContextEx;
-typedef HIMC(WINAPI* flTypeImmGetContext)(HWND);
-extern flTypeImmGetContext flImmGetContext;
-typedef BOOL(WINAPI* flTypeImmSetCompositionWindow)(HIMC, LPCOMPOSITIONFORM);
-extern flTypeImmSetCompositionWindow flImmSetCompositionWindow;
-typedef BOOL(WINAPI* flTypeImmReleaseContext)(HWND, HIMC);
-extern flTypeImmReleaseContext flImmReleaseContext;
-
-
-void Fl_GDI_Graphics_Driver::reset_spot()
-{
-}
-void Fl_GDI_Graphics_Driver::set_spot(int font, int size, int X, int Y, int W, int H, Fl_Window *win)
+fl_uintptr_t Fl_Android_Graphics_Driver::cache(Fl_Bitmap *bm)
{
- if (!win) return;
- Fl_Window* tw = win;
- while (tw->parent()) tw = tw->window(); // find top level window
-
- if (!tw->shown())
- return;
-
- HIMC himc = flImmGetContext(fl_xid(tw));
-
- if (himc) {
- COMPOSITIONFORM cfs;
- cfs.dwStyle = CFS_POINT;
- cfs.ptCurrentPos.x = X;
- cfs.ptCurrentPos.y = Y - tw->labelsize();
- MapWindowPoints(fl_xid(win), fl_xid(tw), &cfs.ptCurrentPos, 1);
- flImmSetCompositionWindow(himc, &cfs);
- flImmReleaseContext(fl_xid(tw), himc);
- }
-}
-
+ int w = bm->w(), h = bm->h();
+ int rowBytes = (w+7)>>3;
-void Fl_GDI_Graphics_Driver::scale(float f) {
- if (f != scale_) {
- size_ = 0;
- scale_ = f;
-//fprintf(LOG,"set scale to %f\n",f);fflush(LOG);
- }
-}
-
-
-/* Rescale region r with factor f and returns the scaled region.
- Region r is returned unchanged if r is null or f is 1.
- The input region is deleted if dr is null.
- */
-HRGN Fl_GDI_Graphics_Driver::scale_region(HRGN r, float f, Fl_GDI_Graphics_Driver *dr) {
- if (r && f != 1) {
- DWORD size = GetRegionData(r, 0, NULL);
- RGNDATA *pdata = (RGNDATA*)malloc(size);
- GetRegionData(r, size, pdata);
- if (!dr) DeleteObject(r);
- POINT pt = {0, 0};
- if (dr && dr->depth >= 1) { // account for translation
- GetWindowOrgEx((HDC)dr->gc(), &pt);
- pt.x *= (f - 1);
- pt.y *= (f - 1);
- }
- RECT *rects = (RECT*)&(pdata->Buffer);
- int delta = (f > 1.75 ? 1 : 0) - int(f/2);
- for (DWORD i = 0; i < pdata->rdh.nCount; i++) {
- int x = rects[i].left * f + pt.x;
- int y = rects[i].top * f + pt.y;
- RECT R2;
- R2.left = x + delta;
- R2.top = y + delta;
- R2.right = int(rects[i].right * f) + pt.x - x + R2.left;
- R2.bottom = int(rects[i].bottom * f) + pt.y - y + R2.top;
- rects[i] = R2;
+ Fl_Android_Bytemap *cache = new Fl_Android_Bytemap(w, h);
+ for (int yy=0; yy<w; yy++) {
+ const uchar *src = bm->array + yy*rowBytes;
+ uchar *dst = cache->pBytes + yy*cache->pStride;
+ uchar d;
+ for (int xx=0; xx<w; xx++) {
+ if ((xx&7)==0) d = *src++;
+ if (d&1) *dst = 0xff; else *dst = 0;
+ dst++;
+ d >>= 1;
}
- r = ExtCreateRegion(NULL, size, pdata);
- free(pdata);
}
- return r;
-}
-
-Fl_Region Fl_GDI_Graphics_Driver::scale_clip(float f) {
- HRGN r = rstack[rstackptr];
- HRGN r2 = scale_region(r, f, this);
- return (r == r2 ? NULL : (rstack[rstackptr] = r2, r));
+ return (fl_uintptr_t)cache;
}
-void Fl_GDI_Graphics_Driver::set_current_() {
- restore_clip();
-}
-
-#endif
-
-/*
-
- */
-
//
// End of "$Id$".
//
diff --git a/src/drivers/Android/Fl_Android_Graphics_Font.H b/src/drivers/Android/Fl_Android_Graphics_Font.H
index e53a9cc05..0966c7830 100644
--- a/src/drivers/Android/Fl_Android_Graphics_Font.H
+++ b/src/drivers/Android/Fl_Android_Graphics_Font.H
@@ -36,11 +36,13 @@ class Fl_Android_Bytemap
{
public:
Fl_Android_Bytemap();
+ Fl_Android_Bytemap(int w, int h);
~Fl_Android_Bytemap();
public:
- int pWidth, pHeight, pStride, pXOffset, pYOffset, pAdvance;
- unsigned char *pBytes;
+ int pWidth = 0, pHeight = 0, pStride = 0;
+ int pXOffset = 0, pYOffset = 0, pAdvance = 0;
+ unsigned char *pBytes = nullptr;
};
diff --git a/src/drivers/Android/Fl_Android_Graphics_Font.cxx b/src/drivers/Android/Fl_Android_Graphics_Font.cxx
index da8f9ddf4..21a7c1fe2 100644
--- a/src/drivers/Android/Fl_Android_Graphics_Font.cxx
+++ b/src/drivers/Android/Fl_Android_Graphics_Font.cxx
@@ -68,12 +68,20 @@ static const char *old_font_names[] = {
/**
* Create an empty Bytemap.
*/
-Fl_Android_Bytemap::Fl_Android_Bytemap() :
- pBytes(nullptr)
+Fl_Android_Bytemap::Fl_Android_Bytemap()
{
}
/**
+ * Create an empty Bytemap.
+ */
+Fl_Android_Bytemap::Fl_Android_Bytemap(int w, int h)
+{
+ pWidth = w; pStride = w; pHeight = h;
+ pBytes = (unsigned char *)malloc(w*h);
+}
+
+/**
* Destroy the Bytemap and its allocated resources.
*/
Fl_Android_Bytemap::~Fl_Android_Bytemap()