Evaluate hypothesis of using GDI+ for the Windows platform

455 views
Skip to first unread message

Manolo

unread,
Feb 1, 2021, 12:40:56 PM2/1/21
to fltk.coredev
I invite fellow FLTK developers to, please, consider whether it would make
sense to have the Windows FLTK platform use GDI+ to perform all graphics,
instead of GDI that's currently used.

According to the Windows documentation,
  https://docs.microsoft.com/en-us/windows/win32/gdiplus/-gdiplus-gdi-start
"GDI+ is a class-based API for C/C++ programmers. It enables applications to use graphics
and formatted text on both the video display and the printer."
"GDI+ can be used in all Windows-based applications. GDI+ was introduced in Windows XP and
Windows Server 2003."

Expected benefits of using GDI+ are :
* it fits well the scaling feature of FLTK 1.4 because GDI+ "drawing contexts" (of type
Gdiplus::Graphics) can be transformed by any translation, scaling and rotation.
* all fonts usable with GDI+ are fully scalable
* rotated text is naturally supported by GDI+
* images can be drawn shrinked or enlarged without limitation
* GDI+ allows a future FLTK extension towards drawing with transparency
* the libfltk.a library is slightly smaller with GDI+ than with GDI:
MinGW build |    32-bit        |        64-bit      |
with GDI+   | 3 247 614 bytes  |  3 986 796  bytes  |
with GDI    | 3 261 516 bytes  |  4 019 914  bytes  |


An essentially complete source code is available by
    git clone https://github.com/ManoloFLTK/fltk.git  fltkGDI+
    cd fltkGDI+
    git checkout GDI+
for evaluation.

I have successfully built (with MinGW) and run the modified, GDI+-using code in standard
Windows XP and Windows 10. I have produced 32-bit code which runs unchanged on
WinXP and Win 10, and 64-bit code on Win 10.

I could not try it with Visual C++ but expect no problem because only documented API's are used.
I don't know, though, if the extra argument "-lgdiplus" of the link command (see below)
takes a different form with Visual C++.

Configure-based builds can activate GDI+ with
  ./configure --enable-gdiplus
CMake-based builds should turn OPTION_USE_GDIPLUS on.

The resulting config.h contains :
------------------ new stuff in config.h ------------
/*
 * Do we use GDI+ rather than GDI?
 */

#ifdef _WIN32
#define USE_GDIPLUS 1
#endif
------------------ end of new stuff in config.h ------------
where the preprocessor variable USE_GDIPLUS is set to 0 if the new build option
has not been activated.

The source code uses this construct
#if USE_GDIPLUS
  ***  new, GDI+ -based source code ***
#else
  ***  unchanged, GDI -based source code ***
#endif
everywhere traditional GDI and new GDI+ differ.

Thus, the new code remains compatible with pre-XP Windows versions through its GDI-based part.

