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 +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 #include #include + #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 +#include +#include +#include +#include +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 @@ -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; - } - 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)); - } - 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) -{ - if (!win) return; - Fl_Window* tw = win; - while (tw->parent()) tw = tw->window(); // find top level window - - if (!tw->shown()) + int X, Y, W, H; + if (Fl_Graphics_Driver::prepare(bm, XP, YP, WP, HP, cx, cy, X, Y, W, H)) { 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); } -} - - -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); + 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()); } - 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; - } - 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)); +fl_uintptr_t Fl_Android_Graphics_Driver::cache(Fl_Bitmap *bm) +{ + int w = bm->w(), h = bm->h(); + int rowBytes = (w+7)>>3; + + Fl_Android_Bytemap *cache = new Fl_Android_Bytemap(w, h); + for (int yy=0; yyarray + yy*rowBytes; + uchar *dst = cache->pBytes + yy*cache->pStride; + uchar d; + for (int xx=0; xx>= 1; + } + } + + 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,11 +68,19 @@ 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. */