summaryrefslogtreecommitdiff
path: root/src/drivers/GDI
diff options
context:
space:
mode:
authormaxim nikonov <maxim.nikonov@hqo.co>2026-02-05 15:21:34 +0500
committermaxim nikonov <maxim.nikonov@hqo.co>2026-02-05 15:21:34 +0500
commitdb214d1145e46d527a46d1fc2519548d2c4d23f1 (patch)
treecf0fd9922e4d54f6beb63888f9b28c8e2a787bdf /src/drivers/GDI
parent75fc94d6c71fe686f6dde5b41ad91cba2f6bdd6f (diff)
wip: fork
Diffstat (limited to 'src/drivers/GDI')
-rw-r--r--src/drivers/GDI/Fl_Font.H43
-rw-r--r--src/drivers/GDI/Fl_GDI_Copy_Surface_Driver.H35
-rw-r--r--src/drivers/GDI/Fl_GDI_Copy_Surface_Driver.cxx95
-rw-r--r--src/drivers/GDI/Fl_GDI_Graphics_Driver.H230
-rw-r--r--src/drivers/GDI/Fl_GDI_Graphics_Driver.cxx322
-rw-r--r--src/drivers/GDI/Fl_GDI_Graphics_Driver_arci.cxx89
-rw-r--r--src/drivers/GDI/Fl_GDI_Graphics_Driver_color.cxx259
-rw-r--r--src/drivers/GDI/Fl_GDI_Graphics_Driver_font.cxx678
-rw-r--r--src/drivers/GDI/Fl_GDI_Graphics_Driver_image.cxx826
-rw-r--r--src/drivers/GDI/Fl_GDI_Graphics_Driver_line_style.cxx111
-rw-r--r--src/drivers/GDI/Fl_GDI_Graphics_Driver_rect.cxx320
-rw-r--r--src/drivers/GDI/Fl_GDI_Graphics_Driver_vertex.cxx231
-rw-r--r--src/drivers/GDI/Fl_GDI_Image_Surface_Driver.H44
-rw-r--r--src/drivers/GDI/Fl_GDI_Image_Surface_Driver.cxx169
14 files changed, 0 insertions, 3452 deletions
diff --git a/src/drivers/GDI/Fl_Font.H b/src/drivers/GDI/Fl_Font.H
deleted file mode 100644
index 3e8b1296f..000000000
--- a/src/drivers/GDI/Fl_Font.H
+++ /dev/null
@@ -1,43 +0,0 @@
-//
-// Font definitions 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:
-//
-// https://www.fltk.org/COPYING.php
-//
-// Please see the following page on how to report bugs and issues:
-//
-// https://www.fltk.org/bugs.php
-//
-
-// Two internal fltk data structures:
-//
-// Fl_Fontdesc: an entry into the fl_font() table. There is one of these
-// for each fltk font number.
-//
-#ifndef FL_FONT_
-#define FL_FONT_
-
-#include <config.h>
-#include "../../Fl_Scalable_Graphics_Driver.H"
-
-class Fl_GDI_Font_Descriptor : public Fl_Font_Descriptor {
-public:
- HFONT fid;
- int *width[64];
- TEXTMETRIC metr;
- int angle;
- FL_EXPORT Fl_GDI_Font_Descriptor(const char* fontname, Fl_Fontsize size);
-# if HAVE_GL
- char glok[64];
-# endif // HAVE_GL
- virtual FL_EXPORT ~Fl_GDI_Font_Descriptor();
-};
-
-extern FL_EXPORT Fl_Fontdesc *fl_fonts; // the table
-
-#endif
diff --git a/src/drivers/GDI/Fl_GDI_Copy_Surface_Driver.H b/src/drivers/GDI/Fl_GDI_Copy_Surface_Driver.H
deleted file mode 100644
index 7eae4c2bc..000000000
--- a/src/drivers/GDI/Fl_GDI_Copy_Surface_Driver.H
+++ /dev/null
@@ -1,35 +0,0 @@
-//
-// Copy-to-clipboard code for the Fast Light Tool Kit (FLTK).
-//
-// Copyright 2022 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:
-//
-// https://www.fltk.org/COPYING.php
-//
-// Please see the following page on how to report bugs and issues:
-//
-// https://www.fltk.org/bugs.php
-//
-
-#ifndef FL_GDI_COPY_SURFACE_DRIVER_H
-#define FL_GDI_COPY_SURFACE_DRIVER_H
-
-#include <FL/Fl_Copy_Surface.H>
-#include <FL/platform.H>
-
-class Fl_GDI_Copy_Surface_Driver : public Fl_Copy_Surface_Driver {
- friend class Fl_Copy_Surface_Driver;
-protected:
- HDC oldgc;
- HDC gc;
- Fl_GDI_Copy_Surface_Driver(int w, int h);
- ~Fl_GDI_Copy_Surface_Driver();
- void set_current() FL_OVERRIDE;
- void translate(int x, int y) FL_OVERRIDE;
- void untranslate() FL_OVERRIDE;
-};
-
-#endif // FL_GDI_COPY_SURFACE_DRIVER_H
diff --git a/src/drivers/GDI/Fl_GDI_Copy_Surface_Driver.cxx b/src/drivers/GDI/Fl_GDI_Copy_Surface_Driver.cxx
deleted file mode 100644
index c44c0a77b..000000000
--- a/src/drivers/GDI/Fl_GDI_Copy_Surface_Driver.cxx
+++ /dev/null
@@ -1,95 +0,0 @@
-//
-// Copy-to-clipboard code 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:
-//
-// https://www.fltk.org/COPYING.php
-//
-// Please see the following page on how to report bugs and issues:
-//
-// https://www.fltk.org/bugs.php
-//
-
-#include <config.h>
-#include "Fl_GDI_Copy_Surface_Driver.H"
-#include <FL/platform.H>
-#include "Fl_GDI_Graphics_Driver.H"
-#include "../WinAPI/Fl_WinAPI_Screen_Driver.H"
-#include <FL/Fl_Image_Surface.H>
-#include <windows.h>
-
-
-Fl_GDI_Copy_Surface_Driver::Fl_GDI_Copy_Surface_Driver(int w, int h) : Fl_Copy_Surface_Driver(w, h) {
- driver(Fl_Graphics_Driver::newMainGraphicsDriver());
- oldgc = (HDC)Fl_Surface_Device::surface()->driver()->gc();
- // exact computation of factor from screen units to EnhMetaFile units (0.01 mm)
- HDC hdc = GetDC(NULL);
- int hmm = GetDeviceCaps(hdc, HORZSIZE);
- int hdots = GetDeviceCaps(hdc, HORZRES);
- int vmm = GetDeviceCaps(hdc, VERTSIZE);
- int vdots = GetDeviceCaps(hdc, VERTRES);
- ReleaseDC(NULL, hdc);
- float factorw = (100.f * hmm) / hdots;
- float factorh = (100.f * vmm) / vdots;
- // Global display scaling factor: 1, 1.25, 1.5, 1.75, etc...
- float scaling = Fl_Graphics_Driver::default_driver().scale();
- driver()->scale(scaling);
- RECT rect; rect.left = 0; rect.top = 0; rect.right = (LONG)((w*scaling) * factorw); rect.bottom = (LONG)((h*scaling) * factorh);
- gc = CreateEnhMetaFile (NULL, NULL, &rect, NULL);
- if (gc != NULL) {
- SetTextAlign(gc, TA_BASELINE|TA_LEFT);
- SetBkMode(gc, TRANSPARENT);
- }
-}
-
-
-Fl_GDI_Copy_Surface_Driver::~Fl_GDI_Copy_Surface_Driver() {
- if (oldgc == (HDC)Fl_Surface_Device::surface()->driver()->gc()) oldgc = NULL;
- HENHMETAFILE hmf = CloseEnhMetaFile (gc);
- if ( hmf != NULL ) {
- if ( OpenClipboard (NULL) ){
- EmptyClipboard ();
- // put first the vectorial form of the graphics in the clipboard
- SetClipboardData (CF_ENHMETAFILE, hmf);
- // then put a BITMAP version of the graphics in the clipboard
- float scaling = driver()->scale();
- int W = Fl_Scalable_Graphics_Driver::floor(width, scaling), H = Fl_Scalable_Graphics_Driver::floor(height, scaling);
- RECT rect = {0, 0, W, H};
- Fl_Image_Surface *surf = new Fl_Image_Surface(W, H);
- Fl_Surface_Device::push_current(surf);
- fl_color(FL_WHITE); // draw white background
- fl_rectf(0, 0, W, H);
- PlayEnhMetaFile((HDC)surf->driver()->gc(), hmf, &rect); // draw metafile to offscreen buffer
- SetClipboardData(CF_BITMAP, (HBITMAP)surf->offscreen());
- Fl_Surface_Device::pop_current();
- delete surf;
-
- CloseClipboard ();
- }
- DeleteEnhMetaFile(hmf);
- }
- DeleteDC(gc);
- Fl_Surface_Device::surface()->driver()->gc(oldgc);
- delete driver();
-}
-
-
-void Fl_GDI_Copy_Surface_Driver::set_current() {
- driver()->gc(gc);
- fl_window = (HWND)1;
- Fl_Surface_Device::set_current();
-}
-
-
-void Fl_GDI_Copy_Surface_Driver::translate(int x, int y) {
- ((Fl_GDI_Graphics_Driver*)driver())->translate_all(x, y);
-}
-
-
-void Fl_GDI_Copy_Surface_Driver::untranslate() {
- ((Fl_GDI_Graphics_Driver*)driver())->untranslate_all();
-}
diff --git a/src/drivers/GDI/Fl_GDI_Graphics_Driver.H b/src/drivers/GDI/Fl_GDI_Graphics_Driver.H
deleted file mode 100644
index 336fa1ebc..000000000
--- a/src/drivers/GDI/Fl_GDI_Graphics_Driver.H
+++ /dev/null
@@ -1,230 +0,0 @@
-//
-// Definition of classes Fl_Graphics_Driver, Fl_Surface_Device, Fl_Display_Device
-// for the Fast Light Tool Kit (FLTK).
-//
-// Copyright 2010-2023 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:
-//
-// https://www.fltk.org/COPYING.php
-//
-// Please see the following page on how to report bugs and issues:
-//
-// https://www.fltk.org/bugs.php
-//
-
-/**
- \file Fl_GDI_Graphics_Driver.H
- \brief Definition of Windows GDI graphics driver.
- */
-
-#ifndef FL_GDI_GRAPHICS_DRIVER_H
-#define FL_GDI_GRAPHICS_DRIVER_H
-
-#include "../../Fl_Scalable_Graphics_Driver.H"
-#include <windows.h>
-#include <stdlib.h>
-#include <config.h>
-
-#if USE_GDIPLUS
-# if defined(_MSC_VER)
-# include <objidl.h>
-# else
-# include <wtypes.h> // for PROPID needed with gcc 4.9.0 but not with 4.9.3
-# endif
-# include <gdiplus.h>
-#endif
-
-/**
- \brief The Windows-specific graphics driver class.
-
- This class is implemented only on the Windows platform.
-*/
-class Fl_GDI_Graphics_Driver : public Fl_Scalable_Graphics_Driver {
-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_() FL_OVERRIDE;
- void draw_fixed(Fl_Pixmap *pxm, int XP, int YP, int WP, int HP, int cx, int cy) FL_OVERRIDE;
- void draw_fixed(Fl_Bitmap *pxm, int XP, int YP, int WP, int HP, int cx, int cy) FL_OVERRIDE;
- void make_unused_color_(unsigned char &r, unsigned char &g, unsigned char &b, int color_count, void **data) FL_OVERRIDE;
-protected:
- void draw_fixed(Fl_RGB_Image *rgb, int XP, int YP, int WP, int HP, int cx, int cy) FL_OVERRIDE;
- void cache(Fl_RGB_Image *rgb) FL_OVERRIDE;
- HDC gc_;
- int numcount;
- int counts[20];
- uchar *mask_bitmap_;
- uchar **mask_bitmap() FL_OVERRIDE {return &mask_bitmap_;}
- POINT *long_point;
- int style_;
-public:
- Fl_GDI_Graphics_Driver();
- ~Fl_GDI_Graphics_Driver() FL_OVERRIDE;
- int has_feature(driver_feature mask) FL_OVERRIDE { return mask & NATIVE; }
- char can_do_alpha_blending() FL_OVERRIDE;
- void gc(void *ctxt) FL_OVERRIDE { gc_ = (HDC)ctxt; global_gc(); }
- void *gc() FL_OVERRIDE {return gc_;}
-
- // --- bitmap stuff
- static HBITMAP create_bitmask(int w, int h, const uchar *array); // NOT virtual
- static HBITMAP calc_HBITMAP_mask(Fl_RGB_Image *mask);
- void delete_bitmask(fl_uintptr_t bm) FL_OVERRIDE;
- HBITMAP create_alphamask(int w, int h, int d, int ld, const uchar *array);
- void draw_unscaled(const char* str, int n, int x, int y) FL_OVERRIDE;
- void draw_unscaled(int angle, const char *str, int n, int x, int y) FL_OVERRIDE;
- void rtl_draw_unscaled(const char* str, int n, int x, int y) FL_OVERRIDE;
- void font_unscaled(Fl_Font face, Fl_Fontsize size) FL_OVERRIDE;
- void draw_rgb(Fl_RGB_Image *img, int XP, int YP, int WP, int HP, int cx, int cy) FL_OVERRIDE;
- void draw_image_unscaled(const uchar* buf, int X,int Y,int W,int H, int D=3, int L=0) FL_OVERRIDE;
- void draw_image_unscaled(Fl_Draw_Image_Cb cb, void* data, int X,int Y,int W,int H, int D=3) FL_OVERRIDE;
- void draw_image_mono_unscaled(const uchar* buf, int X,int Y,int W,int H, int D=1, int L=0) FL_OVERRIDE;
- void draw_image_mono_unscaled(Fl_Draw_Image_Cb cb, void* data, int X,int Y,int W,int H, int D=1) FL_OVERRIDE;
- void cache(Fl_Pixmap *img) FL_OVERRIDE;
- void uncache_pixmap(fl_uintptr_t p) FL_OVERRIDE;
- void cache(Fl_Bitmap *img) FL_OVERRIDE;
- void uncache(Fl_RGB_Image *img, fl_uintptr_t &id_, fl_uintptr_t &mask_) FL_OVERRIDE;
- double width_unscaled(const char *str, int n) FL_OVERRIDE;
- double width_unscaled(unsigned int c) FL_OVERRIDE;
- void text_extents_unscaled(const char*, int n, int& dx, int& dy, int& w, int& h) FL_OVERRIDE;
- int height_unscaled() FL_OVERRIDE;
- int descent_unscaled() FL_OVERRIDE;
- Fl_Fontsize size_unscaled() FL_OVERRIDE;
-#if ! defined(FL_DOXYGEN)
- void copy_offscreen_with_alpha(int x,int y,int w,int h,HBITMAP bitmap,int srcx,int srcy);
-#endif
- void copy_offscreen(int x, int y, int w, int h, Fl_Offscreen pixmap, int srcx, int srcy) FL_OVERRIDE;
- void add_rectangle_to_region(Fl_Region r, int x, int y, int w, int h) FL_OVERRIDE;
- Fl_Region XRectangleRegion(int x, int y, int w, int h) FL_OVERRIDE;
- void XDestroyRegion(Fl_Region r) FL_OVERRIDE;
- void translate_all(int x, int y);
- void untranslate_all(void);
- static HRGN scale_region(HRGN r, float f, Fl_GDI_Graphics_Driver *dr);
- void scale(float f) FL_OVERRIDE;
- float scale() {return Fl_Graphics_Driver::scale();}
-protected:
- void transformed_vertex0(float x, float y) FL_OVERRIDE;
- void fixloop() FL_OVERRIDE;
- void point(int x, int y) FL_OVERRIDE;
- void focus_rect(int x, int y, int w, int h) FL_OVERRIDE;
- void rect_unscaled(int x, int y, int w, int h) FL_OVERRIDE;
- void rectf_unscaled(int x, int y, int w, int h) FL_OVERRIDE;
-#if USE_COLORMAP
- void colored_rectf(int x, int y, int w, int h, uchar r, uchar g, uchar b) FL_OVERRIDE;
-#endif
- void line_unscaled(int x, int y, int x1, int y1) FL_OVERRIDE;
- void line_unscaled(int x, int y, int x1, int y1, int x2, int y2) FL_OVERRIDE;
- void xyline_unscaled(int x, int y, int x1) FL_OVERRIDE;
- void yxline_unscaled(int x, int y, int y1) FL_OVERRIDE;
- void loop_unscaled(int x0, int y0, int x1, int y1, int x2, int y2) FL_OVERRIDE;
- void loop_unscaled(int x0, int y0, int x1, int y1, int x2, int y2, int x3, int y3) FL_OVERRIDE;
- void polygon_unscaled(int x0, int y0, int x1, int y1, int x2, int y2) FL_OVERRIDE;
- void polygon_unscaled(int x0, int y0, int x1, int y1, int x2, int y2, int x3, int y3) FL_OVERRIDE;
- // --- clipping
- void push_clip(int x, int y, int w, int h) FL_OVERRIDE;
- int clip_box(int x, int y, int w, int h, int &X, int &Y, int &W, int &H) FL_OVERRIDE;
- int not_clipped(int x, int y, int w, int h) FL_OVERRIDE;
- void restore_clip() FL_OVERRIDE;
- Fl_Region scale_clip(float f) FL_OVERRIDE;
- // --- implementation is in src/fl_vertex.cxx which includes src/cfg_gfx/xxx_rect.cxx
- void begin_complex_polygon() FL_OVERRIDE;
- void end_points() FL_OVERRIDE;
- void end_line() FL_OVERRIDE;
- void end_loop() FL_OVERRIDE;
- void end_polygon() FL_OVERRIDE;
- void end_complex_polygon() FL_OVERRIDE;
- void gap() FL_OVERRIDE;
- void ellipse_unscaled(double xt, double yt, double rx, double ry) FL_OVERRIDE;
- void arc_unscaled(int x, int y, int w, int h, double a1, double a2) FL_OVERRIDE;
- void pie_unscaled(int x, int y, int w, int h, double a1, double a2) FL_OVERRIDE;
- void line_style_unscaled(int style, int width, char* dashes) FL_OVERRIDE;
- void color(Fl_Color c) FL_OVERRIDE;
- Fl_Color color() FL_OVERRIDE { return color_; }
- void color(uchar r, uchar g, uchar b) FL_OVERRIDE;
- void set_color(Fl_Color i, unsigned int c) FL_OVERRIDE;
- void free_color(Fl_Color i, int overlay) FL_OVERRIDE;
- Fl_Font set_fonts(const char *name) FL_OVERRIDE;
- int get_font_sizes(Fl_Font fnum, int*& sizep) FL_OVERRIDE;
- const char* get_font_name(Fl_Font fnum, int* ap) FL_OVERRIDE;
- const char *font_name(int num) FL_OVERRIDE;
- void font_name(int num, const char *name) FL_OVERRIDE;
- void global_gc() FL_OVERRIDE;
- void overlay_rect(int x, int y, int w , int h) FL_OVERRIDE;
- void cache_size(Fl_Image *img, int &width, int &height) FL_OVERRIDE;
- void* change_pen_width(int width) FL_OVERRIDE;
- void reset_pen_width(void *data) FL_OVERRIDE;
-};
-
-
-/**
- The graphics driver used when printing on Windows.
-
- This class is implemented only on the Windows platform.
- It is extremely similar to Fl_GDI_Graphics_Driver.
-*/
-class Fl_GDI_Printer_Graphics_Driver : public Fl_GDI_Graphics_Driver {
-private:
- typedef BOOL (WINAPI* transparent_f_type) (HDC,int,int,int,int,HDC,int,int,int,int,UINT);
- transparent_f_type TransparentBlt();
-public:
- int has_feature(driver_feature mask) FL_OVERRIDE { return mask & (NATIVE | PRINTER); }
- void draw_pixmap(Fl_Pixmap *pxm, int XP, int YP, int WP, int HP, int cx, int cy) FL_OVERRIDE;
- void draw_bitmap(Fl_Bitmap *bm, int XP, int YP, int WP, int HP, int cx, int cy) FL_OVERRIDE;
- void draw_rgb(Fl_RGB_Image *rgb, int XP, int YP, int WP, int HP, int cx, int cy) FL_OVERRIDE;
- void copy_offscreen(int x, int y, int w, int h, Fl_Offscreen bitmap, int srcx, int srcy) FL_OVERRIDE;
-};
-
-#if USE_GDIPLUS
-
-class Fl_GDIplus_Graphics_Driver : public Fl_GDI_Graphics_Driver {
- friend class Fl_Graphics_Driver;
-private:
- Gdiplus::Color gdiplus_color_;
- Gdiplus::Pen *pen_;
- Gdiplus::SolidBrush *brush_;
- // The code below ensures that a connection to GDIplus is only made once, and that the
- // matching connection shutdown is also done exactly once.
- enum {
- STATE_CLOSED = 0, // no connection, token is invalid
- STATE_STARTUP, // attempt to start up, avoid recursions for whatever reason
- STATE_OPEN, // connection was successful and the token is valid
- STATE_SHUTDOWN // shutting down the gdi connection, avoid possible recursion
- };
- static int gdiplus_state_; // reflect the state of the GDIplus driver connection
- static ULONG_PTR gdiplus_token_; // the token that GDIplus gives to us
-public:
- Fl_GDIplus_Graphics_Driver();
- virtual ~Fl_GDIplus_Graphics_Driver();
- bool active;
- static void shutdown(void);
- void color(Fl_Color c) FL_OVERRIDE;
- Fl_Color color() FL_OVERRIDE { return color_; }
- void color(uchar r, uchar g, uchar b) FL_OVERRIDE;
- void line(int x, int y, int x1, int y1) FL_OVERRIDE;
- void line(int x, int y, int x1, int y1, int x2, int y2) FL_OVERRIDE;
- void loop(int x0, int y0, int x1, int y1, int x2, int y2) FL_OVERRIDE;
- void loop(int x0, int y0, int x1, int y1, int x2, int y2, int x3, int y3) FL_OVERRIDE;
- void polygon(int x0, int y0, int x1, int y1, int x2, int y2) FL_OVERRIDE;
- void polygon(int x0, int y0, int x1, int y1, int x2, int y2, int x3, int y3) FL_OVERRIDE;
- void line_style(int style, int width, char* dashes) FL_OVERRIDE;
- void arc_unscaled(int x, int y, int w, int h, double a1, double a2) FL_OVERRIDE;
- void pie_unscaled(int x, int y, int w, int h, double a1, double a2) FL_OVERRIDE;
- void draw_circle(int x, int y, int d, Fl_Color c) FL_OVERRIDE;
- void transformed_vertex(double xf, double yf) FL_OVERRIDE;
- void vertex(double x,double y) FL_OVERRIDE;
- void end_points() FL_OVERRIDE;
- void end_line() FL_OVERRIDE;
- void end_loop() FL_OVERRIDE;
- void end_polygon() FL_OVERRIDE;
- void end_complex_polygon() FL_OVERRIDE;
- void circle(double x, double y, double r) FL_OVERRIDE;
- void antialias(int state) FL_OVERRIDE;
- int antialias() FL_OVERRIDE;
-};
-
-#endif // USE_GDIPLUS
-
-#endif // FL_GDI_GRAPHICS_DRIVER_H
diff --git a/src/drivers/GDI/Fl_GDI_Graphics_Driver.cxx b/src/drivers/GDI/Fl_GDI_Graphics_Driver.cxx
deleted file mode 100644
index 97b3244d1..000000000
--- a/src/drivers/GDI/Fl_GDI_Graphics_Driver.cxx
+++ /dev/null
@@ -1,322 +0,0 @@
-//
-// Rectangle drawing routines for the Fast Light Tool Kit (FLTK).
-//
-// Copyright 1998-2022 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:
-//
-// https://www.fltk.org/COPYING.php
-//
-// Please see the following page on how to report bugs and issues:
-//
-// https://www.fltk.org/bugs.php
-//
-
-
-#include <config.h>
-#include "Fl_GDI_Graphics_Driver.H"
-#include <FL/Fl.H>
-#include <FL/platform.H>
-#include <FL/fl_draw.H>
-#include "../../Fl_Screen_Driver.H"
-#include "Fl_Font.H"
-
-#if USE_GDIPLUS
-
-Fl_GDIplus_Graphics_Driver::Fl_GDIplus_Graphics_Driver() : Fl_GDI_Graphics_Driver() {
- if (!fl_current_xmap) color(FL_BLACK);
- pen_ = new Gdiplus::Pen(gdiplus_color_, 1);
- pen_->SetLineJoin(Gdiplus::LineJoinRound);
- pen_->SetStartCap(Gdiplus::LineCapFlat);
- pen_->SetEndCap(Gdiplus::LineCapFlat);
- brush_ = new Gdiplus::SolidBrush(gdiplus_color_);
- active = true;
-}
-
-Fl_GDIplus_Graphics_Driver::~Fl_GDIplus_Graphics_Driver() {
- delete pen_;
- delete brush_;
-}
-
-void Fl_GDIplus_Graphics_Driver::antialias(int state) {
- active = state;
-}
-
-int Fl_GDIplus_Graphics_Driver::antialias() {
- return active;
-}
-
-void Fl_GDIplus_Graphics_Driver::draw_circle(int x, int y, int d, Fl_Color c) {
- Fl_Graphics_Driver::draw_circle(x, y, d, c);
-}
-
-int Fl_GDIplus_Graphics_Driver::gdiplus_state_ = Fl_GDIplus_Graphics_Driver::STATE_CLOSED;
-ULONG_PTR Fl_GDIplus_Graphics_Driver::gdiplus_token_ = 0;
-
-void Fl_GDIplus_Graphics_Driver::shutdown() {
- if (gdiplus_state_ == STATE_OPEN) {
- gdiplus_state_ = STATE_SHUTDOWN;
- Gdiplus::GdiplusShutdown(Fl_GDIplus_Graphics_Driver::gdiplus_token_);
- gdiplus_token_ = 0;
- gdiplus_state_ = STATE_CLOSED;
- } else if (gdiplus_state_ == STATE_CLOSED) {
-// Fl::warning("Fl_GDIplus_Graphics_Driver::shutdown() called, but driver is closed.");
- } else if (gdiplus_state_ == STATE_SHUTDOWN) {
-// Fl::warning("Fl_GDIplus_Graphics_Driver::shutdown() called recursively.");
- } else if (gdiplus_state_ == STATE_STARTUP) {
-// Fl::warning("Fl_GDIplus_Graphics_Driver::shutdown() called while driver is starting up.");
- }
-}
-#endif
-
-// 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;
-
-
-HDC fl_win32_gc() { return fl_gc; }
-
-
-Fl_GDI_Graphics_Driver::Fl_GDI_Graphics_Driver() {
- mask_bitmap_ = NULL;
- gc_ = NULL;
- long_point = NULL;
- depth = -1;
- origins = NULL;
- style_ = FL_SOLID;
-}
-
-Fl_GDI_Graphics_Driver::~Fl_GDI_Graphics_Driver() {
- if (long_point) free(long_point);
- delete[] origins;
-}
-
-void Fl_GDI_Graphics_Driver::global_gc()
-{
- 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) {
- x = int(x * scale()); y = int(y * scale()); w = int(w * scale()); h = int(h * scale());
- srcx = int(srcx * scale()); srcy = int(srcy * scale());
- if (srcx < 0) {w += srcx; x -= srcx; srcx = 0;}
- if (srcy < 0) {h += srcy; y -= srcy; srcy = 0;}
- int off_width, off_height;
- Fl::screen_driver()->offscreen_size(bitmap, off_width, off_height);
- if (srcx + w >= off_width) {w = off_width - srcx;}
- if (srcy + h >= off_height) {h = off_height - srcy;}
- if (w <= 0 || h <= 0) return;
- HDC new_gc = CreateCompatibleDC(gc_);
- int save = SaveDC(new_gc);
- SelectObject(new_gc, (HBITMAP)bitmap);
- BitBlt(gc_, x, y, w, h, new_gc, srcx, srcy, SRCCOPY);
- RestoreDC(new_gc, save);
- DeleteDC(new_gc);
-}
-
-void Fl_GDI_Printer_Graphics_Driver::copy_offscreen(int x, int y, int w, int h, Fl_Offscreen bitmap, int srcx, int srcy) {
- Fl_Graphics_Driver::copy_offscreen(x, y, w, h, bitmap, srcx, srcy);
-}
-
-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 ( fl_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(), int(origins[depth].x - x*scale()), int(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) {
- HRGN R = (HRGN)XRectangleRegion(X, Y, W, H);
- CombineRgn((HRGN)r, (HRGN)r, R, RGN_OR);
- XDestroyRegion(R);
-}
-
-void Fl_GDI_Graphics_Driver::transformed_vertex0(float x, float y) {
- if (!n || x != long_point[n-1].x || y != long_point[n-1].y) {
- if (n >= p_size) {
- p_size = long_point ? 2*p_size : 16;
- long_point = (POINT*)realloc((void*)long_point, p_size*sizeof(*long_point));
- }
- long_point[n].x = LONG(x);
- long_point[n].y = LONG(y);
- n++;
- }
-}
-
-void Fl_GDI_Graphics_Driver::fixloop() { // remove equal points from closed path
- while (n>2 && long_point[n-1].x == long_point[0].x && long_point[n-1].y == long_point[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((HRGN)r);
-}
-
-
-void Fl_GDI_Graphics_Driver::scale(float f) {
- if (f != scale()) {
- size_ = 0;
- Fl_Graphics_Driver::scale(f);
- color(FL_BLACK);
- line_style(FL_SOLID); // scale also default line width
- }
-}
-
-
-/* Rescale region r with factor f and returns the scaled region.
- Region r is returned unchanged if r is null or f is 1.
- */
-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);
- POINT pt = {0, 0};
- if (dr && dr->depth >= 1) { // account for translation
- GetWindowOrgEx((HDC)dr->gc(), &pt);
- pt.x = int(pt.x * (f - 1));
- pt.y = int(pt.y * (f - 1));
- }
- RECT *rects = (RECT*)&(pdata->Buffer);
- for (DWORD i = 0; i < pdata->rdh.nCount; i++) {
- int x = Fl_Scalable_Graphics_Driver::floor(rects[i].left, f) + pt.x;
- int y = Fl_Scalable_Graphics_Driver::floor(rects[i].top, f) + pt.y;
- RECT R2;
- R2.left = x;
- R2.top = y;
- R2.right = Fl_Scalable_Graphics_Driver::floor(rects[i].right, f) + pt.x - x + R2.left;
- R2.bottom = Fl_Scalable_Graphics_Driver::floor(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 = (HRGN)rstack[rstackptr];
- HRGN r2 = scale_region(r, f, this);
- return (r == r2 ? NULL : (rstack[rstackptr] = r2, r));
-}
-
-void Fl_GDI_Graphics_Driver::set_current_() {
- restore_clip();
-}
-
-void Fl_GDI_Graphics_Driver::cache_size(Fl_Image *img, int &width, int &height)
-{
- float s = scale();
- width = (s == int(s) ? width * int(s) : floor(width+1));
- height = (s == int(s) ? height * int(s) : floor(height+1));
- cache_size_finalize(img, width, height);
-}
diff --git a/src/drivers/GDI/Fl_GDI_Graphics_Driver_arci.cxx b/src/drivers/GDI/Fl_GDI_Graphics_Driver_arci.cxx
deleted file mode 100644
index 0c1e90064..000000000
--- a/src/drivers/GDI/Fl_GDI_Graphics_Driver_arci.cxx
+++ /dev/null
@@ -1,89 +0,0 @@
-//
-// Arc (integer) drawing functions 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:
-//
-// https://www.fltk.org/COPYING.php
-//
-// Please see the following page on how to report bugs and issues:
-//
-// https://www.fltk.org/bugs.php
-//
-
-/**
- \file Fl_GDI_Graphics_Driver_arci.cxx
- \brief Utility functions for drawing circles using integers
-*/
-
-// "integer" circle drawing functions. These draw the limited
-// circle types provided by X and NT graphics. The advantage of
-// these is that small ones draw quite nicely (probably due to stored
-// hand-drawn bitmaps of small circles!) and may be implemented by
-// hardware and thus are fast.
-
-#include "Fl_GDI_Graphics_Driver.H"
-
-#include <FL/math.h>
-#include <FL/platform.H>
-
-void Fl_GDI_Graphics_Driver::arc_unscaled(int x, int y, int w, int h, double a1, double a2) {
- if (w <= 0 || h <= 0) return;
- w++; h++;
- int xa = int( x+w/2+int(w*cos(a1/180.0*M_PI)) );
- int ya = int( y+h/2-int(h*sin(a1/180.0*M_PI)) );
- int xb = int( x+w/2+int(w*cos(a2/180.0*M_PI)) );
- int yb = int( y+h/2-int(h*sin(a2/180.0*M_PI)) );
- if (fabs(a1 - a2) < 90) {
- if (xa == xb && ya == yb) SetPixel(gc_, xa, ya, fl_RGB());
- else Arc(gc_, int(x), int(y), int(x+w), int(y+h), xa, ya, xb, yb);
- } else Arc(gc_, int(x), int(y), int(x+w), int(y+h), xa, ya, xb, yb);
-}
-
-void Fl_GDI_Graphics_Driver::pie_unscaled(int x, int y, int w, int h, double a1, double a2) {
- if (w <= 0 || h <= 0) return;
- if (a1 == a2) return;
- x++; y++; w--; h--;
- if (scale() >= 3) {x++; y++; w-=2; h-=2;}
- int xa = int( x+w/2+int(w*cos(a1/180.0*M_PI)) );
- int ya = int( y+h/2-int(h*sin(a1/180.0*M_PI)) );
- int xb = int( x+w/2+int(w*cos(a2/180.0*M_PI)) );
- int yb = int( y+h/2-int(h*sin(a2/180.0*M_PI)) );
- SelectObject(gc_, fl_brush());
- if (fabs(a1 - a2) < 90) {
- if (xa == xb && ya == yb) {
- MoveToEx(gc_, int(x+w/2), int(y+h/2), 0L);
- LineTo(gc_, xa, ya);
- SetPixel(gc_, xa, ya, fl_RGB());
- } else Pie(gc_, int(x), int(y), int(x+w), int(y+h), xa, ya, xb, yb);
- } else Pie(gc_, int(x), int(y), int(x+w), int(y+h), xa, ya, xb, yb);
-}
-
-#if USE_GDIPLUS
-
-void Fl_GDIplus_Graphics_Driver::arc_unscaled(int x, int y, int w, int h, double a1, double a2) {
- if (w <= 0 || h <= 0) return;
- if (!active) return Fl_GDI_Graphics_Driver::arc_unscaled(x, y, w, h, a1, a2);
- Gdiplus::Graphics graphics_(gc_);
- pen_->SetColor(gdiplus_color_);
- Gdiplus::REAL oldw = pen_->GetWidth();
- Gdiplus::REAL new_w = (line_width_ <= scale() ? 1 : line_width_) * scale();
- pen_->SetWidth(new_w);
- graphics_.SetSmoothingMode(Gdiplus::SmoothingModeAntiAlias);
- graphics_.DrawArc(pen_, x, y, w, h, Gdiplus::REAL(-a1), Gdiplus::REAL(a1-a2));
- pen_->SetWidth(oldw);
-}
-
-void Fl_GDIplus_Graphics_Driver::pie_unscaled(int x, int y, int w, int h, double a1, double a2) {
- if (w <= 0 || h <= 0) return;
- if (!active) return Fl_GDI_Graphics_Driver::pie_unscaled(x, y, w, h, a1, a2);
- Gdiplus::Graphics graphics_(gc_);
- brush_->SetColor(gdiplus_color_);
- graphics_.SetSmoothingMode(Gdiplus::SmoothingModeAntiAlias);
- graphics_.FillPie(brush_, x, y, w, h, Gdiplus::REAL(-a1), Gdiplus::REAL(a1-a2));
-}
-
-#endif
diff --git a/src/drivers/GDI/Fl_GDI_Graphics_Driver_color.cxx b/src/drivers/GDI/Fl_GDI_Graphics_Driver_color.cxx
deleted file mode 100644
index c05a255d0..000000000
--- a/src/drivers/GDI/Fl_GDI_Graphics_Driver_color.cxx
+++ /dev/null
@@ -1,259 +0,0 @@
-//
-// MSWidnows' GDI color functions 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:
-//
-// https://www.fltk.org/COPYING.php
-//
-// Please see the following page on how to report bugs and issues:
-//
-// https://www.fltk.org/bugs.php
-//
-
-// The fltk "colormap". This allows ui colors to be stored in 8-bit
-// locations, and provides a level of indirection so that global color
-// changes can be made. Not to be confused with the X colormap, which
-// I try to hide completely.
-
-#include "Fl_GDI_Graphics_Driver.H"
-
-#include <config.h>
-#include <FL/Fl.H>
-#include <FL/platform.H>
-#include <FL/fl_draw.H>
-
-// FIXME: all the global functions in this file should probably be protected
-// members of the driver class. Starting with 1.4 we will allow multiple drivers
-// to co-exist, creating conflicts with multipe mapping.
-
-// FIXME: maybe we can forget about color mapping and assume RGB?
-// FIXME: ... but for now we still have it ...
-extern unsigned fl_cmap[256]; // defined in fl_color.cxx
-
-// Translations to win32 data structures:
-Fl_XMap fl_xmap[256];
-
-Fl_XMap* fl_current_xmap;
-
-HPALETTE fl_palette;
-static HGDIOBJ tmppen=0;
-static HPEN savepen=0;
-
-void fl_cleanup_pens(void) {
- for (int i=0; i<256; i++) {
- if (fl_xmap[i].pen) DeleteObject(fl_xmap[i].pen);
- }
-}
-
-void fl_save_pen(void) {
- if(!tmppen) tmppen = CreatePen(PS_SOLID, 1, 0);
- savepen = (HPEN)SelectObject((HDC)fl_graphics_driver->gc(), tmppen);
-}
-
-void fl_restore_pen(void) {
- if (savepen) SelectObject((HDC)fl_graphics_driver->gc(), savepen);
- DeleteObject(tmppen);
- tmppen = 0;
- savepen = 0;
-}
-
-static void clear_xmap(Fl_XMap& xmap) {
- if (xmap.pen) {
- HDC gc = (HDC)fl_graphics_driver->gc();
- HGDIOBJ tmppen = GetStockObject(BLACK_PEN);
- HGDIOBJ oldpen = SelectObject(gc, tmppen); // Push out the current pen of the gc
- if(oldpen != xmap.pen) SelectObject(gc, oldpen); // Put it back if it is not the one we are about to delete
- DeleteObject((HGDIOBJ)(xmap.pen));
- xmap.pen = 0;
- xmap.brush = -1;
- }
-}
-
-static void set_xmap(Fl_XMap& xmap, COLORREF c, int lw) {
- xmap.rgb = c;
- if (xmap.pen) {
- HDC gc = (HDC)fl_graphics_driver->gc();
- HGDIOBJ oldpen = SelectObject(gc,GetStockObject(BLACK_PEN)); // replace current pen with safe one
- if (oldpen != xmap.pen)SelectObject(gc,oldpen); // if old one not xmap.pen, need to put it back
- DeleteObject(xmap.pen); // delete pen
- }
-// xmap.pen = CreatePen(PS_SOLID, 1, xmap.rgb); // get a pen into xmap.pen
- LOGBRUSH penbrush = {BS_SOLID, xmap.rgb, 0};
- xmap.pen = ExtCreatePen(PS_GEOMETRIC | PS_ENDCAP_FLAT | PS_JOIN_ROUND, lw, &penbrush, 0, 0);
- xmap.pwidth = lw;
- xmap.brush = -1;
-}
-
-void Fl_GDI_Graphics_Driver::color(Fl_Color i) {
- if (i & 0xffffff00) {
- unsigned rgb = (unsigned)i;
- color((uchar)(rgb >> 24), (uchar)(rgb >> 16), (uchar)(rgb >> 8));
- } else {
- Fl_Graphics_Driver::color(i);
- Fl_XMap &xmap = fl_xmap[i];
- int tw = line_width_ ? line_width_ : int(scale()); if (!tw) tw = 1;
- if (!xmap.pen || xmap.pwidth != tw) {
-#if USE_COLORMAP
- if (fl_palette) {
- set_xmap(xmap, PALETTEINDEX(i), tw);
- } else {
-#endif
- unsigned c = fl_cmap[i];
- set_xmap(xmap, RGB(uchar(c>>24), uchar(c>>16), uchar(c>>8)), tw);
-#if USE_COLORMAP
- }
-#endif
- }
- fl_current_xmap = &xmap;
- SelectObject(gc_, (HGDIOBJ)(xmap.pen));
- }
-}
-
-void Fl_GDI_Graphics_Driver::color(uchar r, uchar g, uchar b) {
- static Fl_XMap xmap;
- COLORREF c = RGB(r,g,b);
- Fl_Graphics_Driver::color( fl_rgb_color(r, g, b) );
- int tw = line_width_ ? line_width_ : int(scale()); if (!tw) tw = 1;
- if (!xmap.pen || c != xmap.rgb || tw != xmap.pwidth) {
- clear_xmap(xmap);
- set_xmap(xmap, c, tw);
- }
- fl_current_xmap = &xmap;
- SelectObject(gc_, (HGDIOBJ)(xmap.pen));
-}
-
-HBRUSH fl_brush() {
- return fl_brush_action(0);
-}
-
-HBRUSH fl_brush_action(int action) {
- Fl_XMap *xmap = fl_current_xmap;
- HDC gc = (HDC)fl_graphics_driver->gc();
- // Wonko: we use some statistics to cache only a limited number
- // of brushes:
-#define FL_N_BRUSH 16
- static struct Fl_Brush {
- HBRUSH brush;
- unsigned short usage;
- Fl_XMap* backref;
- } brushes[FL_N_BRUSH];
-
- if (action) {
- SelectObject(gc, GetStockObject(BLACK_BRUSH)); // Load stock object
- for (int i=0; i<FL_N_BRUSH; i++) {
- if (brushes[i].brush)
- DeleteObject(brushes[i].brush); // delete all brushes in array
- }
- return NULL;
- }
-
- int i = xmap->brush; // find the associated brush
- if (i != -1) { // if the brush was allready allocated
- if (brushes[i].brush == NULL) goto CREATE_BRUSH;
- if ( (++brushes[i].usage) > 32000 ) { // keep a usage statistic
- for (int j=0; j<FL_N_BRUSH; j++) {
- if (brushes[j].usage>16000)
- brushes[j].usage -= 16000;
- else
- brushes[j].usage = 0;
- }
- }
- return brushes[i].brush;
- } else {
- int umin = 32000, imin = 0;
- for (i=0; i<FL_N_BRUSH; i++) {
- if (brushes[i].brush == NULL) goto CREATE_BRUSH;
- if (brushes[i].usage<umin) {
- umin = brushes[i].usage;
- imin = i;
- }
- }
- i = imin;
- HGDIOBJ tmpbrush = GetStockObject(BLACK_BRUSH); // get a stock brush
- HGDIOBJ oldbrush = SelectObject(gc,tmpbrush); // load in into current context
- if (oldbrush != brushes[i].brush) SelectObject(gc,oldbrush); // reload old one
- DeleteObject(brushes[i].brush); // delete the one in list
- brushes[i].brush = NULL;
- brushes[i].backref->brush = -1;
- }
-CREATE_BRUSH:
- brushes[i].brush = CreateSolidBrush(xmap->rgb);
- brushes[i].usage = 0;
- brushes[i].backref = xmap;
- xmap->brush = i;
- return brushes[i].brush;
-}
-
-void Fl_GDI_Graphics_Driver::free_color(Fl_Color i, int overlay) {
- if (overlay) return; // do something about GL overlay?
- clear_xmap(fl_xmap[i]);
-}
-
-void Fl_GDI_Graphics_Driver::set_color(Fl_Color i, unsigned c) {
- if (fl_cmap[i] != c) {
- clear_xmap(fl_xmap[i]);
- fl_cmap[i] = c;
- }
-}
-
-#if USE_COLORMAP
-
-// 'fl_select_palette()' - Make a color palette for 8-bit displays if necessary
-// Thanks to Michael Sweet @ Easy Software Products for this
-
-HPALETTE
-fl_select_palette(void)
-{
- static char beenhere;
- HDC gc = (HDC)fl_graphics_driver->gc();
- if (!beenhere) {
- beenhere = 1;
-
- int nColors = GetDeviceCaps(gc, SIZEPALETTE);
- if (nColors <= 0 || nColors > 256) return NULL;
- // this will try to work on < 256 color screens, but will probably
- // come out quite badly.
-
- // I lamely try to get this variable-sized object allocated on stack:
- ulong foo[(sizeof(LOGPALETTE)+256*sizeof(PALETTEENTRY))/sizeof(ulong)+1];
- LOGPALETTE *pPal = (LOGPALETTE*)foo;
-
- pPal->palVersion = 0x300;
- pPal->palNumEntries = nColors;
-
- // Build 256 colors from the standard FLTK colormap...
-
- for (int i = 0; i < nColors; i ++) {
- pPal->palPalEntry[i].peRed = (fl_cmap[i] >> 24) & 255;
- pPal->palPalEntry[i].peGreen = (fl_cmap[i] >> 16) & 255;
- pPal->palPalEntry[i].peBlue = (fl_cmap[i] >> 8) & 255;
- pPal->palPalEntry[i].peFlags = 0;
- };
-
- // Create the palette:
- fl_palette = CreatePalette(pPal);
- }
- if (fl_palette) {
- SelectPalette(gc, fl_palette, FALSE);
- RealizePalette(gc);
- }
- return fl_palette;
-}
-
-#endif
-
-#if USE_GDIPLUS
-void Fl_GDIplus_Graphics_Driver::color(uchar r, uchar g, uchar b) {
- Fl_GDI_Graphics_Driver::color(r, g, b);
- gdiplus_color_.SetFromCOLORREF(fl_RGB());
-}
-
-void Fl_GDIplus_Graphics_Driver::color(Fl_Color i) {
- Fl_GDI_Graphics_Driver::color(i);
- gdiplus_color_.SetFromCOLORREF(fl_RGB());
-}
-#endif // USE_GDIPLUS
diff --git a/src/drivers/GDI/Fl_GDI_Graphics_Driver_font.cxx b/src/drivers/GDI/Fl_GDI_Graphics_Driver_font.cxx
deleted file mode 100644
index 49111f10e..000000000
--- a/src/drivers/GDI/Fl_GDI_Graphics_Driver_font.cxx
+++ /dev/null
@@ -1,678 +0,0 @@
-//
-// Windows font utilities for the Fast Light Tool Kit (FLTK).
-//
-// Copyright 1998-2026 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:
-//
-// https://www.fltk.org/COPYING.php
-//
-// Please see the following page on how to report bugs and issues:
-//
-// https://www.fltk.org/bugs.php
-//
-
-#include <config.h>
-
-#ifndef WIN32_LEAN_AND_MEAN
-# define WIN32_LEAN_AND_MEAN
-#endif
-/* We require Windows 2000 features such as GetGlyphIndices */
-#if !defined(WINVER) || (WINVER < 0x0500)
-# ifdef WINVER
-# undef WINVER
-# endif
-# define WINVER 0x0500
-#endif
-#if !defined(_WIN32_WINNT) || (_WIN32_WINNT < 0x0500)
-# ifdef _WIN32_WINNT
-# undef _WIN32_WINNT
-# endif
-# define _WIN32_WINNT 0x0500
-#endif
-
-// Select fonts from the FLTK font table.
-#include "Fl_GDI_Graphics_Driver.H"
-#include "../../flstring.h"
-#include <FL/Fl.H>
-#include <FL/fl_draw.H>
-#include <FL/platform.H>
-#include "Fl_Font.H"
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <FL/fl_string_functions.h>
-
-// This function fills in the FLTK font table with all the fonts that
-// are found on the X server. It tries to place the fonts into families
-// and to sort them so the first 4 in a family are normal, bold, italic,
-// and bold italic.
-#include <FL/fl_utf8.h>
-#ifdef __CYGWIN__
-# include <wchar.h>
-#endif
-
-// Bug: older versions calculated the value for *ap as a side effect of
-// making the name, and then forgot about it. To avoid having to change
-// the header files I decided to store this value in the last character
-// of the font name array.
-#define ENDOFBUFFER 127 // sizeof(Fl_Font.fontname)-1
-
-// turn a stored font name into a pretty name:
-const char* Fl_GDI_Graphics_Driver::get_font_name(Fl_Font fnum, int* ap) {
- Fl_Fontdesc *f = fl_fonts + fnum;
- if (!f->fontname[0]) {
- const char* p = f->name;
- if (!p || !*p) {if (ap) *ap = 0; return "";}
- int type;
- switch (*p) {
- case 'B': type = FL_BOLD; break;
- case 'I': type = FL_ITALIC; break;
- case 'P': type = FL_BOLD | FL_ITALIC; break;
- default: type = 0; break;
- }
- strlcpy(f->fontname, p+1, ENDOFBUFFER);
- if (type & FL_BOLD) strlcat(f->fontname, " bold", ENDOFBUFFER);
- if (type & FL_ITALIC) strlcat(f->fontname, " italic", ENDOFBUFFER);
- f->fontname[ENDOFBUFFER] = (char)type;
- }
- if (ap) *ap = f->fontname[ENDOFBUFFER];
- return f->fontname;
-}
-
-static int fl_free_font = FL_FREE_FONT;
-
-// helper function for `enumcbw()` to avoid code repetition
-// input:
-// ft: font "type", i.e. ' ', 'B', 'I', or 'P'
-// fn: font name whose first byte is overwritten and then stored
-
-static void set_font_name(const char ft, char *fn) {
- fn[0] = ft;
- Fl::set_font((Fl_Font)(fl_free_font++), fl_strdup(fn));
-}
-
-// Callback for EnumFontFamiliesW():
-// return 1 to continue, 0 to stop enumeration
-
-static int CALLBACK
-enumcbw(CONST LOGFONTW *lpelf,
- CONST TEXTMETRICW * /* lpntm */,
- DWORD /* FontType */,
- LPARAM p) {
- if (!p && lpelf->lfCharSet != ANSI_CHARSET) return 1;
- char *fn = nullptr; // FLTK font name
- unsigned lw = (unsigned)wcslen(lpelf->lfFaceName);
- unsigned dstlen = fl_utf8fromwc(fn, 0, (wchar_t*)lpelf->lfFaceName, lw); // measure the string
- fn = (char*)malloc((size_t)dstlen + 2); // "?" + name + NUL
- if (!fn) return 1;
- fn[0] = ' ';
- dstlen = fl_utf8fromwc(fn+1, dstlen+1, (wchar_t*)lpelf->lfFaceName, lw); // convert the string
- fn[dstlen + 1] = 0;
- // skip if it is one of our built-in fonts
- for (int i = 0; i < FL_FREE_FONT; i++) {
- if (!strcmp(Fl::get_font_name((Fl_Font)i), fn+1)) {
- free(fn);
- return 1;
- }
- }
- set_font_name(' ', fn);
- if (lpelf->lfWeight <= 400)
- set_font_name('B', fn);
- set_font_name('I', fn);
- if (lpelf->lfWeight <= 400)
- set_font_name('P', fn);
- free(fn);
- return 1;
-} /* enumcbw */
-
-Fl_Font Fl_GDI_Graphics_Driver::set_fonts(const char* xstarname) {
- HDC gc = (HDC)fl_graphics_driver->gc();
- if (fl_free_font == FL_FREE_FONT) {// if not already been called
- if (!gc) gc = fl_GetDC(0);
-
- EnumFontFamiliesW(gc, NULL, (FONTENUMPROCW)enumcbw, xstarname != 0);
-
- }
- return (Fl_Font)fl_free_font;
-}
-
-
-static int nbSize;
-static int cyPerInch;
-static int sizes[128];
-static int CALLBACK
-
-EnumSizeCbW(CONST LOGFONTW * /*lpelf*/,
- CONST TEXTMETRICW *lpntm,
- DWORD fontType,
- LPARAM /*p*/) {
- if ((fontType & RASTER_FONTTYPE) == 0) {
- sizes[0] = 0;
- nbSize = 1;
-
- // Scalable font
- return 0;
- }
-
- int add = lpntm->tmHeight - lpntm->tmInternalLeading;
- add = MulDiv(add, 72, cyPerInch);
-
- int start = 0;
- while ((start < nbSize) && (sizes[start] < add)) {
- start++;
- }
-
- if ((start < nbSize) && (sizes[start] == add)) {
- return 1;
- }
-
- for (int i=nbSize; i>start; i--) sizes[i] = sizes[i - 1];
-
- sizes[start] = add;
- nbSize++;
-
- // Stop enum if buffer overflow
- return nbSize < 128;
-}
-
-
-int Fl_GDI_Graphics_Driver::get_font_sizes(Fl_Font fnum, int*& sizep) {
- nbSize = 0;
- Fl_Fontdesc *s = fl_fonts+fnum;
- if (!s->name) s = fl_fonts; // empty slot in table, use entry 0
-
- HDC gc = (HDC)fl_graphics_driver->gc();
- if (!gc) gc = fl_GetDC(0);
- cyPerInch = GetDeviceCaps(gc, LOGPIXELSY);
- if (cyPerInch < 1) cyPerInch = 1;
-
-// int l = fl_utf_nb_char((unsigned char*)s->name+1, strlen(s->name+1));
-// unsigned short *b = (unsigned short*) malloc((l + 1) * sizeof(short));
-// fl_utf2unicode((unsigned char*)s->name+1, l, (wchar_t*)b);
- const char *nm = (const char*)s->name+1;
- size_t len = strlen(s->name+1);
- unsigned l = fl_utf8toUtf16(nm, (unsigned) len, NULL, 0); // Pass NULL to query length required
- unsigned short *b = (unsigned short*) malloc((l + 1) * sizeof(short));
- l = fl_utf8toUtf16(nm, (unsigned) len, b, (l+1)); // Now do the conversion
- b[l] = 0;
- EnumFontFamiliesW(gc, (WCHAR*)b, (FONTENUMPROCW)EnumSizeCbW, 0);
- free(b);
-
- sizep = sizes;
- return nbSize;
-}
-
-const char *Fl_GDI_Graphics_Driver::font_name(int num) {
- return fl_fonts[num].name;
-}
-
-void Fl_GDI_Graphics_Driver::font_name(int num, const char *name) {
- Fl_Fontdesc *s = fl_fonts + num;
- if (s->name) {
- if (!strcmp(s->name, name)) {s->name = name; return;}
- for (Fl_Font_Descriptor* f = s->first; f;) {
- Fl_Font_Descriptor* n = f->next; delete f; f = n;
- }
- s->first = 0;
- }
- s->name = name;
- s->fontname[0] = 0;
- s->first = 0;
-}
-
-
-static int fl_angle_ = 0;
-// Unicode string buffer
-static unsigned short *wstr = NULL;
-static int wstr_len = 0;
-
-#ifndef FL_DOXYGEN
-Fl_GDI_Font_Descriptor::Fl_GDI_Font_Descriptor(const char* name, Fl_Fontsize fsize) : Fl_Font_Descriptor(name,fsize) {
- int weight = FW_NORMAL;
- int italic = 0;
- switch (*name++) {
- case 'I': italic = 1; break;
- case 'P': italic = 1;
- case 'B': weight = FW_BOLD; break;
- case ' ': break;
- default: name--;
- }
- int wn = fl_utf8toUtf16(name, (unsigned int)strlen(name), wstr, wstr_len);
- if (wn >= wstr_len) {
- wstr = (unsigned short*) realloc(wstr, sizeof(unsigned short) * (wn + 1));
- wstr_len = wn + 1;
- wn = fl_utf8toUtf16(name, (unsigned int)strlen(name), wstr, wstr_len);
- }
-
- fid = CreateFontW(
- -fsize, // negative makes it use "char size"
- 0, // logical average character width
- fl_angle_*10, // angle of escapement
- fl_angle_*10, // base-line orientation angle
- weight,
- italic,
- FALSE, // underline attribute flag
- FALSE, // strikeout attribute flag
- DEFAULT_CHARSET, // character set identifier
- OUT_DEFAULT_PRECIS, // output precision
- CLIP_DEFAULT_PRECIS,// clipping precision
- DEFAULT_QUALITY, // output quality
- DEFAULT_PITCH, // pitch and family
- (LPCWSTR)wstr // pointer to typeface name string
- );
- angle = fl_angle_;
- HDC gc = (HDC)fl_graphics_driver->gc();
- if (!gc) gc = fl_GetDC(0);
- SelectObject(gc, fid);
- GetTextMetrics(gc, &metr);
-// BOOL ret = GetCharWidthFloat(fl_gc, metr.tmFirstChar, metr.tmLastChar, font->width+metr.tmFirstChar);
-// ...would be the right call, but is not implemented into Window95! (WinNT?)
- //GetCharWidth(fl_gc, 0, 255, width);
- int i;
- memset(width, 0, 64 * sizeof(int*));
-#if HAVE_GL
- for (i = 0; i < 64; i++) glok[i] = 0;
-#endif
- size = fsize;
-}
-
-Fl_GDI_Font_Descriptor::~Fl_GDI_Font_Descriptor() {
-#if HAVE_GL
-// Delete list created by gl_draw(). This is not done by this code
-// as it will link in GL unnecessarily. There should be some kind
-// of "free" routine pointer, or a subclass?
-#endif
- if (this == fl_graphics_driver->font_descriptor()) fl_graphics_driver->font_descriptor(NULL);
- DeleteObject(fid);
- for (int i = 0; i < 64; i++) {
- if ( width[i] ) free(width[i]);
- }
-}
-
-////////////////////////////////////////////////////////////////
-
-// WARNING: if you add to this table, you must redefine FL_FREE_FONT
-// in Enumerations.H & recompile!!
-static Fl_Fontdesc built_in_table[] = {
- {" Microsoft Sans Serif"},
- {"BMicrosoft Sans Serif"},
- {"IMicrosoft Sans Serif"},
- {"PMicrosoft Sans Serif"},
-{" Courier New"},
-{"BCourier New"},
-{"ICourier New"},
-{"PCourier New"},
-{" Times New Roman"},
-{"BTimes New Roman"},
-{"ITimes New Roman"},
-{"PTimes New Roman"},
-{" Symbol"},
-{" Terminal"},
-{"BTerminal"},
-{" Wingdings"},
-};
-
-Fl_Fontdesc* fl_fonts = built_in_table;
-
-static Fl_GDI_Font_Descriptor* find(Fl_Font fnum, Fl_Fontsize size, int angle) {
- Fl_Fontdesc* s = fl_fonts+fnum;
- if (!s->name) s = fl_fonts; // use 0 if fnum undefined
- Fl_GDI_Font_Descriptor* f;
- for (f = (Fl_GDI_Font_Descriptor*)s->first; f; f = (Fl_GDI_Font_Descriptor*)f->next)
- if (f->size == size && f->angle == angle) return f;
- f = new Fl_GDI_Font_Descriptor(s->name, size);
- f->next = s->first;
- s->first = f;
- return f;
-}
-
-////////////////////////////////////////////////////////////////
-// Public interface:
-
-static void fl_font(Fl_Graphics_Driver *driver, Fl_Font fnum, Fl_Fontsize size, int angle) {
- if (fnum==-1) { // just make sure that we will load a new font next time
- fl_angle_ = 0;
- driver->Fl_Graphics_Driver::font(0, 0);
- return;
- }
- if (fnum == driver->Fl_Graphics_Driver::font() && size == ((Fl_GDI_Graphics_Driver*)driver)->size_unscaled() && angle == fl_angle_) return;
- fl_angle_ = angle;
- driver->Fl_Graphics_Driver::font(fnum, size);
- driver->font_descriptor( find(fnum, size, angle) );
-}
-
-void Fl_GDI_Graphics_Driver::font_unscaled(Fl_Font fnum, Fl_Fontsize size) {
- fl_font(this, fnum, size, 0);
-}
-
-int Fl_GDI_Graphics_Driver::height_unscaled() {
- Fl_GDI_Font_Descriptor *fl_fontsize = (Fl_GDI_Font_Descriptor*)font_descriptor();
- if (fl_fontsize) return (fl_fontsize->metr.tmAscent + fl_fontsize->metr.tmDescent);
- else return -1;
-}
-
-int Fl_GDI_Graphics_Driver::descent_unscaled() {
- Fl_GDI_Font_Descriptor *fl_fontsize = (Fl_GDI_Font_Descriptor*)font_descriptor();
- if (fl_fontsize) return fl_fontsize->metr.tmDescent;
- else return -1;
-}
-
-Fl_Fontsize Fl_GDI_Graphics_Driver::size_unscaled() {
- if (font_descriptor()) return size_;
- return -1;
-}
-
-double Fl_GDI_Graphics_Driver::width_unscaled(const char* c, int n) {
- if (n == 0) return 0;
- int len1 = fl_utf8len1(*c);
- if (n > len1 && len1 > 0) { // a text with several codepoints: compute its typographical width
- int wn = fl_utf8toUtf16(c, n, wstr, wstr_len);
- if (wn >= wstr_len) {
- wstr = (unsigned short*) realloc(wstr, sizeof(unsigned short) * (wn + 1));
- wstr_len = wn + 1;
- wn = fl_utf8toUtf16(c, n, wstr, wstr_len);
- }
- HDC gc2 = gc_;
- HWND hWnd;
- if (!gc2) {
- hWnd = Fl::first_window() ? fl_xid(Fl::first_window()) : NULL;
- gc2 = GetDC(hWnd);
- }
- SelectObject(gc2, ((Fl_GDI_Font_Descriptor*)font_descriptor())->fid);
- SIZE s;
- GetTextExtentPoint32W(gc2, (WCHAR*)wstr, wn, &s);
- if (gc2 && gc2 != gc_) ReleaseDC(hWnd, gc2);
- return (double)s.cx;
- }
- int i = 0;
- if (!font_descriptor()) return -1.0;
- double w = 0.0;
- char *end = (char *)&c[n];
- while (i < n) {
- unsigned int ucs;
- int l;
- ucs = fl_utf8decode((const char*)(c + i), end, &l);
-// if (l < 1) l = 1;
- i += l;
- if (!fl_nonspacing(ucs)) {
- w += width_unscaled(ucs);
- }
- }
- return w;
-}
-
-double Fl_GDI_Graphics_Driver::width_unscaled(unsigned int c) {
- Fl_GDI_Font_Descriptor *fl_fontsize = (Fl_GDI_Font_Descriptor*)font_descriptor();
- unsigned int r;
- SIZE s;
- // Special Case Handling of Unicode points over U+FFFF.
- // The logic (below) computes a lookup table for char widths
- // on-the-fly, but the table only covers codepoints up to
- // U+FFFF, which covers the basic multilingual plane, but
- // not any higher plane, or glyphs that require surrogate-pairs
- // to encode them in WinXX, which is UTF16.
- // This code assumes that these glyphs are rarely used and simply
- // measures them explicitly if they occur - This will be slow...
- if(c > 0x0000FFFF) { // UTF16 surrogate pair is needed
- if (!gc_) { // We have no valid gc, so nothing to measure - bail out
- return 0.0;
- }
- int cc; // cell count
- unsigned short u16[4]; // Array for UTF16 representation of c
- // Creates a UTF16 string from a UCS code point.
- cc = fl_ucs_to_Utf16(c, u16, 4);
- // Make sure the current font is selected before we make the measurement
- SelectObject(gc_, fl_fontsize->fid);
- // measure the glyph width
- GetTextExtentPoint32W(gc_, (WCHAR*)u16, cc, &s);
- return (double)s.cx;
- }
- // else - this falls through to the lookup-table for glyph widths
- // in the basic multilingual plane
- r = (c & 0xFC00) >> 10;
- if (!fl_fontsize->width[r]) {
- fl_fontsize->width[r] = (int*) malloc(sizeof(int) * 0x0400);
- for (int i = 0; i < 0x0400; i++) fl_fontsize->width[r][i] = -1;
- } else {
- if ( fl_fontsize->width[r][c&0x03FF] >= 0 ) { // already cached
- return (double) fl_fontsize->width[r][c & 0x03FF];
- }
- }
- unsigned short ii = r * 0x400;
- // The following code makes a best effort attempt to obtain a valid fl_gc.
- // If no fl_gc is available at the time we call fl_width(), then we first
- // try to obtain a gc from the first fltk window.
- // If that is null then we attempt to obtain the gc from the current screen
- // using (GetDC(NULL)).
- // This should resolve STR #2086
- HDC gc2 = gc_;
- HWND hWnd = 0;
- if (!gc2) { // We have no valid gc, try and obtain one
- // Use our first fltk window, or fallback to using the screen via GetDC(NULL)
- hWnd = Fl::first_window() ? fl_xid(Fl::first_window()) : NULL;
- gc2 = GetDC(hWnd);
- }
- if (!gc2) Fl::fatal("Invalid graphic context: fl_width() failed because no valid HDC was found!");
- SelectObject(gc2, fl_fontsize->fid);
- ii += c &0x03FF;
- GetTextExtentPoint32W(gc2, (WCHAR*)&ii, 1, &s);
- fl_fontsize->width[r][c&0x03FF] = s.cx;
- if (gc2 && gc2 != gc_) ReleaseDC(hWnd, gc2);
- return (double) fl_fontsize->width[r][c & 0x03FF];
-}
-
-/* Add function pointer to allow us to access GetGlyphIndicesW on systems that have it,
- * without crashing on systems that do not. */
-/* DWORD WINAPI GetGlyphIndicesW(HDC,LPCWSTR,int,LPWORD,DWORD) */
-typedef DWORD (WINAPI* fl_GetGlyphIndices_func)(HDC,LPCWSTR,int,LPWORD,DWORD);
-
-static fl_GetGlyphIndices_func fl_GetGlyphIndices = NULL; // used to hold a proc pointer for GetGlyphIndicesW
-static int have_loaded_GetGlyphIndices = 0; // Set this non-zero once we have tried to load GetGlyphIndices
-
-// Function that tries to dynamically load GetGlyphIndicesW at runtime
-static void GetGlyphIndices_init() {
- // Since not all versions of Windows include GetGlyphIndicesW support,
- // we do a run-time check for the required function.
- HMODULE hMod = GetModuleHandle("GDI32.DLL");
- if (hMod) {
- // check that GetGlyphIndicesW is available
- fl_GetGlyphIndices = (fl_GetGlyphIndices_func)GetProcAddress(hMod, "GetGlyphIndicesW");
- }
- have_loaded_GetGlyphIndices = -1; // set this non-zero when we have attempted to load GetGlyphIndicesW
-} // GetGlyphIndices_init function
-
-static void on_printer_extents_update(int &dx, int &dy, int &w, int &h, HDC gc)
-// converts text extents from device coords to logical coords
-{
- POINT pt[3] = { {0, 0}, {dx, dy}, {dx+w, dy+h} };
- DPtoLP(gc, pt, 3);
- w = pt[2].x - pt[1].x;
- h = pt[2].y - pt[1].y;
- dx = pt[1].x - pt[0].x;
- dy = pt[1].y - pt[0].y;
-}
-
-// if printer context, extents shd be converted to logical coords
-#define EXTENTS_UPDATE(x,y,w,h,gc) \
- if (Fl_Surface_Device::surface() != Fl_Display_Device::display_device()) { \
- on_printer_extents_update(x,y,w,h,gc); \
- }
-
-// Function to determine the extent of the "inked" area of the glyphs in a string
-void Fl_GDI_Graphics_Driver::text_extents_unscaled(const char *c, int n, int &dx, int &dy, int &w, int &h) {
-
- Fl_GDI_Font_Descriptor *fl_fontsize = (Fl_GDI_Font_Descriptor*)font_descriptor();
- if (!fl_fontsize) { // no valid font, nothing to measure
- w = 0; h = 0;
- dx = dy = 0;
- return;
- }
-
- static unsigned short *ext_buff = NULL; // UTF-16 converted version of input UTF-8 string
- static WORD *w_buff = NULL; // glyph indices array
- static unsigned wc_len = 0; // current string buffer dimensions
- static const MAT2 matrix = { { 0, 1 }, { 0, 0 }, { 0, 0 }, { 0, 1 } }; // identity mat for GetGlyphOutlineW
- GLYPHMETRICS metrics;
- int maxw = 0, maxh = 0, dh;
- int minx = 0, miny = -999999;
- unsigned len = 0, idx = 0;
- HWND hWnd = 0;
- HDC gc2 = gc_; // local copy of current gc - make a copy in case we change it...
- int has_surrogates; // will be set if the string contains surrogate pairs
-
- // Have we loaded the GetGlyphIndicesW function yet?
- if (have_loaded_GetGlyphIndices == 0) {
- GetGlyphIndices_init();
- }
- // Do we have a usable GetGlyphIndices function?
- if(!fl_GetGlyphIndices) goto exit_error; // No GetGlyphIndices function, use fallback mechanism instead
-
- // The following code makes a best effort attempt to obtain a valid fl_gc.
- // See description in fl_width() above for an explanation.
- if (!gc2) { // We have no valid gc, try and obtain one
- // Use our first fltk window, or fallback to using the screen via GetDC(NULL)
- hWnd = Fl::first_window() ? fl_xid(Fl::first_window()) : NULL;
- gc2 = GetDC(hWnd);
- }
- if (!gc2) goto exit_error; // no valid gc, attempt to use fallback measure
-
- // now convert the string to WCHAR and measure it
- len = fl_utf8toUtf16(c, n, ext_buff, wc_len);
- if(len >= wc_len) {
- if(ext_buff) {delete [] ext_buff;}
- if(w_buff) {delete [] w_buff;}
- wc_len = len + 64;
- ext_buff = new unsigned short[wc_len];
- w_buff = new WORD[wc_len];
- len = fl_utf8toUtf16(c, n, ext_buff, wc_len);
- }
- SelectObject(gc2, fl_fontsize->fid);
-
- // Are there surrogate-pairs in this string? If so GetGlyphIndicesW will fail
- // since it can only handle the BMP range.
- // We ideally want to use GetGlyphIndicesW, as it is the Right Thing, but it
- // only works for the BMP, so we leverage GetCharacterPlacementW instead, which
- // is not ideal, but works adequately well, and does handle surrogate pairs.
- has_surrogates = 0;
- for(unsigned ll = 0; ll < len; ll++) {
- if((ext_buff[ll] >= 0xD800) && (ext_buff[ll] < 0xE000)) {
- has_surrogates = -1;
- break;
- }
- }
- if (has_surrogates) {
- // GetGlyphIndices will not work - use GetCharacterPlacementW() instead
- GCP_RESULTSW gcp_res;
- memset(w_buff, 0, (sizeof(WORD) * wc_len));
- memset(&gcp_res, 0, sizeof(GCP_RESULTSW));
- gcp_res.lpGlyphs = (LPWSTR)w_buff;
- gcp_res.nGlyphs = wc_len;
- gcp_res.lStructSize = sizeof(gcp_res);
-
- DWORD dr = GetCharacterPlacementW(gc2, (WCHAR*)ext_buff, len, 0, &gcp_res, GCP_GLYPHSHAPE);
- if(dr) {
- len = gcp_res.nGlyphs;
- } else goto exit_error;
- } else {
- if (fl_GetGlyphIndices(gc_, (WCHAR*)ext_buff, len, w_buff, GGI_MARK_NONEXISTING_GLYPHS) == GDI_ERROR) {
- // some error occurred here - just return fl_measure values
- goto exit_error;
- }
- }
-
- // now we have the glyph array we measure each glyph in turn...
- for(idx = 0; idx < len; idx++){
- if (GetGlyphOutlineW (gc2, w_buff[idx], GGO_METRICS | GGO_GLYPH_INDEX,
- &metrics, 0, NULL, &matrix) == GDI_ERROR) {
- goto exit_error;
- }
- maxw += metrics.gmCellIncX;
- if(idx == 0) minx = metrics.gmptGlyphOrigin.x;
- dh = metrics.gmBlackBoxY - metrics.gmptGlyphOrigin.y;
- if(dh > maxh) maxh = dh;
- if(miny < metrics.gmptGlyphOrigin.y) miny = metrics.gmptGlyphOrigin.y;
- }
- // for the last cell, we only want the bounding X-extent, not the glyphs increment step
- maxw = maxw - metrics.gmCellIncX + metrics.gmBlackBoxX + metrics.gmptGlyphOrigin.x;
- w = maxw - minx;
- h = maxh + miny;
- dx = minx;
- dy = -miny;
- EXTENTS_UPDATE(dx, dy, w, h, gc_);
- return; // normal exit
-
-exit_error:
- // some error here - just return fl_measure values
- w = (int)width(c, n);
- h = height_unscaled();
- dx = 0;
- dy = descent_unscaled() - h;
- EXTENTS_UPDATE(dx, dy, w, h, gc_);
- return;
-} // fl_text_extents
-
-void Fl_GDI_Graphics_Driver::draw_unscaled(const char* str, int n, int x, int y) {
- COLORREF oldColor = SetTextColor(gc_, fl_RGB());
- // avoid crash if no font has been set yet
- if (!font_descriptor()) this->font(FL_HELVETICA, FL_NORMAL_SIZE);
- SelectObject(gc_, ((Fl_GDI_Font_Descriptor*)font_descriptor())->fid);
- int wn = fl_utf8toUtf16(str, n, wstr, wstr_len);
- if(wn >= wstr_len) {
- wstr = (unsigned short*) realloc(wstr, sizeof(unsigned short) * (wn + 1));
- wstr_len = wn + 1;
- wn = fl_utf8toUtf16(str, n, wstr, wstr_len);
- }
- TextOutW(gc_, x, y, (WCHAR*)wstr, wn);
- SetTextColor(gc_, oldColor); // restore initial state
-}
-
-void Fl_GDI_Graphics_Driver::draw_unscaled(int angle, const char* str, int n, int x, int y) {
- fl_font(this, Fl_Graphics_Driver::font(), size_unscaled(), angle);
- int wn = 0; // count of UTF16 cells to render full string
- COLORREF oldColor = SetTextColor(gc_, fl_RGB());
- SelectObject(gc_, ((Fl_GDI_Font_Descriptor*)font_descriptor())->fid);
- wn = fl_utf8toUtf16(str, n, wstr, wstr_len);
- if(wn >= wstr_len) { // Array too small
- wstr = (unsigned short*) realloc(wstr, sizeof(unsigned short) * (wn + 1));
- wstr_len = wn + 1;
- wn = fl_utf8toUtf16(str, n, wstr, wstr_len); // respin the translation
- }
- TextOutW(gc_, x, y, (WCHAR*)wstr, wn);
- SetTextColor(gc_, oldColor);
- fl_font(this, Fl_Graphics_Driver::font(), size_unscaled(), 0);
-}
-
-void Fl_GDI_Graphics_Driver::rtl_draw_unscaled(const char* c, int n, int x, int y) {
- int wn;
- wn = fl_utf8toUtf16(c, n, wstr, wstr_len);
- if(wn >= wstr_len) {
- wstr = (unsigned short*) realloc(wstr, sizeof(unsigned short) * (wn + 1));
- wstr_len = wn + 1;
- wn = fl_utf8toUtf16(c, n, wstr, wstr_len);
- }
-
- COLORREF oldColor = SetTextColor(gc_, fl_RGB());
- SelectObject(gc_, ((Fl_GDI_Font_Descriptor*)font_descriptor())->fid);
-#ifdef RTL_CHAR_BY_CHAR
- int i = 0;
- int lx = 0;
- while (i < wn) { // output char by char is very bad for Arabic but coherent with fl_width()
- lx = (int) width(wstr[i]);
- x -= lx;
- TextOutW(gc_, x, y, (WCHAR*)wstr + i, 1);
- if (fl_nonspacing(wstr[i])) {
- x += lx;
- }
- i++;
- }
-#else
- UINT old_align = SetTextAlign(gc_, TA_RIGHT | TA_RTLREADING);
- TextOutW(gc_, x, y - height_unscaled() + descent_unscaled(), (WCHAR*)wstr, wn);
- SetTextAlign(gc_, old_align);
-#endif
- SetTextColor(gc_, oldColor);
-}
-#endif
diff --git a/src/drivers/GDI/Fl_GDI_Graphics_Driver_image.cxx b/src/drivers/GDI/Fl_GDI_Graphics_Driver_image.cxx
deleted file mode 100644
index 3a8e70689..000000000
--- a/src/drivers/GDI/Fl_GDI_Graphics_Driver_image.cxx
+++ /dev/null
@@ -1,826 +0,0 @@
-//
-// Windows image drawing code for the Fast Light Tool Kit (FLTK).
-//
-// Copyright 1998-2024 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:
-//
-// https://www.fltk.org/COPYING.php
-//
-// Please see the following page on how to report bugs and issues:
-//
-// https://www.fltk.org/bugs.php
-//
-
-// I hope a simple and portable method of drawing color and monochrome
-// images. To keep this simple, only a single storage type is
-// supported: 8 bit unsigned data, byte order RGB, and pixels are
-// stored packed into rows with the origin at the top-left. It is
-// possible to alter the size of pixels with the "delta" argument, to
-// add alpha or other information per pixel. It is also possible to
-// change the origin and direction of the image data by messing with
-// the "delta" and "linedelta", making them negative, though this may
-// defeat some of the shortcuts in translating the image for X.
-
-// Unbelievably (since it conflicts with how most PC software works)
-// Micro$oft picked a bottom-up and BGR storage format for their
-// DIB images. I'm pretty certain there is a way around this, but
-// I can't find any other than the brute-force method of drawing
-// each line as a separate image. This may also need to be done
-// if the delta is any amount other than 1, 3, or 4.
-
-////////////////////////////////////////////////////////////////
-
-#include <config.h>
-#include "Fl_GDI_Graphics_Driver.H"
-#include "../WinAPI/Fl_WinAPI_System_Driver.H"
-#include <FL/Fl.H>
-#include <FL/fl_draw.H>
-#include <FL/platform.H>
-#include <FL/Fl_Image_Surface.H>
-
-#define MAXBUFFER 0x40000 // 256k
-
-void fl_release_dc(HWND, HDC); // from Fl_win32.cxx
-
-#if USE_COLORMAP
-
-// error-diffusion dither into the FLTK colormap
-static void dither(uchar* to, const uchar* from, int w, int delta) {
- static int ri, gi, bi, dir;
- int r=ri, g=gi, b=bi;
- int d, td;
- if (dir) {
- dir = 0;
- from = from+(w-1)*delta;
- to = to+(w-1);
- d = -delta;
- td = -1;
- } else {
- dir = 1;
- d = delta;
- td = 1;
- }
- for (; w--; from += d, to += td) {
- r += from[0]; if (r < 0) r = 0; else if (r>255) r = 255;
- int rr = r*FL_NUM_RED/256;
- r -= rr*255/(FL_NUM_RED-1);
- g += from[1]; if (g < 0) g = 0; else if (g>255) g = 255;
- int gg = g*FL_NUM_GREEN/256;
- g -= gg*255/(FL_NUM_GREEN-1);
- b += from[2]; if (b < 0) b = 0; else if (b>255) b = 255;
- int bb = b*FL_NUM_BLUE/256;
- b -= bb*255/(FL_NUM_BLUE-1);
- *to = uchar(FL_COLOR_CUBE+(bb*FL_NUM_RED+rr)*FL_NUM_GREEN+gg);
- }
- ri = r; gi = g; bi = b;
-}
-
-// error-diffusion dither into the FLTK colormap
-static void monodither(uchar* to, const uchar* from, int w, int delta) {
- static int ri,dir;
- int r=ri;
- int d, td;
- if (dir) {
- dir = 0;
- from = from+(w-1)*delta;
- to = to+(w-1);
- d = -delta;
- td = -1;
- } else {
- dir = 1;
- d = delta;
- td = 1;
- }
- for (; w--; from += d, to += td) {
- r += *from; if (r < 0) r = 0; else if (r>255) r = 255;
- int rr = r*FL_NUM_GRAY/256;
- r -= rr*255/(FL_NUM_GRAY-1);
- *to = uchar(FL_GRAY_RAMP+rr);
- }
- ri = r;
-}
-
-#endif // USE_COLORMAP
-
-static int fl_abs(int v) { return v<0 ? -v : v; }
-
-static void innards(const uchar *buf, int X, int Y, int W, int H,
- int delta, int linedelta, int depth,
- Fl_Draw_Image_Cb cb, void* userdata, HDC gc)
-{
- char indexed = 0;
-
-#if USE_COLORMAP
- indexed = (fl_palette != 0);
-#endif
-
- if (depth==0) depth = 3;
- if (indexed || !fl_can_do_alpha_blending())
- depth = (depth-1)|1;
-
- if (!linedelta) linedelta = W*fl_abs(delta);
-
- int x = 0, y = 0, w = 0, h = 0;
- fl_clip_box(X, Y, W, H, x, y, w, h);
- if (w<=0 || h<=0) return;
- if (buf) buf += (x-X)*delta + (y-Y)*linedelta;
-
- // bmibuffer: BITMAPINFOHEADER + 256 colors (RGBQUAD) + 1 (rounding effects ?)
- static U32 bmibuffer[sizeof(BITMAPINFOHEADER)/4 + 257];
- BITMAPINFO *bmi = (BITMAPINFO*)bmibuffer;
- if (!bmi->bmiHeader.biSize) {
- bmi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
- bmi->bmiHeader.biPlanes = 1;
- bmi->bmiHeader.biCompression = BI_RGB;
- bmi->bmiHeader.biXPelsPerMeter = 0;
- bmi->bmiHeader.biYPelsPerMeter = 0;
- bmi->bmiHeader.biClrUsed = 0;
- bmi->bmiHeader.biClrImportant = 0;
- }
-#if USE_COLORMAP
- if (indexed) {
- for (short i=0; i<256; i++) {
- *((short*)(bmi->bmiColors)+i) = i;
- }
- } else
-#endif
- if (depth<3) {
- RGBQUAD *bmi_colors = &(bmi->bmiColors[0]); // use pointer to suppress warning (STR #3199)
- for (int i=0; i<256; i++) {
- bmi_colors[i].rgbBlue = (uchar)i; // = bmi->bmiColors[i]
- bmi_colors[i].rgbGreen = (uchar)i;
- bmi_colors[i].rgbRed = (uchar)i;
- bmi_colors[i].rgbReserved = (uchar)0; // must be zero
- }
- }
- bmi->bmiHeader.biWidth = w;
-#if USE_COLORMAP
- bmi->bmiHeader.biBitCount = indexed ? 8 : depth*8;
- int pixelsize = indexed ? 1 : depth;
-#else
- bmi->bmiHeader.biBitCount = depth*8;
- int pixelsize = depth;
-#endif
- if (depth==2) { // special case: gray with alpha
- bmi->bmiHeader.biBitCount = 32;
- pixelsize = 4;
- }
- int linesize = (pixelsize*w+3)&~3;
-
- static U32* buffer;
- static long buffer_size;
- int blocking = h;
- {
- int size = linesize * h;
- // when printing, don't limit buffer size not to get a crash in StretchDIBits
- if (size > MAXBUFFER && !fl_graphics_driver->has_feature(Fl_Graphics_Driver::PRINTER)) {
- size = MAXBUFFER;
- blocking = MAXBUFFER / linesize;
- }
- if (size > buffer_size) {
- delete[] buffer;
- buffer_size = size;
- buffer = new U32[(size + 3) / 4];
- }
- }
- bmi->bmiHeader.biHeight = blocking;
- static U32* line_buffer;
- if (!buf) {
- int size = W*delta;
- static int line_buf_size;
- if (size > line_buf_size) {
- delete[] line_buffer;
- line_buf_size = size;
- line_buffer = new U32[(size+3)/4];
- }
- }
- for (int j=0; j<h; ) {
- int k;
- for (k = 0; j<h && k<blocking; k++, j++) {
- const uchar* from;
- if (!buf) { // run the converter:
- cb(userdata, x-X, y-Y+j, w, (uchar*)line_buffer);
- from = (uchar*)line_buffer;
- } else {
- from = buf;
- buf += linedelta;
- }
- uchar *to = (uchar*)buffer+(blocking-k-1)*linesize;
-#if USE_COLORMAP
- if (indexed) {
- if (depth<3)
- monodither(to, from, w, delta);
- else
- dither(to, from, w, delta);
- } else
-#endif
- {
- int i;
- switch (depth) {
- case 1:
- for (i=w; i--; from += delta) *to++ = *from;
- break;
- case 2:
- for (i=w; i--; from += delta, to += 4) {
- uchar a = from[1];
- uchar gray = (from[0]*a)>>8;
- to[0] = gray;
- to[1] = gray;
- to[2] = gray;
- to[3] = a;
- }
- break;
- case 3:
- for (i=w; i--; from += delta, to += 3) {
- uchar r = from[0];
- to[0] = from[2];
- to[1] = from[1];
- to[2] = r;
- }
- break;
- case 4:
- for (i=w; i--; from += delta, to += 4) {
- uchar a = from[3];
- uchar r = from[0];
- to[0] = (from[2]*a)>>8;
- to[1] = (from[1]*a)>>8;
- to[2] = (r*a)>>8;
- to[3] = from[3];
- }
- break;
- }
- }
- } // for (k = 0; j<h && k<blocking ...)
-
- if (fl_graphics_driver->has_feature(Fl_Graphics_Driver::PRINTER)) {
- // if print context, device and logical units are not equal, so SetDIBitsToDevice
- // does not do the expected job, whereas StretchDIBits does it.
- StretchDIBits(gc, x, y+j-k, w, k, 0, 0, w, k,
- (LPSTR)((uchar*)buffer+(blocking-k)*linesize),
- bmi,
-#if USE_COLORMAP
- indexed ? DIB_PAL_COLORS : DIB_RGB_COLORS
-#else
- DIB_RGB_COLORS
-#endif
- , SRCCOPY );
- delete[] buffer;
- buffer = NULL;
- buffer_size = 0;
- }
- else {
- SetDIBitsToDevice(gc, x, y+j-k, w, k, 0, 0, 0, k,
- (LPSTR)((uchar*)buffer+(blocking-k)*linesize),
- bmi,
-#if USE_COLORMAP
- indexed ? DIB_PAL_COLORS : DIB_RGB_COLORS
-#else
- DIB_RGB_COLORS
-#endif
- );
- }
- } // for (int j=0; j<h; )
-}
-
-void Fl_GDI_Graphics_Driver::draw_image_unscaled(const uchar* buf, int x, int y, int w, int h, int d, int l){
- if (fl_abs(d)&FL_IMAGE_WITH_ALPHA) {
- d ^= FL_IMAGE_WITH_ALPHA;
- innards(buf,x,y,w,h,d,l,fl_abs(d),0,0, gc_);
- } else {
- innards(buf,x,y,w,h,d,l,(d<3&&d>-3),0,0, gc_);
- }
-}
-
-void Fl_GDI_Graphics_Driver::draw_image_unscaled(Fl_Draw_Image_Cb cb, void* data,
- int x, int y, int w, int h,int d) {
- if (fl_abs(d)&FL_IMAGE_WITH_ALPHA) {
- d ^= FL_IMAGE_WITH_ALPHA;
- innards(0,x,y,w,h,d,0,(d<3&&d>-3),cb,data, gc_);
- } else {
- innards(0,x,y,w,h,d,0,(d<3&&d>-3),cb,data, gc_);
- }
-}
-
-void Fl_GDI_Graphics_Driver::draw_image_mono_unscaled(const uchar* buf, int x, int y, int w, int h, int d, int l){
- if (fl_abs(d)&FL_IMAGE_WITH_ALPHA) {
- d ^= FL_IMAGE_WITH_ALPHA;
- innards(buf,x,y,w,h,d,l,1,0,0, gc_);
- } else {
- innards(buf,x,y,w,h,d,l,1,0,0, gc_);
- }
-}
-
-void Fl_GDI_Graphics_Driver::draw_image_mono_unscaled(Fl_Draw_Image_Cb cb, void* data,
- int x, int y, int w, int h,int d) {
- if (fl_abs(d)&FL_IMAGE_WITH_ALPHA) {
- d ^= FL_IMAGE_WITH_ALPHA;
- innards(0,x,y,w,h,d,0,1,cb,data, gc_);
- } else {
- innards(0,x,y,w,h,d,0,1,cb,data, gc_);
- }
-}
-
-#if USE_COLORMAP
-void Fl_GDI_Graphics_Driver::colored_rectf(int x, int y, int w, int h, uchar r, uchar g, uchar b) {
- // use the error diffusion dithering code to produce a much nicer block:
- if (fl_palette) {
- uchar c[3];
- c[0] = r; c[1] = g; c[2] = b;
- innards(c, floor(x), floor(y), floor(x + w) - floor(x), floor(y + h) - floor(y),
- 0,0,0,0,0, (HDC)gc());
- return;
- }
- Fl_Graphics_Driver::colored_rectf(x, y, w, h, r, g, b);
-}
-#endif
-
-// Create an N-bit bitmap for masking...
-HBITMAP Fl_GDI_Graphics_Driver::create_bitmask(int w, int h, const uchar *data) {
- // this won't work when the user changes display mode during run or
- // has two screens with different depths
- HBITMAP bm;
- static uchar hiNibble[16] =
- { 0x00, 0x80, 0x40, 0xc0, 0x20, 0xa0, 0x60, 0xe0,
- 0x10, 0x90, 0x50, 0xd0, 0x30, 0xb0, 0x70, 0xf0 };
- static uchar loNibble[16] =
- { 0x00, 0x08, 0x04, 0x0c, 0x02, 0x0a, 0x06, 0x0e,
- 0x01, 0x09, 0x05, 0x0d, 0x03, 0x0b, 0x07, 0x0f };
- HDC current_gc = (HDC)Fl_Surface_Device::surface()->driver()->gc();
- int np = GetDeviceCaps(current_gc, PLANES); //: was always one on sample machines
- int bpp = GetDeviceCaps(current_gc, BITSPIXEL);//: 1,4,8,16,24,32 and more odd stuff?
- int Bpr = (bpp*w+7)/8; //: bytes per row
- int pad = Bpr&1, w1 = (w+7)/8, shr = ((w-1)&7)+1;
- if (bpp==4) shr = (shr+1)/2;
- uchar *newarray = new uchar[(Bpr+pad)*h];
- uchar *dst = newarray;
- const uchar *src = data;
-
- for (int i=0; i<h; i++) {
- // This is slooow, but we do it only once per pixmap
- for (int j=w1; j>0; j--) {
- uchar b = *src++;
- if (bpp==1) {
- *dst++ = (uchar)( hiNibble[b&15] ) | ( loNibble[(b>>4)&15] );
- } else if (bpp==4) {
- for (int k=(j==1)?shr:4; k>0; k--) {
- *dst++ = (uchar)("\377\360\017\000"[b&3]);
- b = b >> 2;
- }
- } else {
- for (int k=(j==1)?shr:8; k>0; k--) {
- if (b&1) {
- *dst++=0;
- if (bpp>8) *dst++=0;
- if (bpp>16) *dst++=0;
- if (bpp>24) *dst++=0;
- } else {
- *dst++=0xff;
- if (bpp>8) *dst++=0xff;
- if (bpp>16) *dst++=0xff;
- if (bpp>24) *dst++=0xff;
- }
-
- b = b >> 1;
- }
- }
- }
-
- dst += pad;
- }
-
- bm = CreateBitmap(w, h, np, bpp, newarray);
- delete[] newarray;
-
- return bm;
-}
-
-void Fl_GDI_Graphics_Driver::delete_bitmask(fl_uintptr_t bm) {
- DeleteObject((HGDIOBJ)bm);
-}
-
-void Fl_GDI_Graphics_Driver::draw_fixed(Fl_Bitmap *bm, int X, int Y, int W, int H, int cx, int cy) {
- X = this->floor(X);
- Y = this->floor(Y);
- cache_size(bm, W, H);
- cx = this->floor(cx); cy = this->floor(cy);
-
- HDC tempdc = CreateCompatibleDC(gc_);
- int save = SaveDC(tempdc);
- SelectObject(tempdc, (HGDIOBJ)*Fl_Graphics_Driver::id(bm));
- SelectObject(gc_, fl_brush());
- // secret bitblt code found in old Windows reference manual:
- BitBlt(gc_, X, Y, W, H, tempdc, cx, cy, 0xE20746L);
- RestoreDC(tempdc, save);
- DeleteDC(tempdc);
-}
-
-Fl_GDI_Printer_Graphics_Driver::transparent_f_type Fl_GDI_Printer_Graphics_Driver::TransparentBlt() {
- HMODULE hMod;
- static transparent_f_type fpter = ( (hMod = LoadLibrary("MSIMG32.DLL")) ?
- (transparent_f_type)GetProcAddress(hMod, "TransparentBlt") : NULL
- );
- return fpter;
-}
-
-void Fl_GDI_Printer_Graphics_Driver::draw_bitmap(Fl_Bitmap *bm, int XP, int YP, int WP, int HP, int cx, int cy) {
- int X, Y, W, H;
- if (Fl_Graphics_Driver::start_image(bm, XP, YP, WP, HP, cx, cy, X, Y, W, H)) {
- return;
- }
- transparent_f_type fl_TransparentBlt = TransparentBlt();
- if (!fl_TransparentBlt) {
- Fl_Graphics_Driver::draw_bitmap(bm, X, Y, W, H, cx, cy);
- return;
- }
- bool recache = false;
- if (*id(bm)) {
- int *pw, *ph;
- cache_w_h(bm, pw, ph);
- recache = (*pw != bm->data_w() || *ph != bm->data_h());
- }
- if (recache || !*id(bm)) {
- bm->uncache();
- cache(bm);
- }
- HDC tempdc;
- int save;
- // algorithm for bitmap output to Fl_GDI_Printer
- Fl_Color save_c = fl_color(); // save bitmap's desired color
- uchar r, g, b;
- Fl::get_color(save_c, r, g, b);
- r = 255-r;
- g = 255-g;
- b = 255-b;
- Fl_Color background = fl_rgb_color(r, g, b); // a color very different from the bitmap's
- Fl_Image_Surface *img_surf = new Fl_Image_Surface(bm->data_w(), bm->data_h());
- Fl_Surface_Device::push_current(img_surf);
- fl_color(background);
- fl_rectf(0,0, bm->data_w(), bm->data_h()); // use this color as offscreen background
- fl_color(save_c); // back to bitmap's color
- HDC off_gc = (HDC)fl_graphics_driver->gc();
- tempdc = CreateCompatibleDC(off_gc);
- save = SaveDC(tempdc);
- SelectObject(tempdc, (HGDIOBJ)*Fl_Graphics_Driver::id(bm));
- SelectObject(off_gc, fl_brush()); // use bitmap's desired color
- BitBlt(off_gc, 0, 0, bm->data_w(), bm->data_h(), tempdc, 0, 0, 0xE20746L); // draw bitmap to offscreen
- Fl_Surface_Device::pop_current();
- SelectObject(tempdc, (HGDIOBJ)img_surf->offscreen()); // use offscreen data
- // draw it to printer context with background color as transparent
- float scaleW = bm->data_w()/float(bm->w());
- float scaleH = bm->data_h()/float(bm->h());
- fl_TransparentBlt(gc_, X, Y, W, H, tempdc,
- int(cx * scaleW), int(cy * scaleH), int(W * scaleW), int(H * scaleH), RGB(r, g, b) );
- delete img_surf;
- RestoreDC(tempdc, save);
- DeleteDC(tempdc);
- if (recache) bm->uncache();
-}
-
-
-// Create a 1-bit mask used for alpha blending
-HBITMAP Fl_GDI_Graphics_Driver::create_alphamask(int w, int h, int d, int ld, const uchar *array) {
- HBITMAP bm;
- int bmw = (w + 7) / 8;
- uchar *bitmap = new uchar[bmw * h];
- uchar *bitptr, bit;
- const uchar *dataptr;
- int x, y;
- static uchar dither[16][16] = { // Simple 16x16 Floyd dither
- { 0, 128, 32, 160, 8, 136, 40, 168,
- 2, 130, 34, 162, 10, 138, 42, 170 },
- { 192, 64, 224, 96, 200, 72, 232, 104,
- 194, 66, 226, 98, 202, 74, 234, 106 },
- { 48, 176, 16, 144, 56, 184, 24, 152,
- 50, 178, 18, 146, 58, 186, 26, 154 },
- { 240, 112, 208, 80, 248, 120, 216, 88,
- 242, 114, 210, 82, 250, 122, 218, 90 },
- { 12, 140, 44, 172, 4, 132, 36, 164,
- 14, 142, 46, 174, 6, 134, 38, 166 },
- { 204, 76, 236, 108, 196, 68, 228, 100,
- 206, 78, 238, 110, 198, 70, 230, 102 },
- { 60, 188, 28, 156, 52, 180, 20, 148,
- 62, 190, 30, 158, 54, 182, 22, 150 },
- { 252, 124, 220, 92, 244, 116, 212, 84,
- 254, 126, 222, 94, 246, 118, 214, 86 },
- { 3, 131, 35, 163, 11, 139, 43, 171,
- 1, 129, 33, 161, 9, 137, 41, 169 },
- { 195, 67, 227, 99, 203, 75, 235, 107,
- 193, 65, 225, 97, 201, 73, 233, 105 },
- { 51, 179, 19, 147, 59, 187, 27, 155,
- 49, 177, 17, 145, 57, 185, 25, 153 },
- { 243, 115, 211, 83, 251, 123, 219, 91,
- 241, 113, 209, 81, 249, 121, 217, 89 },
- { 15, 143, 47, 175, 7, 135, 39, 167,
- 13, 141, 45, 173, 5, 133, 37, 165 },
- { 207, 79, 239, 111, 199, 71, 231, 103,
- 205, 77, 237, 109, 197, 69, 229, 101 },
- { 63, 191, 31, 159, 55, 183, 23, 151,
- 61, 189, 29, 157, 53, 181, 21, 149 },
- { 254, 127, 223, 95, 247, 119, 215, 87,
- 253, 125, 221, 93, 245, 117, 213, 85 }
- };
-
- // Generate a 1-bit "screen door" alpha mask; not always pretty, but
- // definitely fast... In the future we may be able to support things
- // like the RENDER extension in XFree86, when available, to provide
- // true RGBA-blended rendering. See:
- //
- // http://www.xfree86.org/~keithp/render/protocol.html
- //
- // for more info on XRender...
- //
- memset(bitmap, 0, bmw * h);
-
- for (dataptr = array + d - 1, y = 0; y < h; y ++, dataptr += ld)
- for (bitptr = bitmap + y * bmw, bit = 1, x = 0; x < w; x ++, dataptr += d) {
- if (*dataptr > dither[x & 15][y & 15])
- *bitptr |= bit;
- if (bit < 128) bit <<= 1;
- else {
- bit = 1;
- bitptr ++;
- }
- }
-
- bm = create_bitmask(w, h, bitmap);
- delete[] bitmap;
-
- return bm;
-}
-
-
-void Fl_GDI_Graphics_Driver::cache(Fl_RGB_Image *img)
-{
- Fl_Image_Surface *surface = new Fl_Image_Surface(img->data_w(), img->data_h());
- Fl_Surface_Device::push_current(surface);
- if ((img->d() == 2 || img->d() == 4) && fl_can_do_alpha_blending()) {
- fl_draw_image(img->array, 0, 0, img->data_w(), img->data_h(), img->d()|FL_IMAGE_WITH_ALPHA, img->ld());
- } else {
- fl_draw_image(img->array, 0, 0, img->data_w(), img->data_h(), img->d(), img->ld());
- if (img->d() == 2 || img->d() == 4) {
- *Fl_Graphics_Driver::mask(img) = (fl_uintptr_t)create_alphamask(img->data_w(), img->data_h(), img->d(), img->ld(), img->array);
- }
- }
- Fl_Surface_Device::pop_current();
- Fl_Offscreen offs = Fl_Graphics_Driver::get_offscreen_and_delete_image_surface(surface);
- int *pw, *ph;
- cache_w_h(img, pw, ph);
- *pw = img->data_w();
- *ph = img->data_h();
- *Fl_Graphics_Driver::id(img) = (fl_uintptr_t)offs;
-}
-
-
-void Fl_GDI_Graphics_Driver::draw_fixed(Fl_RGB_Image *img, int X, int Y, int W, int H, int cx, int cy) {
- X = this->floor(X);
- Y = this->floor(Y);
- cache_size(img, W, H);
- cx = this->floor(cx); cy = this->floor(cy);
- if (W + cx > img->data_w()) W = img->data_w() - cx;
- if (H + cy > img->data_h()) H = img->data_h() - cy;
- if (!*Fl_Graphics_Driver::id(img)) {
- cache(img);
- }
- if (*Fl_Graphics_Driver::mask(img)) {
- HDC new_gc = CreateCompatibleDC(gc_);
- int save = SaveDC(new_gc);
- SelectObject(new_gc, (void*)*Fl_Graphics_Driver::mask(img));
- BitBlt(gc_, X, Y, W, H, new_gc, cx, cy, SRCAND);
- SelectObject(new_gc, (void*)*Fl_Graphics_Driver::id(img));
- BitBlt(gc_, X, Y, W, H, new_gc, cx, cy, SRCPAINT);
- RestoreDC(new_gc,save);
- DeleteDC(new_gc);
- } else if (img->d()==2 || img->d()==4) {
- copy_offscreen_with_alpha(X, Y, W, H, (HBITMAP)*Fl_Graphics_Driver::id(img), cx, cy);
- } else {
- copy_offscreen(X, Y, W, H, (Fl_Offscreen)*Fl_Graphics_Driver::id(img), cx, cy);
- }
-}
-
-
-void Fl_GDI_Graphics_Driver::draw_rgb(Fl_RGB_Image *rgb, int XP, int YP, int WP, int HP, int cx, int cy) {
- if (Fl_Graphics_Driver::start_image(rgb, XP, YP, WP, HP, cx, cy, XP, YP, WP, HP)) {
- return;
- }
- if ((rgb->d() % 2) == 0 && !fl_can_do_alpha_blending()) {
- Fl_Graphics_Driver::draw_rgb(rgb, XP, YP, WP, HP, cx, cy);
- return;
- }
- if (!*Fl_Graphics_Driver::id(rgb)) {
- cache(rgb);
- }
- push_clip(XP, YP, WP, HP);
- XP -= cx; YP -= cy;
- WP = rgb->w(); HP = rgb->h();
- cache_size(rgb, WP, HP);
- HDC new_gc = CreateCompatibleDC(gc_);
- int save = SaveDC(new_gc);
- SelectObject(new_gc, (HBITMAP)*Fl_Graphics_Driver::id(rgb));
- if ( (rgb->d() % 2) == 0 ) {
- alpha_blend_(this->floor(XP), this->floor(YP), WP, HP, new_gc, 0, 0, rgb->data_w(), rgb->data_h());
- } else {
- SetStretchBltMode(gc_, (Fl_Image::scaling_algorithm() == FL_RGB_SCALING_BILINEAR ? HALFTONE : BLACKONWHITE));
- StretchBlt(gc_, this->floor(XP), this->floor(YP), WP, HP, new_gc, 0, 0, rgb->data_w(), rgb->data_h(), SRCCOPY);
- }
- RestoreDC(new_gc, save);
- DeleteDC(new_gc);
- pop_clip();
-}
-
-
-void Fl_GDI_Printer_Graphics_Driver::draw_rgb(Fl_RGB_Image *rgb, int XP, int YP, int WP, int HP, int cx, int cy) {
- if (Fl_Graphics_Driver::start_image(rgb, XP, YP, WP, HP, cx, cy, XP, YP, WP, HP)) {
- return;
- }
- XFORM old_tr, tr;
- GetWorldTransform(gc_, &old_tr); // storing old transform
- tr.eM11 = float(rgb->w())/float(rgb->data_w());
- tr.eM22 = float(rgb->h())/float(rgb->data_h());
- tr.eM12 = tr.eM21 = 0;
- tr.eDx = float(XP);
- tr.eDy = float(YP);
- ModifyWorldTransform(gc_, &tr, MWT_LEFTMULTIPLY);
- if (*id(rgb)) {
- int *pw, *ph;
- cache_w_h(rgb, pw, ph);
- if ( *pw != rgb->data_w() || *ph != rgb->data_h()) rgb->uncache();
- }
- if (!*id(rgb)) cache(rgb);
- draw_fixed(rgb, 0, 0, int(WP / tr.eM11), int(HP / tr.eM22), int(cx / tr.eM11), int(cy / tr.eM22));
- SetWorldTransform(gc_, &old_tr);
-}
-
-
-void Fl_GDI_Graphics_Driver::uncache(Fl_RGB_Image*, fl_uintptr_t &id_, fl_uintptr_t &mask_)
-{
- if (id_) {
- DeleteObject((HBITMAP)id_);
- id_ = 0;
- }
-
- if (mask_) {
- delete_bitmask(mask_);
- mask_ = 0;
- }
-}
-
-// 'fl_create_bitmap()' - Create a 1-bit bitmap for drawing...
-static HBITMAP fl_create_bitmap(int w, int h, const uchar *data) {
- // we need to pad the lines out to words & swap the bits
- // in each byte.
- int w1 = (w + 7) / 8;
- int w2 = ((w + 15) / 16) * 2;
- uchar* newarray = new uchar[w2*h];
- const uchar* src = data;
- uchar* dest = newarray;
- HBITMAP bm;
- static uchar reverse[16] = /* Bit reversal lookup table */
- { 0x00, 0x88, 0x44, 0xcc, 0x22, 0xaa, 0x66, 0xee,
- 0x11, 0x99, 0x55, 0xdd, 0x33, 0xbb, 0x77, 0xff };
-
- for (int y = 0; y < h; y++) {
- for (int n = 0; n < w1; n++, src++)
- *dest++ = (uchar)((reverse[*src & 0x0f] & 0xf0) |
- (reverse[(*src >> 4) & 0x0f] & 0x0f));
- dest += w2 - w1;
- }
-
- bm = CreateBitmap(w, h, 1, 1, newarray);
-
- delete[] newarray;
-
- return bm;
-}
-
-void Fl_GDI_Graphics_Driver::cache(Fl_Bitmap *bm) {
- int *pw, *ph;
- cache_w_h(bm, pw, ph);
- *pw = bm->data_w();
- *ph = bm->data_h();
- *Fl_Graphics_Driver::id(bm) = (fl_uintptr_t)fl_create_bitmap(bm->data_w(), bm->data_h(), bm->array);
-}
-
-void Fl_GDI_Graphics_Driver::draw_fixed(Fl_Pixmap *pxm, int X, int Y, int W, int H, int cx, int cy) {
- X = this->floor(X);
- Y = this->floor(Y);
- cache_size(pxm, W, H);
- cx = this->floor(cx); cy = this->floor(cy);
- Fl_Region r2 = scale_clip(scale());
- if (*Fl_Graphics_Driver::mask(pxm)) {
- HDC new_gc = CreateCompatibleDC(gc_);
- int save = SaveDC(new_gc);
- SelectObject(new_gc, (void*)*Fl_Graphics_Driver::mask(pxm));
- BitBlt(gc_, X, Y, W, H, new_gc, cx, cy, SRCAND);
- SelectObject(new_gc, (void*)*Fl_Graphics_Driver::id(pxm));
- BitBlt(gc_, X, Y, W, H, new_gc, cx, cy, SRCPAINT);
- RestoreDC(new_gc,save);
- DeleteDC(new_gc);
- } else {
- float s = scale(); Fl_Graphics_Driver::scale(1);
- copy_offscreen(X, Y, W, H, (Fl_Offscreen)*Fl_Graphics_Driver::id(pxm), cx, cy);
- Fl_Graphics_Driver::scale(s);
- }
- unscale_clip(r2);
-}
-
-/* ===== Implementation note about how Fl_Pixmap objects get printed under Windows =====
- Fl_Pixmap objects are printed with the print-specific Fl_GDI_Printer_Graphics_Driver
- which uses the TransparentBlt() system function that can scale the image and treat one
- of its colors as transparent.
- Fl_GDI_Printer_Graphics_Driver::draw_pixmap(Fl_Pixmap *,...) sets need_pixmap_bg_color,
- a static class variable, to 1 and recaches the image. This calls fl_convert_pixmap()
- that checks the value of need_pixmap_bg_color. When this value is not 0, fl_convert_pixmap
- runs in a way that memorizes the list of all colors in the pixmap, computes
- a color absent from this list, uses it for the transparent pixels of the pixmap and puts
- this color value in need_pixmap_bg_color. As a result, the transparent areas of the image
- are correcty handled by the printing operation. Variable need_pixmap_bg_color is ultimately
- reset to 0.
- Fl_GDI_Graphics_Driver::make_unused_color_() which does the color computation mentioned
- above is implemented in file src/fl_draw_pixmap.cxx
- */
-void Fl_GDI_Printer_Graphics_Driver::draw_pixmap(Fl_Pixmap *pxm, int XP, int YP, int WP, int HP, int cx, int cy) {
- int X, Y, W, H;
- if (start_image(pxm, XP, YP, WP, HP, cx, cy, X, Y, W, H)) return;
- transparent_f_type fl_TransparentBlt = TransparentBlt();
- if (fl_TransparentBlt) {
- need_pixmap_bg_color = 1;
- pxm->uncache();
- cache(pxm);
- HDC new_gc = CreateCompatibleDC(gc_);
- int save = SaveDC(new_gc);
- SelectObject(new_gc, (void*)*Fl_Graphics_Driver::id(pxm));
- // print all of offscreen but its parts in background color
- float scaleW = pxm->data_w()/float(pxm->w());
- float scaleH = pxm->data_h()/float(pxm->h());
- fl_TransparentBlt(gc_, X, Y, W, H, new_gc,
- int(cx * scaleW), int(cy * scaleH), int(W * scaleW), int(H * scaleH), need_pixmap_bg_color );
- RestoreDC(new_gc,save);
- DeleteDC(new_gc);
- need_pixmap_bg_color = 0;
- }
- else {
- copy_offscreen(X, Y, W, H, (Fl_Offscreen)*Fl_Graphics_Driver::id(pxm), cx, cy);
- }
-}
-
-// Makes an RGB triplet different from all the colors used in the pixmap
-// and computes Fl_Graphics_Driver::need_pixmap_bg_color from this triplet
-void Fl_GDI_Graphics_Driver::make_unused_color_(uchar &r, uchar &g, uchar &b, int color_count, void **data) {
- typedef struct { uchar r; uchar g; uchar b; } UsedColor;
- UsedColor *used_colors = *(UsedColor**)data;
- int i;
- r = 2; g = 3; b = 4;
- while (1) {
- for ( i=0; i<color_count; i++ )
- if ( used_colors[i].r == r &&
- used_colors[i].g == g &&
- used_colors[i].b == b )
- break;
- if (i >= color_count) {
- free((void*)used_colors);
- *(UsedColor**)data = NULL;
- need_pixmap_bg_color = RGB(r, g, b);
- return;
- }
- if (r < 255) {
- r++;
- } else {
- r = 0;
- if (g < 255) {
- g++;
- } else {
- g = 0;
- b++;
- }
- }
- }
-}
-
-void Fl_GDI_Graphics_Driver::cache(Fl_Pixmap *img) {
- Fl_Image_Surface *surf = new Fl_Image_Surface(img->data_w(), img->data_h());
- Fl_Surface_Device::push_current(surf);
- uchar **pbitmap = surf->driver()->mask_bitmap();
- *pbitmap = (uchar*)1;// will instruct fl_draw_pixmap() to compute the image's mask
- fl_draw_pixmap(img->data(), 0, 0, FL_BLACK);
- uchar *bitmap = *pbitmap;
- if (bitmap) {
- *Fl_Graphics_Driver::mask(img) =
- (fl_uintptr_t)create_bitmask(img->data_w(), img->data_h(), bitmap);
- delete[] bitmap;
- }
- *pbitmap = 0;
- Fl_Surface_Device::pop_current();
- Fl_Offscreen id = Fl_Graphics_Driver::get_offscreen_and_delete_image_surface(surf);
- int *pw, *ph;
- cache_w_h(img, pw, ph);
- *pw = img->data_w();
- *ph = img->data_h();
- *Fl_Graphics_Driver::id(img) = (fl_uintptr_t)id;
-}
-
-void Fl_GDI_Graphics_Driver::uncache_pixmap(fl_uintptr_t offscreen) {
- DeleteObject((HBITMAP)offscreen);
-}
diff --git a/src/drivers/GDI/Fl_GDI_Graphics_Driver_line_style.cxx b/src/drivers/GDI/Fl_GDI_Graphics_Driver_line_style.cxx
deleted file mode 100644
index 9d086f353..000000000
--- a/src/drivers/GDI/Fl_GDI_Graphics_Driver_line_style.cxx
+++ /dev/null
@@ -1,111 +0,0 @@
-//
-// Line style code 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:
-//
-// https://www.fltk.org/COPYING.php
-//
-// Please see the following page on how to report bugs and issues:
-//
-// https://www.fltk.org/bugs.php
-//
-
-/**
- \file Fl_GDI_Graphics_Driver_line_style.cxx
-
- \brief Line style drawing utility for Windows (GDI) platform.
-*/
-
-#include <FL/Fl.H>
-#include <FL/platform.H>
-#include <FL/fl_draw.H>
-
-#include "Fl_GDI_Graphics_Driver.H"
-
-
-void Fl_GDI_Graphics_Driver::line_style_unscaled(int style, int width, char* dashes) {
-
- // According to Bill, the "default" cap and join should be the
- // "fastest" mode supported for the platform. I don't know why
- // they should be different (same graphics cards, etc., right?) MRS
-
- static const DWORD Cap[4] = {PS_ENDCAP_FLAT, PS_ENDCAP_FLAT, PS_ENDCAP_ROUND, PS_ENDCAP_SQUARE};
- static const DWORD Join[4] = {PS_JOIN_ROUND, PS_JOIN_MITER, PS_JOIN_ROUND, PS_JOIN_BEVEL};
-
- int s1 = PS_GEOMETRIC | Cap[(style>>8)&3] | Join[(style>>12)&3];
- DWORD a[16];
- int n = 0;
- if (dashes && dashes[0]) {
- s1 |= PS_USERSTYLE;
- for (n = 0; n < 16 && *dashes; n++) a[n] = *dashes++;
- } else {
- s1 |= style & 0xff; // allow them to pass any low 8 bits for style
- }
- if ((style || n) && !width) width = int(scale()); // fix cards that do nothing for 0?
- if (!width) width = 1;
- if (!fl_current_xmap) color(FL_BLACK);
- LOGBRUSH penbrush = {BS_SOLID,fl_RGB(),0}; // can this be fl_brush()?
- HPEN newpen = ExtCreatePen(s1, width, &penbrush, n, n ? a : 0);
- if (!newpen) {
- Fl::error("fl_line_style(): Could not create GDI pen object.");
- return;
- }
- HPEN oldpen = (HPEN)SelectObject(gc_, newpen);
- DeleteObject(oldpen);
- DeleteObject(fl_current_xmap->pen);
- fl_current_xmap->pen = newpen;
- style_ = style;
-}
-
-#if USE_GDIPLUS
-
-void Fl_GDIplus_Graphics_Driver::line_style(int style, int width, char* dashes) {
- if (!active) return Fl_Scalable_Graphics_Driver::line_style(style, width, dashes);
- int gdi_width = (width ? width : 1);
- pen_->SetWidth(Gdiplus::REAL(gdi_width));
- int standard_dash = style & 0x7;
- if (standard_dash == FL_DASH )
- pen_->SetDashStyle(Gdiplus::DashStyleDash);
- else if (standard_dash == FL_DOT )
- pen_->SetDashStyle(Gdiplus::DashStyleDot);
- else if (standard_dash == FL_DASHDOT )
- pen_->SetDashStyle(Gdiplus::DashStyleDashDot);
- else if (standard_dash == FL_DASHDOTDOT )
- pen_->SetDashStyle(Gdiplus::DashStyleDashDotDot);
- else if(!dashes || !*dashes)
- pen_->SetDashStyle(Gdiplus::DashStyleSolid);
-
- if (style & FL_CAP_ROUND ) {
- pen_->SetStartCap(Gdiplus::LineCapRound);
- pen_->SetEndCap(Gdiplus::LineCapRound);
- } else if (style & FL_CAP_SQUARE ) {
- pen_->SetStartCap(Gdiplus::LineCapSquare);
- pen_->SetEndCap(Gdiplus::LineCapSquare);
- } else {
- pen_->SetStartCap(Gdiplus::LineCapFlat);
- pen_->SetEndCap(Gdiplus::LineCapFlat);
- }
-
- if (style & FL_JOIN_MITER ) {
- pen_->SetLineJoin(Gdiplus::LineJoinMiter);
- } else if (style & FL_JOIN_BEVEL ) {
- pen_->SetLineJoin(Gdiplus::LineJoinBevel);
- } else {
- pen_->SetLineJoin(Gdiplus::LineJoinRound);
- }
-
- if (dashes && *dashes) {
- int n = 0; while (dashes[n]) n++;
- Gdiplus::REAL *gdi_dashes = new Gdiplus::REAL[n];
- for (int i = 0; i < n; i++) gdi_dashes[i] = dashes[i]/float(gdi_width);
- pen_->SetDashPattern(gdi_dashes, n);
- delete[] gdi_dashes;
- }
- Fl_Scalable_Graphics_Driver::line_style(style, width, dashes);
-}
-
-#endif
diff --git a/src/drivers/GDI/Fl_GDI_Graphics_Driver_rect.cxx b/src/drivers/GDI/Fl_GDI_Graphics_Driver_rect.cxx
deleted file mode 100644
index a86242e12..000000000
--- a/src/drivers/GDI/Fl_GDI_Graphics_Driver_rect.cxx
+++ /dev/null
@@ -1,320 +0,0 @@
-//
-// Rectangle drawing routines 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:
-//
-// https://www.fltk.org/COPYING.php
-//
-// Please see the following page on how to report bugs and issues:
-//
-// https://www.fltk.org/bugs.php
-//
-
-
-/**
- \file Fl_GDI_Graphics_Driver_rect.cxx
- \brief Windows GDI specific line and polygon drawing with integer coordinates.
- */
-
-#include <config.h>
-#include <FL/Fl.H>
-#include <FL/Fl_Widget.H>
-#include <FL/fl_draw.H>
-#include <FL/platform.H>
-
-#include "Fl_GDI_Graphics_Driver.H"
-
-
-// --- line and polygon drawing with integer coordinates
-
-void Fl_GDI_Graphics_Driver::point(int x, int y) {
- rectf(x, y, 1, 1);
-}
-
-void Fl_GDI_Graphics_Driver::overlay_rect(int x, int y, int w , int h) {
- // make pen have a one-pixel width
- line_style_unscaled( (color()==FL_WHITE?FL_SOLID:FL_DOT), 1, NULL);
- int right = this->floor(x+w-1), bottom = this->floor(y+h-1);
- x = this->floor(x); y = this->floor(y);
- MoveToEx(gc_, x, y, 0L);
- LineTo(gc_, right, y);
- LineTo(gc_, right, bottom);
- LineTo(gc_, x, bottom);
- LineTo(gc_, x, y);
-}
-
-void Fl_GDI_Graphics_Driver::focus_rect(int x, int y, int w, int h) {
- // Windows 95/98/ME do not implement the dotted line style, so draw
- // every other pixel around the focus area...
- w = floor(x+w-1) - floor(x) + 1;
- h = floor(y+h-1) - floor(y) + 1;
- x = floor(x); y = floor(y);
- int i=1, xx, yy;
- COLORREF c = fl_RGB();
- for (xx = 0; xx < w; xx++, i++) if (i & 1) SetPixel(gc_, x+xx, y, c);
- for (yy = 0; yy < h; yy++, i++) if (i & 1) SetPixel(gc_, x+w, y+yy, c);
- for (xx = w; xx > 0; xx--, i++) if (i & 1) SetPixel(gc_, x+xx, y+h, c);
- for (yy = h; yy > 0; yy--, i++) if (i & 1) SetPixel(gc_, x, y+yy, c);
-}
-
-void Fl_GDI_Graphics_Driver::rect_unscaled(int x, int y, int w, int h) {
- if (is_solid_ && line_width_ > 1) {
- line_style_unscaled(FL_CAP_SQUARE, line_width_, 0); // see issue #1052
- }
- MoveToEx(gc_, x, y, 0L);
- LineTo(gc_, x+w, y);
- if (is_solid_ && line_width_ <= 1) LineTo(gc_, x+w, y+h+1); // see issue #1052
- LineTo(gc_, x+w, y+h);
- LineTo(gc_, x, y+h);
- LineTo(gc_, x, y);
- if (is_solid_ && line_width_ > 1) {
- line_style_unscaled(style_, line_width_, 0);
- }
-}
-
-void Fl_GDI_Graphics_Driver::rectf_unscaled(int x, int y, int w, int h) {
- RECT rect;
- rect.left = x; rect.top = y;
- rect.right = (x + w); rect.bottom = (y + h);
- FillRect(gc_, &rect, fl_brush());
-}
-
-void Fl_GDI_Graphics_Driver::line_unscaled(int x, int y, int x1, int y1) {
- MoveToEx(gc_, x, y, 0L);
- LineTo(gc_, x1, y1);
- SetPixel(gc_, x1, y1, fl_RGB());
-}
-
-void Fl_GDI_Graphics_Driver::line_unscaled(int x, int y, int x1, int y1, int x2, int y2) {
- MoveToEx(gc_, x, y, 0L);
- LineTo(gc_, x1, y1);
- LineTo(gc_, x2, y2);
- SetPixel(gc_, x2, y2, fl_RGB());
-}
-
-void* Fl_GDI_Graphics_Driver::change_pen_width(int width) { // set the width of the pen, return previous pen
- LOGBRUSH penbrush = {BS_SOLID, fl_RGB(), 0};
- HPEN newpen = ExtCreatePen(PS_GEOMETRIC | PS_ENDCAP_FLAT | PS_JOIN_ROUND, width, &penbrush, 0, 0);
- return SelectObject(gc_, newpen);
-}
-
-void Fl_GDI_Graphics_Driver::reset_pen_width(void *data) {
- DeleteObject(SelectObject(gc_, (HPEN)data));
-}
-
-void Fl_GDI_Graphics_Driver::xyline_unscaled(int x, int y, int x1) {
- MoveToEx(gc_, x, y, 0L);
- LineTo(gc_, x1+1 , y);
-}
-
-void Fl_GDI_Graphics_Driver::yxline_unscaled(int x, int y, int y1) {
- MoveToEx(gc_, x, y, 0L);
- LineTo(gc_, x, y1+1);
-}
-
-void Fl_GDI_Graphics_Driver::loop_unscaled(int x, int y, int x1, int y1, int x2, int y2) {
- MoveToEx(gc_, x, y, 0L);
- LineTo(gc_, x1, y1);
- LineTo(gc_, x2, y2);
- LineTo(gc_, x, y);
-}
-
-void Fl_GDI_Graphics_Driver::loop_unscaled(int x, int y, int x1, int y1, int x2, int y2, int x3, int y3) {
- MoveToEx(gc_, x, y, 0L);
- LineTo(gc_, x1, y1);
- LineTo(gc_, x2, y2);
- LineTo(gc_, x3, y3);
- LineTo(gc_, x, y);
-}
-
-void Fl_GDI_Graphics_Driver::polygon_unscaled(int x, int y, int x1, int y1, int x2, int y2) {
- POINT p[3];
- p[0].x = x; p[0].y = y;
- p[1].x = x1; p[1].y = y1;
- p[2].x = x2; p[2].y = y2;
- SelectObject(gc_, fl_brush());
- Polygon(gc_, p, 3);
-}
-
-void Fl_GDI_Graphics_Driver::polygon_unscaled(int x, int y, int x1, int y1, int x2, int y2, int x3, int y3) {
- POINT p[4];
- p[0].x = x; p[0].y = y;
- p[1].x = x1; p[1].y = y1;
- p[2].x = x2; p[2].y = y2;
- p[3].x = x3; p[3].y = y3;
- SelectObject(gc_, fl_brush());
- Polygon(gc_, p, 4);
-}
-
-// --- clipping
-
-void Fl_GDI_Graphics_Driver::push_clip(int x, int y, int w, int h) {
- HRGN r;
- if (w > 0 && h > 0) {
- r = (HRGN)XRectangleRegion(x,y,w,h);
- HRGN current = (HRGN)rstack[rstackptr];
- if (current) {
- CombineRgn(r,r,current,RGN_AND);
- }
- } else { // make empty clip region:
- r = CreateRectRgn(0,0,0,0);
- }
- if (rstackptr < region_stack_max) rstack[++rstackptr] = r;
- else Fl::warning("Fl_GDI_Graphics_Driver::push_clip: clip stack overflow!\n");
- fl_restore_clip();
-}
-
-int Fl_GDI_Graphics_Driver::clip_box(int x, int y, int w, int h, int& X, int& Y, int& W, int& H){
- X = x; Y = y; W = w; H = h;
- HRGN r = (HRGN)rstack[rstackptr];
- if (!r) return 0;
- // The win32 API makes no distinction between partial and complete
- // intersection, so we have to check for partial intersection ourselves.
- // However, given that the regions may be composite, we have to do
- // some voodoo stuff...
- HRGN rr = (HRGN)XRectangleRegion(x,y,w,h);
- HRGN temp = CreateRectRgn(0,0,0,0);
- int ret;
- if (CombineRgn(temp, rr, r, RGN_AND) == NULLREGION) { // disjoint
- W = H = 0;
- ret = 2;
- } else if (EqualRgn(temp, rr)) { // complete
- ret = 0;
- } else { // partial intersection
- RECT rect;
- GetRgnBox(temp, &rect);
- if (Fl_Surface_Device::surface() != Fl_Display_Device::display_device()) { // if print context, convert coords from device to logical
- POINT pt[2] = { {rect.left, rect.top}, {rect.right, rect.bottom} };
- DPtoLP(gc_, pt, 2);
- X = pt[0].x; Y = pt[0].y; W = pt[1].x - X; H = pt[1].y - Y;
- }
- else {
- X = rect.left; Y = rect.top; W = rect.right - X; H = rect.bottom - Y;
- }
- ret = 1;
- }
- DeleteObject(temp);
- DeleteObject(rr);
- return ret;
-}
-
-int Fl_GDI_Graphics_Driver::not_clipped(int x, int y, int w, int h) {
- if (x+w <= 0 || y+h <= 0) return 0;
- HRGN r = (HRGN)rstack[rstackptr];
- if (!r) return 1;
- RECT rect;
- if (Fl_Surface_Device::surface() != Fl_Display_Device::display_device()) { // in case of print context, convert coords from logical to device
- POINT pt[2] = { {x, y}, {x + w, y + h} };
- LPtoDP(gc_, pt, 2);
- rect.left = pt[0].x; rect.top = pt[0].y; rect.right = pt[1].x; rect.bottom = pt[1].y;
- } else {
- rect.left = x; rect.top = y; rect.right = x+w; rect.bottom = y+h;
- }
- return RectInRegion(r,&rect);
-}
-
-void Fl_GDI_Graphics_Driver::restore_clip() {
- fl_clip_state_number++;
- if (gc_) {
- HRGN r = NULL;
- if (rstack[rstackptr]) r = (HRGN)scale_clip(scale());
- SelectClipRgn(gc_, (HRGN)rstack[rstackptr]); // if region is NULL, clip is automatically cleared
- if (r) unscale_clip(r);
- }
-}
-
-#if USE_GDIPLUS
-
-void Fl_GDIplus_Graphics_Driver::line(int x, int y, int x1, int y1) {
- if (!active) return Fl_Scalable_Graphics_Driver::line(x, y, x1, y1);
- bool AA = !(x == x1 || y == y1);
- Gdiplus::Graphics graphics_(gc_);
- graphics_.ScaleTransform(scale(), scale());
- pen_->SetColor(gdiplus_color_);
- if (AA) graphics_.SetSmoothingMode(Gdiplus::SmoothingModeAntiAlias);
- graphics_.DrawLine(pen_, x, y, x1, y1);
-}
-
-void Fl_GDIplus_Graphics_Driver::line(int x, int y, int x1, int y1, int x2, int y2) {
- if (!active) return Fl_Scalable_Graphics_Driver::line(x, y, x1, y1, x2, y2);
- line(x, y, x1, y1);
- line(x1, y1, x2, y2);
-}
-
-void Fl_GDIplus_Graphics_Driver::loop(int x0, int y0, int x1, int y1, int x2, int y2) {
- if (!active) return Fl_Scalable_Graphics_Driver::loop(x0, y0, x1, y1, x2, y2);
- Gdiplus::GraphicsPath path;
- Gdiplus::Point gdi2_p[3] = {Gdiplus::Point(x0, y0), Gdiplus::Point(x1, y1), Gdiplus::Point(x2, y2)};
- path.AddLines(gdi2_p, 3);
- path.CloseFigure();
- Gdiplus::Graphics graphics_(gc_);
- graphics_.ScaleTransform(scale(), scale());
- pen_->SetColor(gdiplus_color_);
- graphics_.SetSmoothingMode(Gdiplus::SmoothingModeAntiAlias);
- graphics_.DrawPath(pen_, &path);
-}
-
-#define fl_min(a,b) (a < b ? a : b)
-#define fl_max(a,b) (a > b ? a : b)
-void Fl_GDIplus_Graphics_Driver::loop(int x0, int y0, int x1, int y1, int x2, int y2, int x3, int y3) {
- if ( (x0 == x3 && x1 == x2 && y0 == y1 && y3 == y2) ||
- (x0 == x1 && y1 == y2 && x2 == x3 && y3 == y0) ) { // rectangular loop
- int left = fl_min(x0, fl_min(x1, fl_min(x2, x3)));
- int right = fl_max(x0, fl_max(x1, fl_max(x2, x3)));
- int top = fl_min(y0, fl_min(y1, fl_min(y2, y3)));
- int bottom = fl_max(y0, fl_max(y1, fl_max(y2, y3)));
- rect(left, top, right-left+1, bottom-top+1);
- } else {
- if (!active) return Fl_Scalable_Graphics_Driver::loop(x0, y0, x1, y1, x2, y2, x3, y3);
- Gdiplus::GraphicsPath path;
- Gdiplus::PointF gdi2_p[4] = {Gdiplus::PointF(x0+1-line_width_/2.f, y0+1-line_width_/2.f), Gdiplus::PointF(x1+1-line_width_/2.f, y1+1-line_width_/2.f), Gdiplus::PointF(x2+1-line_width_/2.f, y2+1-line_width_/2.f), Gdiplus::PointF(x3+1-line_width_/2.f, y3+1-line_width_/2.f)};
- path.AddLines(gdi2_p, 4);
- path.CloseFigure();
- Gdiplus::Graphics graphics_(gc_);
- graphics_.ScaleTransform(scale(), scale());
- pen_->SetColor(gdiplus_color_);
- graphics_.SetSmoothingMode(Gdiplus::SmoothingModeAntiAlias);
- graphics_.DrawPath(pen_, &path);
- }
-}
-
-void Fl_GDIplus_Graphics_Driver::polygon(int x0, int y0, int x1, int y1, int x2, int y2) {
- if (!active) return Fl_Scalable_Graphics_Driver::polygon(x0, y0, x1, y1, x2, y2);
- Gdiplus::GraphicsPath path;
- path.AddLine(x0, y0, x1, y1);
- path.AddLine(x1, y1, x2, y2);
- path.CloseFigure();
- Gdiplus::Graphics graphics_(gc_);
- graphics_.ScaleTransform(scale(), scale());
- brush_->SetColor(gdiplus_color_);
- graphics_.SetSmoothingMode(Gdiplus::SmoothingModeAntiAlias);
- graphics_.FillPath(brush_, &path);
-}
-
-void Fl_GDIplus_Graphics_Driver::polygon(int x0, int y0, int x1, int y1, int x2, int y2, int x3, int y3) {
- if ( (x0 == x3 && x1 == x2 && y0 == y1 && y3 == y2) ||
- (x0 == x1 && y1 == y2 && x2 == x3 && y3 == y0) ) {
- int left = fl_min(x0, fl_min(x1, fl_min(x2, x3)));
- int right = fl_max(x0, fl_max(x1, fl_max(x2, x3)));
- int top = fl_min(y0, fl_min(y1, fl_min(y2, y3)));
- int bottom = fl_max(y0, fl_max(y1, fl_max(y2, y3)));
- rectf(left, top, right-left, bottom-top);
- } else {
- if (!active) return Fl_Scalable_Graphics_Driver::polygon(x0, y0, x1, y1, x2, y2, x3, y3);
- Gdiplus::GraphicsPath path;
- path.AddLine(x0, y0, x1, y1);
- path.AddLine(x1, y1, x2, y2);
- path.AddLine(x2, y2, x3, y3);
- path.CloseFigure();
- Gdiplus::Graphics graphics_(gc_);
- graphics_.ScaleTransform(scale(), scale());
- brush_->SetColor(gdiplus_color_);
- graphics_.SetSmoothingMode(Gdiplus::SmoothingModeAntiAlias);
- graphics_.FillPath(brush_, &path);
- }
-}
-#endif
diff --git a/src/drivers/GDI/Fl_GDI_Graphics_Driver_vertex.cxx b/src/drivers/GDI/Fl_GDI_Graphics_Driver_vertex.cxx
deleted file mode 100644
index e469bb11b..000000000
--- a/src/drivers/GDI/Fl_GDI_Graphics_Driver_vertex.cxx
+++ /dev/null
@@ -1,231 +0,0 @@
-//
-// Portable drawing routines 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:
-//
-// https://www.fltk.org/COPYING.php
-//
-// Please see the following page on how to report bugs and issues:
-//
-// https://www.fltk.org/bugs.php
-//
-
-/**
- \file Fl_GDI_Graphics_Driver_vertex.cxx
-
- \brief Portable drawing code for drawing arbitrary shapes with
- simple 2D transformations, implemented for Windows GDI.
-*/
-
-#include "Fl_GDI_Graphics_Driver.H"
-
-#include <FL/fl_draw.H>
-#include <FL/platform.H>
-#include <FL/math.h>
-
-
-void Fl_GDI_Graphics_Driver::end_points() {
- for (int i=0; i<n; i++) SetPixel(gc_, long_point[i].x, long_point[i].y, fl_RGB());
-}
-
-void Fl_GDI_Graphics_Driver::end_line() {
- if (n < 2) {
- end_points();
- return;
- }
- if (n>1) Polyline(gc_, long_point, n);
-}
-
-void Fl_GDI_Graphics_Driver::end_loop() {
- fixloop();
- if (n>2) transformed_vertex0(float(long_point[0].x), float(long_point[0].y));
- end_line();
-}
-
-void Fl_GDI_Graphics_Driver::end_polygon() {
- fixloop();
- if (n < 3) {
- end_line();
- return;
- }
- if (n>2) {
- SelectObject(gc_, fl_brush());
- Polygon(gc_, long_point, n);
- }
-}
-
-void Fl_GDI_Graphics_Driver::begin_complex_polygon() {
- Fl_Graphics_Driver::begin_complex_polygon();
- numcount = 0;
-}
-
-void Fl_GDI_Graphics_Driver::gap() {
- while (n>gap_+2 && long_point[n-1].x == long_point[gap_].x && long_point[n-1].y == long_point[gap_].y) n--;
- if (n > gap_+2) {
- transformed_vertex0(float(long_point[gap_].x), float(long_point[gap_].y));
- counts[numcount++] = n-gap_;
- gap_ = n;
- } else {
- n = gap_;
- }
-}
-
-void Fl_GDI_Graphics_Driver::end_complex_polygon() {
- gap();
- if (n < 3) {
- end_line();
- return;
- }
- if (n>2) {
- SelectObject(gc_, fl_brush());
- PolyPolygon(gc_, long_point, counts, numcount);
- }
-}
-
-void Fl_GDI_Graphics_Driver::ellipse_unscaled(double xt, double yt, double rx, double ry) {
- int llx = (int)rint(xt-rx);
- int w = (int)rint(xt+rx)-llx;
- int lly = (int)rint(yt-ry);
- int h = (int)rint(yt+ry)-lly;
-
- if (what==POLYGON) {
- SelectObject(gc_, fl_brush());
- Pie(gc_, llx, lly, llx+w, lly+h, 0,0, 0,0);
- } else
- Arc(gc_, llx, lly, llx+w, lly+h, 0,0, 0,0);
-}
-
-#if USE_GDIPLUS
-
-void Fl_GDIplus_Graphics_Driver::transformed_vertex(double xf, double yf) {
- if (!active) return Fl_Scalable_Graphics_Driver::transformed_vertex(xf, yf);
- transformed_vertex0(float(xf) , float(yf) );
-}
-
-void Fl_GDIplus_Graphics_Driver::vertex(double x,double y) {
- if (!active) return Fl_Scalable_Graphics_Driver::vertex(x, y);
- transformed_vertex0(float(x*m.a + y*m.c + m.x) , float(x*m.b + y*m.d + m.y) );
-}
-
-void Fl_GDIplus_Graphics_Driver::end_points() {
- if (!active) return Fl_GDI_Graphics_Driver::end_points();
- for (int i = 0; i < n; i++) point(long_point[i].x, long_point[i].y);
-}
-
-void Fl_GDIplus_Graphics_Driver::end_line() {
- if (!active) return Fl_GDI_Graphics_Driver::end_line();
- if (n < 2) {
- end_points();
- return;
- }
- if (n>1) {
- Gdiplus::GraphicsPath path;
- Gdiplus::Point *gdi2_p = new Gdiplus::Point[n];
- for (int i = 0; i < n; i++) {
- gdi2_p[i] = Gdiplus::Point(long_point[i].x, long_point[i].y);
- }
- path.AddLines(gdi2_p, n);
- delete[] gdi2_p;
- Gdiplus::Graphics graphics_(gc_);
- graphics_.ScaleTransform(scale(), scale());
- graphics_.SetSmoothingMode(Gdiplus::SmoothingModeAntiAlias);
- pen_->SetColor(gdiplus_color_);
- graphics_.DrawPath(pen_, &path);
- }
-}
-
-void Fl_GDIplus_Graphics_Driver::end_loop() {
- if (!active) return Fl_GDI_Graphics_Driver::end_loop();
- fixloop();
- if (n >= 2) {
- Gdiplus::GraphicsPath path;
- Gdiplus::Point *gdi2_p = new Gdiplus::Point[n];
- for (int i = 0; i < n; i++) {
- gdi2_p[i] = Gdiplus::Point(long_point[i].x, long_point[i].y);
- }
- path.AddLines(gdi2_p, n);
- path.CloseFigure();
- delete[] gdi2_p;
- Gdiplus::Graphics graphics_(gc_);
- graphics_.ScaleTransform(scale(), scale());
- graphics_.SetSmoothingMode(Gdiplus::SmoothingModeAntiAlias);
- pen_->SetColor(gdiplus_color_);
- graphics_.DrawPath(pen_, &path);
- }
-}
-
-void Fl_GDIplus_Graphics_Driver::end_polygon() {
- if (!active) return Fl_GDI_Graphics_Driver::end_polygon();
- fixloop();
- if (n < 3) {
- end_line();
- return;
- }
- if (n>2) {
- Gdiplus::GraphicsPath path;
- Gdiplus::Point *gdi2_p = new Gdiplus::Point[n];
- for (int i = 0; i < n; i++) {
- gdi2_p[i] = Gdiplus::Point(long_point[i].x, long_point[i].y);
- }
- path.AddPolygon(gdi2_p, n);
- delete[] gdi2_p;
- path.CloseFigure();
- Gdiplus::Graphics graphics_(gc_);
- graphics_.ScaleTransform(scale(), scale());
- graphics_.SetSmoothingMode(Gdiplus::SmoothingModeAntiAlias);
- brush_->SetColor(gdiplus_color_);
- graphics_.FillPath(brush_, &path);
- }
-}
-
-void Fl_GDIplus_Graphics_Driver::end_complex_polygon() {
- if (!active) return Fl_GDI_Graphics_Driver::end_complex_polygon();
- gap();
- if (n < 3) {
- end_line();
- return;
- }
- if (n>2) {
- Gdiplus::GraphicsPath path;
- Gdiplus::Point *gdi2_p = new Gdiplus::Point[n];
- for (int i = 0; i < n; i++) {
- gdi2_p[i] = Gdiplus::Point(long_point[i].x, long_point[i].y);
- }
- path.AddPolygon(gdi2_p, n);
- delete[] gdi2_p;
- path.CloseFigure();
- Gdiplus::Graphics graphics_(gc_);
- graphics_.ScaleTransform(scale(), scale());
- graphics_.SetSmoothingMode(Gdiplus::SmoothingModeAntiAlias);
- brush_->SetColor(gdiplus_color_);
- graphics_.FillPath(brush_, &path);
- }
-}
-
-void Fl_GDIplus_Graphics_Driver::circle(double x, double y, double r) {
- if (!active) return Fl_Scalable_Graphics_Driver::circle(x, y, r);
- double xt = transform_x(x,y);
- double yt = transform_y(x,y);
- double rx = r * (m.c ? sqrt(m.a*m.a+m.c*m.c) : fabs(m.a));
- double ry = r * (m.b ? sqrt(m.b*m.b+m.d*m.d) : fabs(m.d));
- int llx = (int)rint(xt-rx);
- int w = (int)rint(xt+rx)-llx;
- int lly = (int)rint(yt-ry);
- int h = (int)rint(yt+ry)-lly;
- Gdiplus::Graphics graphics_(gc_);
- graphics_.ScaleTransform(scale(), scale());
- graphics_.SetSmoothingMode(Gdiplus::SmoothingModeAntiAlias);
- if (what==POLYGON) {
- brush_->SetColor(gdiplus_color_);
- graphics_.FillPie(brush_, llx, lly, w, h, 0, 360);
- } else {
- pen_->SetColor(gdiplus_color_);
- graphics_.DrawArc(pen_, llx, lly, w, h, 0, 360);
- }
-}
-#endif
-
diff --git a/src/drivers/GDI/Fl_GDI_Image_Surface_Driver.H b/src/drivers/GDI/Fl_GDI_Image_Surface_Driver.H
deleted file mode 100644
index 129a4ecbc..000000000
--- a/src/drivers/GDI/Fl_GDI_Image_Surface_Driver.H
+++ /dev/null
@@ -1,44 +0,0 @@
-//
-// Draw-to-image code for the Fast Light Tool Kit (FLTK).
-//
-// Copyright 2022 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:
-//
-// https://www.fltk.org/COPYING.php
-//
-// Please see the following page on how to report bugs and issues:
-//
-// https://www.fltk.org/bugs.php
-//
-
-#ifndef FL_GDI_IMAGE_SURFACE_DRIVER_H
-#define FL_GDI_IMAGE_SURFACE_DRIVER_H
-
-#include <FL/Fl_Image_Surface.H>
-#include <FL/Fl_RGB_Image.H>
-#include <FL/platform.H>
-
-class Fl_GDI_Image_Surface_Driver : public Fl_Image_Surface_Driver {
- void end_current() FL_OVERRIDE;
-public:
- HWND pre_window;
- int _savedc;
- void mask(const Fl_RGB_Image *) FL_OVERRIDE;
- struct shape_data_type {
- HBITMAP background;
- uchar *vBits;
- Fl_RGB_Image* mask;
- } *shape_data_;
- Fl_GDI_Image_Surface_Driver(int w, int h, int high_res, Fl_Offscreen off);
- ~Fl_GDI_Image_Surface_Driver();
- void set_current() FL_OVERRIDE;
- void translate(int x, int y) FL_OVERRIDE;
- void untranslate() FL_OVERRIDE;
- Fl_RGB_Image *image() FL_OVERRIDE;
- POINT origin;
-};
-
-#endif // FL_GDI_IMAGE_SURFACE_DRIVER_H
diff --git a/src/drivers/GDI/Fl_GDI_Image_Surface_Driver.cxx b/src/drivers/GDI/Fl_GDI_Image_Surface_Driver.cxx
deleted file mode 100644
index a14524ee2..000000000
--- a/src/drivers/GDI/Fl_GDI_Image_Surface_Driver.cxx
+++ /dev/null
@@ -1,169 +0,0 @@
-//
-// Draw-to-image code 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:
-//
-// https://www.fltk.org/COPYING.php
-//
-// Please see the following page on how to report bugs and issues:
-//
-// https://www.fltk.org/bugs.php
-//
-
-
-#include "Fl_GDI_Graphics_Driver.H"
-#include "../WinAPI/Fl_WinAPI_Screen_Driver.H"
-#include "Fl_GDI_Image_Surface_Driver.H"
-#include <FL/platform.H>
-#include <FL/Fl_Bitmap.H>
-#include <windows.h>
-
-
-Fl_GDI_Image_Surface_Driver::Fl_GDI_Image_Surface_Driver(int w, int h, int high_res, Fl_Offscreen off) : Fl_Image_Surface_Driver(w, h, high_res, off) {
- Fl_Display_Device::display_device(); // make sure fl_graphics_driver was initialized
- float d = fl_graphics_driver->scale();
- if (!off && d != 1 && high_res) {
- w = int(w*d);
- h = int(h*d);
- }
- HDC gc = (HDC)Fl_Graphics_Driver::default_driver().gc();
- offscreen = off ? off : (Fl_Offscreen)CreateCompatibleBitmap( (gc ? gc : fl_GetDC(0) ) , w, h);
- if (!offscreen) offscreen = (Fl_Offscreen)CreateCompatibleBitmap(fl_GetDC(0), w, h);
- driver(Fl_Graphics_Driver::newMainGraphicsDriver());
- if (d != 1 && high_res) ((Fl_GDI_Graphics_Driver*)driver())->scale(d);
- origin.x = origin.y = 0;
- shape_data_ = NULL;
-}
-
-
-Fl_GDI_Image_Surface_Driver::~Fl_GDI_Image_Surface_Driver() {
- if (shape_data_ && shape_data_->background) {
- DeleteObject(shape_data_->background);
- delete shape_data_->mask;
- free(shape_data_);
- }
- if (offscreen && !external_offscreen) DeleteObject((HBITMAP)offscreen);
- delete driver();
-}
-
-
-void Fl_GDI_Image_Surface_Driver::set_current() {
- HDC gc = fl_makeDC((HBITMAP)offscreen);
- driver()->gc(gc);
- SetWindowOrgEx(gc, origin.x, origin.y, NULL);
- Fl_Surface_Device::set_current();
- pre_window = fl_window;
- _savedc = SaveDC(gc);
- fl_window=(HWND)offscreen;
-}
-
-
-void Fl_GDI_Image_Surface_Driver::translate(int x, int y) {
- ((Fl_GDI_Graphics_Driver*)driver())->translate_all(x, y);
-}
-
-
-void Fl_GDI_Image_Surface_Driver::untranslate() {
- ((Fl_GDI_Graphics_Driver*)driver())->untranslate_all();
-}
-
-
-Fl_RGB_Image* Fl_GDI_Image_Surface_Driver::image()
-{
- if (shape_data_ && shape_data_->background) {
- // get the offscreen size in pixels
- HDC gc = fl_makeDC((HBITMAP)offscreen);
- BITMAPINFO bmi;
- bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
- bmi.bmiHeader.biCompression = BI_RGB;
- bmi.bmiHeader.biPlanes = 1;
- bmi.bmiHeader.biBitCount = 0;
- bmi.bmiHeader.biSizeImage = 0;
- GetDIBits(gc, (HBITMAP)offscreen, 0, 0, NULL, &bmi, DIB_RGB_COLORS);
- int W = bmi.bmiHeader.biWidth;
- int H = bmi.bmiHeader.biHeight;
- int line_size = ((3*W+3)/4) * 4;
-
- // read bits of main offscreen
- uchar *dib_src = new uchar[line_size * H];
- bmi.bmiHeader.biWidth = W;
- bmi.bmiHeader.biHeight = H;
- bmi.bmiHeader.biCompression = BI_RGB;
- bmi.bmiHeader.biBitCount = 24;
- GetDIBits(gc, (HBITMAP)offscreen, 0, H,
- dib_src, &bmi, DIB_RGB_COLORS);
-
- // draw above the secondary offscreen the main offscreen masked by shape_data_->mask
- GdiFlush();
- Fl_Image_Surface_Driver::copy_with_mask(shape_data_->mask, shape_data_->vBits, dib_src, ((3*W+3)/4) * 4, true);
- delete shape_data_->mask;
- delete[] dib_src;
-
- // write bits of main offscreen
- SetDIBits(gc, (HBITMAP)offscreen, 0, H, shape_data_->vBits, &bmi, DIB_RGB_COLORS);
- DeleteDC(gc);
- DeleteObject(shape_data_->background);
- shape_data_->background = NULL;
- free(shape_data_);
- shape_data_ = NULL;
- }
- Fl_RGB_Image *image = Fl::screen_driver()->read_win_rectangle( 0, 0, width, height, 0);
- return image;
-}
-
-
-void Fl_GDI_Image_Surface_Driver::end_current()
-{
- HDC gc = (HDC)driver()->gc();
- GetWindowOrgEx(gc, &origin);
- RestoreDC(gc, _savedc);
- DeleteDC(gc);
- fl_window = pre_window;
- Fl_Surface_Device::end_current();
-}
-
-
-void Fl_GDI_Image_Surface_Driver::mask(const Fl_RGB_Image *mask) {
- shape_data_ = (struct shape_data_type*)calloc(1, sizeof(struct shape_data_type));
- // get the offscreen size in pixels
- HDC gc = fl_makeDC((HBITMAP)offscreen);
- BITMAPINFO bmi;
- bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
- bmi.bmiHeader.biCompression = BI_RGB;
- bmi.bmiHeader.biPlanes = 1;
- bmi.bmiHeader.biBitCount = 0;
- bmi.bmiHeader.biSizeImage = 0;
-
- GetDIBits(gc, (HBITMAP)offscreen, 0, 0, NULL, &bmi, DIB_RGB_COLORS);
- int W = bmi.bmiHeader.biWidth;
- int H = bmi.bmiHeader.biHeight;
-
- shape_data_->mask = Fl_Image_Surface_Driver::RGB3_to_RGB1(mask, W, H);
-
- // duplicate current offscreen content to new offscreen
- int line_size = ((3*W+3)/4) * 4;
- uchar *dib = new uchar[line_size * H]; // create temporary buffer to read DIB
- bmi.bmiHeader.biWidth = W;
- bmi.bmiHeader.biHeight = H;
- bmi.bmiHeader.biCompression = BI_RGB;
- bmi.bmiHeader.biBitCount = 24;
-
- GetDIBits(gc, (HBITMAP)offscreen, 0, H, dib, &bmi, DIB_RGB_COLORS);
-
- HDC background_gc = CreateCompatibleDC(gc);
- shape_data_->background =
- CreateDIBSection(background_gc, &bmi, DIB_RGB_COLORS,
- (void**)&shape_data_->vBits, NULL, 0);
- if (!shape_data_->background) {
- Fl::error("CreateDIBSection error=%lu", GetLastError());
- }
- memcpy(shape_data_->vBits, dib, H * line_size);
- delete[] dib;
- DeleteDC(background_gc);
- DeleteDC(gc);
-}
-