With one exception, all changes to the FLTK code base are located in Windows-specific
parts, which guarantees that the X11 and macOS platforms and the public FLTK API are
totally unaffected. The exception is a code fragment where platform-independent code
processes an Fl_RGB_Image object (let's call it rgb) created by FLTK which assumed
  rgb->ld() == 0.
That assumption is not valid for the GDI+-generated object. That code has been modified
to correctly handle an object for which rgb->ld() > 0.

The platform-specific source code requires
#include <gdiplus.h>
and the link command requires "-lgdiplus". All platform-independent user code is unchanged.

With GDI, the class hierarchy for graphics drivers is
  +- Fl_Graphics_Driver: platform-independent root class
      +- Fl_Scalable_Graphics_Driver: helper class to support GUI scaling
          +- Fl_GDI_Graphics_Driver: Windows-specific graphics driver
              +- Fl_GDI_Printer_Graphics_Driver: re-implements a few member functions for printing
and class Fl_Xlib_Graphics_Driver, the X11-specific graphics driver, is a sister of Fl_GDI_Graphics_Driver.

With GDI+, the hierarchy is simpler :
  +- Fl_Graphics_Driver: platform-independent root class
      +- Fl_GDIplus_Graphics_Driver: Windows-GDI+ specific graphics driver

Three platform-specific, FLTK-defined types (declared in FL/platform_types.h)
change between GDI and GDI+. It turned out it's not possible to declare
their true value in a way accepted both by platform-independent and platform-specific
parts of the source code. They are therefore declared as "pointer to void" as follows:
typedef void* Fl_Offscreen; /* HBITMAP under GDI; Gdiplus::Bitmap* under GDI+ */
typedef void* Fl_Region; /* HRGN under GDI; Gdiplus::Region* under GDI+ */
typedef void* Fl_Bitmask; /* HBITMAP under GDI; class Fl_GdiPlusBitmap* under GDI+ */
The platform-specific source code casts objects of these types to their true
type when necessary.

That part of the FLTK doc
  https://fltk.gitlab.io/fltk/osissues.html#osissues_win32_gdi
would become invalidated by the GDI+ change.

Ian MacArthur

unread,
Feb 1, 2021, 1:32:48 PM2/1/21
to coredev fltk
On 1 Feb 2021, at 17:40, Manolo wrote:
>
> I invite fellow FLTK developers to, please, consider whether it would make
> sense to have the Windows FLTK platform use GDI+ to perform all graphics,
> instead of GDI that's currently used.
>
> According to the Windows documentation,
> https://docs.microsoft.com/en-us/windows/win32/gdiplus/-gdiplus-gdi-start
> "GDI+ is a class-based API for C/C++ programmers. It enables applications to use graphics
> and formatted text on both the video display and the printer."
> "GDI+ can be used in all Windows-based applications. GDI+ was introduced in Windows XP and
> Windows Server 2003.”


I really do not know - I don't really comprehend all the variant API that MS provide...

TBH, I actually thought that GDI+ was deprecated now (and they only keep GDI round because *everything* depends on it) and that we were meant to use Direct2D or some such thing instead.

Also, ISTR that GDI+ was more capable (as Manolo describes below) but achieved that through being software rendered, rather than hardware accelerated like GDI is, and so folks disliked it for that reason.

But, as I say, I do not actually know what I’m talking about...
> --
> You received this message because you are subscribed to the Google Groups "fltk.coredev" group.
> To unsubscribe from this group and stop receiving emails from it, send an email to fltkcoredev...@googlegroups.com.
> To view this discussion on the web visit https://groups.google.com/d/msgid/fltkcoredev/5dff1d54-6fe1-4641-8938-d0e629b768e7n%40googlegroups.com.

Greg Ercolano

unread,
Feb 1, 2021, 1:42:03 PM2/1/21
to fltkc...@googlegroups.com


On 2/1/21 9:40 AM, Manolo wrote:
I invite fellow FLTK developers to, please, consider whether it would make
sense to have the Windows FLTK platform use GDI+ to perform all graphics,
instead of GDI that's currently used.


    Sounds generally good to me, gonna go with your instinct on this, as my only concern
    is that FLTK still build on XP and up, which it sounds like it does.

    However there are some folks working on DOS support somehow; will their
    efforts
be negatively affected?

    Beyond that I have no opinion, other than it sounds like it's more C++ "friendly" and offers
    features the older GDI does not which may help us in the long run. So I'm not sure I see a
    downside other than backwards support before XP (which might be an issue for some).

    Just doing a casual google search for GDI vs GDI+:
    https://stackoverflow.com/questions/4551224/what-is-the-difference-between-gdi-and-gdi

"""
GDI+ is object oriented, and it's main purpose is to provide C++ classes to simplify and extend in some ways GDI usage. GDI+ is an improvement on GDI. It contains features not readily available in GDI such as gradient brushes, alpha blending, and more image format support.
"""


    ..and (emphasis from the OP):

"""
With the introduction of Windows XP, GDI was deprecated in favor of its successor, the C++ based GDI+ subsystem. GDI+ adds anti-aliased 2D graphics, floating point coordinates, gradient shading, more complex path management, intrinsic support for modern graphics-file formats like JPEG and PNG, and support for composition of affine transformations in the 2D view pipeline.
"""

According to the Windows documentation,
  https://docs.microsoft.com/en-us/windows/win32/gdiplus/-gdiplus-gdi-start
"GDI+ is a class-based API for C/C++ programmers. It enables applications to use graphics
and formatted text on both the video display and the printer."
"GDI+ can be used in all Windows-based applications. GDI+ was introduced in Windows XP and
Windows Server 2003."

Expected benefits of using GDI+ are :

    All sounds good to me!


Greg Ercolano

unread,
Feb 1, 2021, 1:47:29 PM2/1/21
to fltkc...@googlegroups.com

I could not try it with Visual C++ but expect no problem because only documented API's are used.
I don't know, though, if the extra argument "-lgdiplus" of the link command (see below)
takes a different form with Visual C++.

    I can try your fork in VS 7 and VS Express 2017 later today and report back
    if that would help.

    Let me know if there's any specific things you want me to enable or look for/test.
    I can also provide you with executables if need be to play with.


Manolo

unread,
Feb 1, 2021, 3:10:55 PM2/1/21
to fltk.coredev
On Monday, February 1, 2021 at 7:47:29 PM UTC+1 er...@seriss.com wrote:
    I can try your fork in VS 7 and VS Express 2017 later today and report back if that would help.
Yes, please. Thanks.


    Let me know if there's any specific things you want me to enable or look for/test.
    I can also provide you with executables if need be to play with.

Could you try and build a real-scale app?  If it's not rich of GDI-specific code,
it should readily build.

Albrecht Schlosser

unread,
Feb 1, 2021, 4:00:00 PM2/1/21
to fltkc...@googlegroups.com
On 2/1/21 6:40 PM Manolo wrote:
> I invite fellow FLTK developers to, please, consider whether it would make
> sense to have the Windows FLTK platform use GDI+ to perform all graphics,
> instead of GDI that's currently used.
>
> According to the Windows documentation,
> ... GDI+ was introduced in Windows XP and Windows Server 2003."
>
> Expected benefits of using GDI+ are :
> * it fits well the scaling feature of FLTK 1.4 because GDI+ "drawing
> contexts" (of type
> Gdiplus::Graphics) can be transformed by any translation, scaling and
> rotation.
> * all fonts usable with GDI+ are fully scalable
> * rotated text is naturally supported by GDI+
> * images can be drawn shrinked or enlarged without limitation
> * GDI+ allows a future FLTK extension towards drawing with transparency
> * the libfltk.a library is slightly smaller with GDI+ than with GDI:

This all sounds pretty good! Thank you very much for your efforts.

> An essentially complete source code is available by
>     git clone https://github.com/ManoloFLTK/fltk.git  fltkGDI+
>     cd fltkGDI+
>     git checkout GDI+
> for evaluation.

I'll definitely give it a try!

> I could not try it with Visual C++ but expect no problem because only
> documented API's are used.

My current Windows test system has VS 2019 IIRC, so that's something I
can test.

> I don't know, though, if the extra argument "-lgdiplus" of the link
> command (see below) takes a different form with Visual C++.

Supposedly not.

> Configure-based builds can activate GDI+ with
>   ./configure --enable-gdiplus
> CMake-based builds should turn OPTION_USE_GDIPLUS on.
> [...]
> Thus, the new code remains compatible with pre-XP Windows versions
> through its GDI-based part.

What's your (and other devs') idea/vision: keep the full code base for
both GDI and GDI+ in the future, or switch entirely to GDI+ once we know
it's working?

> With one exception, all changes to the FLTK code base are located in
> Windows-specific
> parts, which guarantees that the X11 and macOS platforms and the public
> FLTK API are
> totally unaffected. The exception is a code fragment where
> platform-independent code
> processes an Fl_RGB_Image object (let's call it rgb) created by FLTK
> which assumed
>   rgb->ld() == 0.
> That assumption is not valid for the GDI+-generated object. That code
> has been modified to correctly handle an object for which rgb->ld() > 0.

Hmm, I don't understand this. IIRC it's well documented that ld() == 0
is a shortcut for ld() == w() * d(). So why does this need a special
treatment?

> All platform-independent user code is unchanged.

That's great (and it really *should* be so).

> With GDI+, the hierarchy is simpler :
>   +- Fl_Graphics_Driver: platform-independent root class
>       +- Fl_GDIplus_Graphics_Driver: Windows-GDI+ specific graphics driver

Very good!

> Three platform-specific, FLTK-defined types (declared in
> FL/platform_types.h)
> change between GDI and GDI+. It turned out it's not possible to declare
> their true value in a way accepted both by platform-independent and
> platform-specific
> parts of the source code. They are therefore declared as "pointer to
> void" as follows:
> typedef void* Fl_Offscreen; /* HBITMAP under GDI; Gdiplus::Bitmap* under
> GDI+ */
> typedef void* Fl_Region; /* HRGN under GDI; Gdiplus::Region* under GDI+ */
> typedef void* Fl_Bitmask; /* HBITMAP under GDI; class Fl_GdiPlusBitmap*
> under GDI+ */
> The platform-specific source code casts objects of these types to their true
> type when necessary.

That's something we might consider for other platforms as well. We could
maybe hide more platform specific code/types from the user code.

> That part of the FLTK doc
>   https://fltk.gitlab.io/fltk/osissues.html#osissues_win32_gdi
> would become invalidated by the GDI+ change.

Is it possible to have an alternative for user code using GDI+ for
drawing in their own draw() methods?

Manolo

unread,
Feb 2, 2021, 4:23:34 AM2/2/21
to fltk.coredev
Many thanks for all your comments.

Ian's note about GDI+ being software rendered whereas GDI is hardware accelerated
is especially important. If GDI+ is less efficient than GDI, adopting it for FLTK seems
less compelling.
@Ian: do you know any document that could help us quantify GDI+ efficiency?

I understand some time is necessary for the evaluation of this hypothesis.

On Monday, February 1, 2021 at 10:00:00 PM UTC+1 Albrecht Schlosser wrote:
What's your (and other devs') idea/vision: keep the full code base for
both GDI and GDI+ in the future, or switch entirely to GDI+ once we know
it's working?
My vision is still unsure at this point. Compatibility with pre-XP versions
would require GDI to be kept. But do we test FLTK on any such environment?
I don't. Isn't a compatibility claim without effective test a deceptive illusion?
 

> With one exception, all changes to the FLTK code base are located in
> Windows-specific
> parts, which guarantees that the X11 and macOS platforms and the public
> FLTK API are
> totally unaffected. The exception is


Hmm, I don't understand this. IIRC it's well documented that ld() == 0
is a shortcut for ld() == w() * d(). So why does this need a special
treatment?
That is a small detail. It's in function fl_read_image() of file src/fl_read_image.cxx
It returns an RGB(A) image, as a byte array, read from the current window or off-screen buffer.
Because the function's output is a byte array, "image" lines cannot be larger than
its width. The byte array is built from an Fl_RGB_Image object called img built inside
the function. Until addition of the GDI+ source code, the 3 platforms built img such that
img->ld() == 0. This allowed the function to return img->array as the function's product.
GDI+ wants its images to have line length a multiple of 4, thus img->ld() is sometimes
!= 0 and fl_read_image() must do an extra operation (a copy) with img to build the final
byte array when img->ld() != 0. That change in platform-independent code does no harm
but is necessary for fl_read_image() to be correct with GDI+.


> That part of the FLTK doc
>   https://fltk.gitlab.io/fltk/osissues.html#osissues_win32_gdi
> would become invalidated by the GDI+ change.

Is it possible to have an alternative for user code using GDI+ for
drawing in their own draw() methods?
I believe so. The current :

extern HDC fl_gc;
COLORREF fl_RGB();
HPEN fl_pen();
HBRUSH fl_brush();
DrawSomething(fl_gc, ..., fl_brush());
 
could be replaced by (it's not -- yet -- in the source code) :

#include <gdiplus.h>
extern Gdiplus::Graphics *fl_gdiplus_graphics;
Gdiplus::Pen *fl_pen();
Gdiplus::Color gdi_color;  fl_pen->GetColor(&gdi_color);
Gdiplus::SolidBrush* fl_brush();
fl_gdiplus_graphics->DrawSomething(fl_pen() or fl_brush(), …);
 

Albrecht Schlosser

unread,
Feb 2, 2021, 6:36:34 AM2/2/21
to fltkc...@googlegroups.com
On 2/2/21 10:23 AM Manolo wrote:
>
> Ian's note about GDI+ being software rendered whereas GDI is hardware
> accelerated
> is especially important. If GDI+ is less efficient than GDI, adopting it
> for FLTK seems less compelling.
> @Ian: do you know any document that could help us quantify GDI+ efficiency?

I did a quick search and found on Wikipedia
https://en.wikipedia.org/wiki/Graphics_Device_Interface

"GDI+ is included with all versions of Windows from Windows XP. The GDI+
dynamic library can also be shipped with an application and used under
older versions of Windows from Windows 98 and Windows NT 4.0 onwards.[3]

Because of the additional text processing and resolution independence
capabilities in GDI+, text rendering is performed by the CPU[4] and it
is nearly an order of magnitude slower than in hardware accelerated
GDI.[5] Chris Jackson published some tests indicating that a piece of
text rendering code he had written could render 99,000 glyphs per second
in GDI, but the same code using GDI+ rendered 16,600 glyphs per second."

Interesting points: From my first view (elsewhere) I got the impression
that GDI+ is a wrapper around GDI functions, but with extensions.
Wikipedia adds that text rendering is different and NOT hardware
accelerated. Unfortunately the links [4] and [5] in this article don't
refer to any useful information, they only link to a "blog archive"
which I didn't search further.

The other "interesting" point is that the GDI+ DLL "can be shipped with
an application and used under older versions of Windows from Windows 98
and Windows NT 4.0 onwards" which should at least give some backwards
compatibility, although perhaps not for "old DOS".

Albrecht Schlosser

unread,
Feb 2, 2021, 6:54:44 AM2/2/21
to fltkc...@googlegroups.com
On 2/2/21 10:23 AM Manolo wrote:
> On Monday, February 1, 2021 at 10:00:00 PM UTC+1 Albrecht Schlosser wrote:
>
> What's your (and other devs') idea/vision: keep the full code base for
> both GDI and GDI+ in the future, or switch entirely to GDI+ once we
> know
> it's working?
>
> My vision is still unsure at this point. Compatibility with pre-XP versions
> would require GDI to be kept. But do we test FLTK on any such environment?
> I don't. Isn't a compatibility claim without effective test a deceptive
> illusion?

Our compatibility claim was in the past that we support Windows XP /
2000 and later versions, particularly since 1.3.0 which needs working
UTF-8 support. IMHO even XP / 2000 are questionable because of their
maybe incomplete Unicode (UTF-8) features.

As Greg mentioned, some people are using FLTK on old DOS-like systems (I
read about FreeDOS) but these are IMHO unsupported corner cases. If it
works for them: fine, if not: well, there's nothing we can do.

One way out could be to define another "official" compatibility target
for FLTK 1.4 which *might* be Windows 10 because:
- all Windows versions up to Win7 are no longer supported
- I have no idea if Win8 is still supported
- Win10 is likely the only version still supported by Microsoft

> > With one exception, all changes to the FLTK code base are
> > located in Windows-specific parts, which guarantees that
> > the X11 and macOS platforms and the public FLTK API are
> > totally unaffected. The exception is …
>
> Hmm, I don't understand this. IIRC it's well documented that ld() == 0
> is a shortcut for ld() == w() * d(). So why does this need a special
> treatment?
>
> That is a small detail. It's in function fl_read_image() of file
> src/fl_read_image.cxx ...
> ... GDI+ wants its images to have line length a multiple of 4, ...
> ... That change in platform-independent code does no harm but
> is necessary for fl_read_image() to be correct with GDI+.

I understand, thanks for the explanation.

> …
> > That part of the FLTK doc
> > https://fltk.gitlab.io/fltk/osissues.html#osissues_win32_gdi
> > would become invalidated by the GDI+ change.
>
> Is it possible to have an alternative for user code using GDI+ for
> drawing in their own draw() methods?
>
> I believe so. The current :
>
> extern HDC fl_gc;
> COLORREF fl_RGB();
> HPEN fl_pen();
> HBRUSH fl_brush();
> DrawSomething(fl_gc, ..., fl_brush());
> could be replaced by (it's not -- yet -- in the source code) :
>
> #include <gdiplus.h>
> extern Gdiplus::Graphics *fl_gdiplus_graphics;
> Gdiplus::Pen *fl_pen();
> Gdiplus::Color gdi_color;  fl_pen->GetColor(&gdi_color);
> Gdiplus::SolidBrush* fl_brush();
> fl_gdiplus_graphics->DrawSomething(fl_pen() or fl_brush(), …);

Great! I think that we'd need at least such a migration option for user
code that does its own GDI drawing operations inside draw().

Manolo

unread,
Feb 3, 2021, 8:29:32 AM2/3/21
to fltk.coredev
Branch GDI+ now draws all but horizontal and vertical lines in antialiased form.
That's an interesting improvement over GDI.

Albrecht Schlosser

unread,
Feb 3, 2021, 4:01:17 PM2/3/21
to fltkc...@googlegroups.com
On 2/1/21 9:59 PM Albrecht Schlosser wrote:
> On 2/1/21 6:40 PM Manolo wrote:
>
>> An essentially complete source code is available by
>>      git clone https://github.com/ManoloFLTK/fltk.git  fltkGDI+
>>      cd fltkGDI+
>>      git checkout GDI+
>> for evaluation.
>
> I'll definitely give it a try!

My first results (incomplete):

(1) Linux with MinGW-w64 cross build (64-bit build)

Builds, but doesn't display text at all (using wine). Some lines and/or
points are offset (see test/unittests). Testing is almost impossible w/o
text.

The executables work fine on Windows 10 though (copied to my VM I'm
using Win10), antialiased lines look good, text is being displayed.
Rotated text works but looks really bad.

The text issue on Linux may be due to something unsupported in wine.


(2) Windows 10 with MSYS2/MinGW-w64 (64-bit build)

Antialiasing of lines looks fine, as do boxes in the "gleam" scheme.
There some really minor issues though with colors in "gleam" boxes,
maybe antialiasing artefacts (with different scaling factors). See
test/unittests: scheme test.

Rotated text (test/rotated_text.cxx) works but looks really bad. Rotated
text with GDI looks a little better (IMHO) but has issues with "jumping
letters", i.e. letters that appear to be somewhat above the baseline
and/or slightly too far right or left. Both systems (GDI vs. GDIplus)
seem to have their own issues.


(3) Building on Win10 with VS2019 *failed* completely. There are cryptic
error messages, most if not all of them from some gdiplus *header files*
and there are more than 100 errors in one compilation unit which causes
the compilation to stop.

I *love* these Microsoft error messages! :-(
Particularly if they are from MS header files.

See attached excerpt from the build log (vs2019-build-errors.txt).

I don't think that my VS2019 build system is broken since I don't see
such errors w/o gdiplus. I have currently no idea how to proceed.

Anyway, double checking by others with VS2019 and maybe other VS
versions would be helpful.
vs2019-build-errors.txt

Ian MacArthur

unread,
Feb 3, 2021, 5:20:01 PM2/3/21
to coredev fltk
On 2 Feb 2021, at 09:23, Manolo wrote:
>
> Many thanks for all your comments.
>
> Ian's note about GDI+ being software rendered whereas GDI is hardware accelerated
> is especially important. If GDI+ is less efficient than GDI, adopting it for FLTK seems
> less compelling.
> @Ian: do you know any document that could help us quantify GDI+ efficiency?


No, not really - though I see Albrecht found some relevant references.

TBH, I don't even know how / where I found that out, it was just a thing I vaguely thought I remembered...

Indeed, it is entirely possible that later iterations (e.g. Win10) may be rendering it differently; certainly the “basic” GDI drivers seem to have seen some switching back and forth between hardware and software render paths over the years, so GDI+ may be similar. But I do not know.

It is possible I heard about this when I was looking at some anti-aliasing task on Windows, but that was maybe 10 years ago. I have a vague idea I looked at GDI+, but ended up using something else (might have been Cairo though, which is also slow...)
I think that’s possibly where I picked up the idea that GDI+ was deprecated in favour of Direct2D or something these days, too, but basically I know nothing about any of this!


Manolo

unread,
Feb 4, 2021, 11:42:32 AM2/4/21
to fltk.coredev
@Albrecht : many thanks for trying the GDI+ branch with Visual Studio.

The Windows doc gives the complete source  of a toy GDI+-based program at
that does create a window with a blue line after I compile it with MinGW and run it here.
Its include directives are:

#include <stdafx.h>
#include <windows.h>
#include <objidl.h>
#include <gdiplus.h>

using namespace Gdiplus;
#pragma comment (lib,"Gdiplus.lib")

I believe stdafx.h is VS-specific. But could it be that including objidh.h between windows.h and gdiplus.h
is all what is needed to have the GDI+ branch running?
To check that, could you, please, modify file src/drivers/GDI/Fl_GDI_Graphics_Driver.H adding
#include <objidl.h>
just before
#include <gdiplus.h>
and do the same for file src/drivers/GDI/Fl_Font.H ?

If that's correct, I'll add that extra #include directive.
TIA
Manolo

Albrecht Schlosser

unread,
Feb 4, 2021, 12:31:01 PM2/4/21
to fltkc...@googlegroups.com
On 2/4/21 5:42 PM Manolo wrote:
> @Albrecht : many thanks for trying the GDI+ branch with Visual Studio.

welcome

> The Windows doc gives the complete source  of a toy GDI+-based program at
>
> https://docs.microsoft.com/en-us/windows/win32/gdiplus/-gdiplus-drawing-a-line-use
> that does create a window with a blue line after I compile it with MinGW
> and run it here.

Yep, I found this too. I downloaded the entire docs as one PDF file,
BTW, which is handy.

> Its include directives are:
>
> #include <stdafx.h>
> #include <windows.h>
> #include <objidl.h>
> #include <gdiplus.h>
>
> using namespace Gdiplus;
> #pragma comment (lib,"Gdiplus.lib")
>
> I believe stdafx.h is VS-specific. But could it be that including
> objidh.h between windows.h and gdiplus.h
> is all what is needed to have the GDI+ branch running?

Not all, but almost. :-)

You're right that stdafx.h is not needed. Meanwhile I found a first
patch (a quick hack) but we can probably improve that. See attached file
vs2019-includes.diff.

Just wanted to let you know that it does indeed work now.

> To check that, could you, please, modify file
> src/drivers/GDI/Fl_GDI_Graphics_Driver.H adding
> #include <objidl.h>
> just before
> #include <gdiplus.h>
> and do the same for file src/drivers/GDI/Fl_Font.H ?

Adding it in src/drivers/GDI/Fl_GDI_Graphics_Driver.H was obviously
enough to fix most of the errors but the build still errored out with
missing definitions for ceil() and floor(). I added #include <math.h>
where needed as well.

> If that's correct, I'll add that extra #include directive.

I can look for a better patch, maybe include <math.h> in
Fl_GDI_Graphics_Driver.H instead of the source files?

Another point was indeed the missing gdiplus.lib linker statement (as
you suspected). My preferred solution would be to add it to the CMake
files at the appropriate place, but for now I used the way of least
resistance (the Microsoft way) and added

#pragma comment (lib,"gdiplus.lib")

(all lowercase in my patch). This solved the linker issues and seems to
work, however I don't like these linker pragma's because they obfuscate
the build requirements.

I need a little break to do other stuff but I'll pursue this later and
let you know of my further patch and test results.
vs2019-includes.diff

Manolo

unread,
Feb 4, 2021, 1:21:13 PM2/4/21
to fltk.coredev
I have decided to give a try with Visual Studio and installed VS 2019,
and arrived to the same conclusions as you: added the include <objidl.h>,
a couple of #include <FL/math.h> and of the pragma directive.
Its now pushed to the git granch. Please, pull it.

It seems to be all working well now, at least within VirtualBox.
I will progressively try to remove the compilation warnings, but expect
you can tell me how to express the need for gdiplus.lib the CMake-way.

Greg Ercolano

unread,
Feb 4, 2021, 1:51:18 PM2/4/21
to fltkc...@googlegroups.com
On 2/4/21 10:21 AM, Manolo wrote:
I have decided to give a try with Visual Studio and installed VS 2019,
and arrived to the same conclusions as you [Albrecht]: added the include <objidl.h>,
a couple of #include <FL/math.h> and of the pragma directive.
Its now pushed to the git granch. Please, pull it.

Looks like I'm a little late to the party; cloned/checked out your repo just now,
which is currently at:

commit 356e60c26f39d3391f0b54ecaa315bb69f6c8825 (HEAD -> GDI+, origin/GDI+)
Author: ManoloFLTK <41016272+...@users.noreply.github.com>
Date:   Thu Feb 4 19:05:41 2021 +0100

    Windows GDI+: add support of Visual Studio
Then used cmake to configure for VS 2017:

cmake -G "Visual Studio 15 2017" -D CMAKE_BUILD_TYPE=Release ..

Loaded the fltk.sln up in VS 2017, changed Debug -> Release and built the whole project,
resulting in "94 succeeded" and no fails or skips, but lots of the usual warnings (attached as warnings.txt).

Test programs look OK so far, unit tests for drawing all seem to look consistent with linux.

Should the lines be antialiased? If so, not for me:




Widgets look ok, e.g. test/tree



Next I'll try building an app that draws lots and lots of vectors quickly in animation, a good way to see if there's
any slowness for line drawing.

But before I do that, wanted to check if I've built this right, because I was expecting antialiased lines..?



warnings.txt

Albrecht Schlosser

unread,
Feb 4, 2021, 2:22:30 PM2/4/21
to fltkc...@googlegroups.com
On 2/4/21 7:51 PM Greg Ercolano wrote:
> On 2/4/21 10:21 AM, Manolo wrote:
>
> Looks like I'm a little late to the party; cloned/checked out your
> repo just now, which is currently at:
>
> commit *356e60c26f39d3391f0b54ecaa315bb69f6c8825* (HEAD -> GDI+,
> origin/GDI+)
> Author: ManoloFLTK <41016272+...@users.noreply.github.com>
> Date:   Thu Feb 4 19:05:41 2021 +0100
>
> *Windows GDI+: add support of Visual Studio*

OK, that's probably the correct commit.

> Then used cmake to configure for VS 2017:
>
> *cmake -G "Visual Studio 15 2017" -D CMAKE_BUILD_TYPE=Release ..*
>
> Loaded the fltk.sln up in VS 2017, changed Debug -> Release and
> built the whole project,
> resulting in "94 succeeded" and no fails or skips, but lots of the
> usual warnings (attached as warnings.txt).
>
> Test programs look OK so far, unit tests for drawing all seem to
> look consistent with linux.
>
> _*Should the lines be antialiased? If so, not for me:*_

First of all, I assume you checked out branch GDI+, right?

Second important point is to set OPTION_USE_GDIPLUS but your CMake
command above doesn't include this.

In case you didn't you can just run cmake again with that option (-D
OPTION_USE_GDIPLUS=ON) or edit the option with cmake-gui.

See attached image with antialiased lines.
vs2019-gdiplus-lines.png

Greg Ercolano

unread,
Feb 4, 2021, 2:45:05 PM2/4/21
to fltkc...@googlegroups.com

On 2/4/21 11:22 AM, Albrecht Schlosser wrote:

On 2/4/21 7:51 PM Greg Ercolano wrote:
    _*Should the lines be antialiased? If so, not for me:*_

First of all, I assume you checked out branch GDI+, right?


    Ya. Copy pasted the clone + checkout commands from Manolo's earlier msg.



Second important point is to set OPTION_USE_GDIPLUS but your CMake command above doesn't include this.
In case you didn't you can just run cmake again with that option (-D OPTION_USE_GDIPLUS=ON) or edit the option with cmake-gui.


    Thanks, that must be it -- will retry with that.

    It would be good if the FLTK api provided a way to turn AA off from within the app, as there are rare apps
    that can benefit from turning AA on/off within the app. PCB board CAD comes to mind.


Greg Ercolano

unread,
Feb 4, 2021, 3:24:32 PM2/4/21
to fltkc...@googlegroups.com

OK,  94 succeeded, no errors, but there are some new warnings about the /ldgiplus flag being ignored, which has already been noted by Albrecht.

There are some other warnings too; attached here as "warnings2.txt", so one can diff these against the previous warnings.txt to see what new warnings GDI added to the VS2017 build.

Can now confirm AA lines in the unittests, which do look great.. and text looks better (see "rendering text" unit test results, compared to my previous screenshots).

I should my tests today with VS2017 are all on Windows 8.






Widgets look good/the same, however oddly the text seems more antialiased in the GDI+ build than the non-GDI build.
Perhaps AA is turned ON for lines, but turned OFF for text? Seems to be.


Here's the above GDI+ screenshow shown with the non-GDI+ overlaid in red boxes for comparison:

I'll follow up with results for my real world app that renders lots of vectors in animation.


warnings2.txt

Greg Ercolano

unread,
Feb 4, 2021, 3:28:25 PM2/4/21
to fltkc...@googlegroups.com
Oops, CORRECTION in my last post (in red):
[..]
Widgets look good/the same, however oddly the text seems more aliased in the GDI+ build than the non-GDI build.

Perhaps AA is turned ON for lines, but turned OFF for text? Seems to be.
[..]

Greg Ercolano

unread,
Feb 4, 2021, 4:00:03 PM2/4/21
to fltkc...@googlegroups.com
On 2/4/21 12:28 PM, Greg Ercolano wrote:
Widgets look good/the same, however oddly the text seems more aliased in the GDI+ build than the non-GDI build.
Perhaps AA is turned ON for lines, but turned OFF for text? Seems to be.


It's almost like the rendering of text has been reversed; in GDI+ the default font look worse/aliased,
but the larger fonts (under unittests "rendering text") looks better/anti-aliased.

The large text in the non-GDI version was kinda ugly, had weird stair-stepping in the "a":



Oh, and I guess I didn't notice this before, but now zooming in, looks like GDI+ has a little trouble
with the 'missing pixel' problem; note the top/left corner of the green rectangle in the GDI+ screenshot above:



Now that I look closely at my unittest shots, seems they too have the missing pixel at the top/left, e.g. the "drawing lines":



Also, the "square" in the above has some tell-tale pixels showing at all 4 corners, and some aliasing where perhaps there shouldn't be? It's also more than one pixel wide and gray instead of black. I think the square is drawn with a series of fl_line() calls, whereas
the other segments that look OK are drawn with fl_xyline().. I think.

Albrecht Schlosser

unread,
Feb 4, 2021, 4:11:04 PM2/4/21
to fltkc...@googlegroups.com
On 2/4/21 7:21 PM Manolo wrote:
> I have decided to give a try with Visual Studio and installed VS 2019,

That's good. Although I really don't like it, it's good to be able to
use it for testing FLTK.

Just one note for the future: Generally you don't need to "register" or
use a MS account, but after a "trial period" (30 or 90 days, I don't
remember) VS 2019 will ask you to register or buy a license or something
like that. There's no need to buy a license though - the only thing you
need to do is "log in" with a Microsoft account (that's something you
really need) and then you can use it further without buying a license.

> and arrived to the same conclusions as you: added the include <objidl.h>,
> a couple of #include <FL/math.h> and of the pragma directive.
> Its now pushed to the git granch. Please, pull it.

Did that, worked.

> It seems to be all working well now, at least within VirtualBox.

Same here, using Virtualbox.

> I [...] expect
> you can tell me how to express the need for gdiplus.lib the CMake-way.

Yes, I hope I can. I attach a patch you can use to update your
repository like this:

1) apply patch:

$ git checkout GDI+

$ git am 0001-Windows-GDI-Improve-CMake-build-using-gdiplus.lib.patch
Applying: Windows GDI+: Improve CMake build using gdiplus.lib

2) verify:

$ git log -1
commit c0d7ad53b99b85724755ff4ac8434e22426c968a (HEAD -> GDI+)
Author: Albrecht Schlosser <albrech...@online.de>
Date: Thu Feb 4 21:53:42 2021 +0100

Windows GDI+: Improve CMake build using gdiplus.lib

- Remove MS specific #pragma comment (lib,"Gdiplus.lib")
- Add gdiplus explicitly to fluid and all demos
- Don't modify CMAKE_CXX_STANDARD_LIBRARIES
- Keep "-lgdiplus" for use in fltk-config

Tested build and "fltk-config --compile" under MSYS2/MinGW-w64,
tested build with VS2019


Note that this patch will be applied with my complete commit message to
your current branch (GDI+).

I'm not 100% happy with this patch but I believe it's an improvement. I
tested it with both MinGW and VS2019 and verified that "-lgdiplus" is
included in `fltk-config --compile' under MinGW.
0001-Windows-GDI-Improve-CMake-build-using-gdiplus.lib.patch

Albrecht Schlosser

unread,
Feb 4, 2021, 4:24:51 PM2/4/21
to fltkc...@googlegroups.com
On 2/4/21 10:11 PM Albrecht Schlosser wrote:

> Generally you don't need to "register" or
> use a MS account, but after a "trial period" (30 or 90 days, I don't
> remember) VS 2019 will ask you to register or buy a license or something
> like that. There's no need to buy a license though - the only thing you
> need to do is "log in" with a Microsoft account (that's something you
> really need) and then you can use it further without buying a license.

To clarify (just in case): you don't need to log in to your Windows
system with a Microsoft account (I always use a local account). It's
only internal in VS 2019 that you need to "log in" - unfortunately I
don't remember the details, hence I can't describe it better. You'll see
what I mean when the trial period expires. Hopefully.

Ian MacArthur

unread,
Feb 4, 2021, 4:50:29 PM2/4/21
to coredev fltk
On 3 Feb 2021, at 13:29, Manolo wrote:
>
> Branch GDI+ now draws all but horizontal and vertical lines in antialiased form.
> That's an interesting improvement over GDI.


Gave this a try with mingw on Win10, built (via cmake) for 32 and 64 bit. Both compiled fine and seem to run OK.
Haven’t tried Vs yet though.
(Note: This was checked out prior to Manolo’s commits to address the VS2019 issues, though that does not seem to affect mingw builds anyway.)

Observations:

- As Albrecht noted, the rotated text looks disappointing. It doesn’t seem to be well AA’d at all, and just looks a bit messy.

In fact, *all* text rendering looks a bit fuzzy, so it must be being anti-aliased in a different fashion from the Windows default.
Actually, what it reminds me of (very strongly) is the way Apple’s early port of Safari to Win7 looked, where they had used their own AA scheme for text rendering and it looked fuzzy like this, and just a bit odd against other Windows applications... (But probably no one by me remember that now!)

- The line AA looks (mostly) pretty good, I liked that.

- I ran through the test apps and some (not all) of the examples, and generally, stuff looked to be working OK.


Question: Can we do a compromise that uses our existing text rendering scheme (which I think looks consistent with other Windows apps and generally looks pretty decent) but uses the AA GDI+ stuff for other rendering?



Greg Ercolano

unread,
Feb 4, 2021, 6:04:28 PM2/4/21
to fltkc...@googlegroups.com


On 2/4/21 1:50 PM, Ian MacArthur wrote:
On 3 Feb 2021, at 13:29, Manolo wrote:
Branch GDI+ now draws all but horizontal and vertical lines in antialiased form.
That's an interesting improvement over GDI.

Gave this a try with mingw on Win10, built (via cmake) for 32 and 64 bit. Both compiled fine and seem to run OK.
Haven’t tried Vs yet though.
(Note: This was checked out prior to Manolo’s commits to address the VS2019 issues, though that does not seem to affect mingw builds anyway.)

Observations:

- As Albrecht noted, the rotated text looks disappointing. It doesn’t seem to be well AA’d at all, and just looks a bit messy.

Can confirm on rotated text:

See my previous comments; I think AA text may be off for some cases and on for others. Not sure why or how.
Here's a different font and set to a larger size, making it easy to see the horiz text is AA, but the rotated is not:


Manolo

unread,
Feb 5, 2021, 12:00:16 AM2/5/21
to fltk.coredev


On Thursday, February 4, 2021 at 10:50:29 PM UTC+1 imacarthur wrote:
Mnay thanks, Ian, for testing the GDI+ branch.

In fact, *all* text rendering looks a bit fuzzy, so it must be being anti-aliased in a different fashion from the Windows default.
I'm afraid you've not pulled a recent enough version of the code, because I have very recently introduced a change
that results in very sharp text rendering. Please, pull, clean, make and run anew.

- The line AA looks (mostly) pretty good, I liked that.
The text-related change is posterior to that for line antialiasing.


Question: Can we do a compromise that uses our existing text rendering scheme (which I think looks consistent with other Windows apps and generally looks pretty decent) but uses the AA GDI+ stuff for other rendering?
I would like you to, please, re-consider this question after having tried the new code.

Manolo

unread,
Feb 5, 2021, 2:53:06 AM2/5/21
to fltk.coredev
Many thanks  to Greg, Albrecht and Ian for all your testing.

Please pull from the git repository, to a01e74e or after. That should fix most of the issues reported.

@Albrecht: your patch is included, and VS now builds everything OK.

@Greg:
- The missing pixel at rectangle top-left should be fixed.
- As you have reported, antialiasing was missing for rotated text. That's now fixed.
- A more intensive text antialiasing option is now used. All font sizes should now
be antialiased. That's the same output I see when looking at system-generated text
under Windows 10. Under XP, system-generated text seems less antialiased.
I don't know the situation with Win8.
- Yes, it's possible to add an API to turn antialiasing off. Let's first agree on the default
behaviour.

For the aficionados, these are the 2 text antialiasing modes that we could hesitate between :
1) TextRenderingHintAntiAliasGridFit
:  Specifies that a character is drawn using its antialiased glyph bitmap and hinting. This results in much better quality due to antialiasing at a higher performance cost.
2) TextRenderingHintClearTypeGridFit  :  Specifies that a character is drawn using its glyph ClearType bitmap and hinting.

Mode 1 was used when Greg last tested GDI+. Some small fonts are not antialiased but larger sizes of the same font are.
Other fonts (e.g., bold ones) are antialiased at all sizes.

Mode 2 is in the current code. All text is antialiased, apparently the same way as system-generated text in Windows 10.


Greg Ercolano

unread,
Feb 5, 2021, 11:34:17 AM2/5/21
to fltkc...@googlegroups.com


On 2/4/21 11:53 PM, Manolo wrote:
Many thanks  to Greg, Albrecht and Ian for all your testing.

Please pull from the git repository, to a01e74e or after. That should fix most of the issues reported.

@Albrecht: your patch is included, and VS now builds everything OK.

@Greg:
- The missing pixel at rectangle top-left should be fixed.

    Yes, confirmed.

    And the "square" now renders correctly as a one pixel thick black
    instead of a 2 pixel width gray (probably AA line for a +0.5 pixel offset)



- As you have reported, antialiasing was missing for rotated text. That's now fixed.
- A more intensive text antialiasing option is now used. All font sizes should now
be antialiased. That's the same output I see when looking at system-generated text
under Windows 10. Under XP, system-generated text seems less antialiased.
I don't know the situation with Win8.

    Hmm, I think it's better than it was; just rotating without changing the font or size
    looks much better now than it did (non-GDI left, GDI+ right):



    ..but I'm still seeing full aliasing on most of the rotated text when I increase the size (with 09202a32b3c6f)..
    Left: GDI+ with font 0/size 64/angle 34, Right: linux with same settings:

 


Perhaps it's just how MS renders some fonts though.
For instance, after I took the above MS GDI+ screenshot, I changed to font 14, it's a bit better with the AA:

Anyway, certainly better than it was! In the old GDI, when I rotated the text, it was not only jaggy,
but it also jittered around, and letters would get too close or too far from one another. With GDI+
it rotated "smoothly"..


- Yes, it's possible to add an API to turn antialiasing off. Let's first agree on the default
behaviour.


Yep, OK

Ian MacArthur

unread,
Feb 5, 2021, 12:34:03 PM2/5/21
to fltkc...@googlegroups.com
On 5 Feb 2021, at 16:34, Greg Ercolano wrote:

Perhaps it's just how MS renders some fonts though.
For instance, after I took the above MS GDI+ screenshot, I changed to font 14, it's a bit better with the AA:


Well, I don’t know...
I tried a few fonts (in the rotated_text demo) and various sizes on the Win10 laptop. What I *think* I saw was:

Our “legacy” GDI version, the fonts were always better AA than the “new’ GDI+ version. Even horizontal text in the GDI+ version exhibited some jaggies on letter curves, that were much less apparent on the old GDI renders (when I screen grabbed them and zoomed way in...!)

-but-

The “legacy” GDI version is prone to the text jittering about as the words rotate (presumably because GDI does not support sub-pixel positioning whereas GDI+ does, at a guess.)


Reply all
Reply to author
Forward
0 new messages