GDI+, the beginnings of a class-based wrapper

Developed or developing a new product in PureBasic? Tell the world about it.
srod
PureBasic Expert
PureBasic Expert
Posts: 10589
Joined: Wed Oct 29, 2003 4:35 pm
Location: Beyond the pale...

GDI+, the beginnings of a class-based wrapper

Post by srod »

19th Oct 2010.
For those keeping track of progress, our full list of classes now runs as follows (c/c++ counterparts are in brackets)
  • BitmapData (BitmapData)
  • EncoderParameters (EncoderParameter and EncoderParameters)
  • Brush (Font)
  • Font (Font)
  • FontCollection (FontCollection, InstalledFontCollection and PrivateFontCollection)
  • FontFamily (FontFamily)
  • HatchBrush (HatchBrush)
  • Image (Bitmap and Image)
  • LinearGradientBrush (LinearGradientBrush)
  • Matrix (Matrix)
  • PointF (PointF)
  • PointI (Point)
  • PropertyItem (PropertyItem)
  • RectF (RectF)
  • RectI (Rect)
Each class comes with demos (all tested with x86 and x64) and some documentation. None of the demos currently render to screen etc. as that requires the 'Graphics' class which I have yet to do.

Progress will now slow down somewhat as the classes are getting bigger and bigger now. I am of course studying every facet of each function we import and so it will take a bit of time to complete this wrapper. A few weeks yet I reckon. In terms of functions imported from the GDI+ library, we are just under 25% of the way through. :)

More to follow. :)

Download

===============================


14th Oct 2010.
Have added the following classes (together with documentation and demos) :
  • Font
  • FontFamily
  • FontCollection
These mimic the c/c++ wrapper classes, Font, FontFamily, FontCollection, InstalledFontCollection and PrivateFontCollection.

Our full list of classes now runs as follows (c/c++ counterparts are in brackets)
  • REMOVED
More to follow. :)

Download

===============================


Hi,

in my concerted efforts to learn everything there is to learn about GDI+, and being a graduate of the 'diving in head first and learning by getting stuck in' university, I have started creating a class-based OOP wrapper around GDI+ (version 1.0) to basically mimic the MS c/c++ class wrapper (http://msdn.microsoft.com/en-us/library ... S.85).aspx)

Basically, GDI+ exports a flat-based c-style API. The class-based c/c++ wrapper is one of convenience and simplicity, breaking the 600+ functions exported by the flat API into a set of convenient classes. Most of the example code you will find scaterred about the web make use of this class-based wrapper (or the .Net equivalent) and so it is hoped that my wrapper will make code conversion somewhat simpler (no guarantees though!)

I intend adding as many classes as required for my own needs, but of course anticipate that this wrapper will grow with time.

So far I have wrapped the Bitmap and Image classes and a few sundry classes (e.g. encoder parameters). I make no real attempt to simplify access to GDI+ in any way, intending this to be no more than a Purebasic equivalent of the aforementioned c/c++ class wrapper. However, the differences between c++ and Purebasic have led me to simplify certain aspects of the GDI+ APIs. For example, I have added a CatchImage() type constructor as well as the ability to save an image directly to memory etc. I have also simplified access to encoder parameters which are always a pain in the a*se! :)

Each class I add comes with 101 or so demos since this is the best way for me to learn. There are also help documents for each class, though I have to say that they are very brief since you can simply turn to the relevant MSDN pages and MS has done a good job of documenting the c++ class methods.

I anticipate moving very fast now and will simply keep going until I have enough done to cater for my own immediate needs.

I am releasing a version now for two reasons. First, there may be a few people also wishing to delve head first into GDI+ and can use my work thus far to kick-start proceedings. God knows it has taken me long enough to get around to this. :) Secondly, I would be very keen to have others help out with this, perhaps adding a class or two or some additional demos etc. :wink: Anyone interested is asked to send me a pm so that we can ensure no duplication of work etc.

Every demo has been tested with both 32-bit and 64-bit versions of Purebasic (running under Vista).

Please read the "gdiPlus" help document before starting. You will find .doc and .pdf versions of this document within the download.

My thanks to Flype and SFSxOI for their various gdiPlus includes which I have used as reference material.

Download


Notes regarding GDI+.
I'll add to this as I proceed.
  • Support for icons seems poor, very poor in fact. GDI+ seems unable to deal with icons which exhibit an alpha-channel. The advice seems to be to bypass the icon decoder and load them up through other means.
  • Loading an image from a file locks the file whilst the resulting image is in use. This is because GDI+ sometimes discards the image memory when not in use and of course may subsequently have to reload the image data etc. This means that we can not overwrite an existing image file whilst the underlying image is in use. Work-around, use our gdiPlus_CatchImage() which, internally, stuffs the image data within a Stream object built upon a moveable hGlobal memory object.
  • Take care with retrieving font metrics when obtained through GDI+ as the process differs markedly from GDI in this regard. Take the business of retrieving a cell's 'ascent' when a font is in use with a particular device. With GDI we simply select the font into the HDC representing the device in question and issue the GetTextMetrics_() api function in order to retrieve a whole bunch of info, amongst which is the required ascent value.

    With GDI+ the situation seems, at first glance, somewhat backward. A quick glance at the 'Font' class (or the GDI+ flat API Font functions) and we see that there is no means of obtaining this metric without backtracking to GDI. Instead, we have to turn to the appropriate FontFamily class (or API) and issue the \GetCellAscent() method. With GDI+, we create a FontFamily object (which contains information on the font face etc.) before creating a font object housed 'within' this font family.

    The problem with this \GetCellAscent() method, however, is that our call to this method does not refer to any particular device! Instead, the metric returned is in what are termed 'font design units' (not pixels or points for example) and are meaningless outside of the font file itself! Such values cannot even be used to compare like for like quantities between two different fonts! Thus, in terms of our ascent metric for example, we are left with a value which is to all intents useless!

    Here's what we have to do. We must calculate the ratio of the actual line-height of our font when applied to a given device to the line spacing of the font-family when given the underlying font style. This ratio can then be used to adjust the font-family metrics when the associated font is to be rendered on the appropriate device. The ratio is calculated as font\GetHeightFromGraphics(...) / fontFamily\GetLineSpacing() etc.

    So, to get the actual ascent (in the underlying units of the graphics object) we simply multiply the ascent value obtained from the appropriate FontFamily object by this ratio.

    Seems backwards, but it is actually quite efficient really and, I have to say, that I like this better than the GDI method. Having a single ascent for the entire font-family kind of makes it 'cleaner' in a way. :)
  • GDI+ has Matrix transformations all backwards, forcing mathematicians (like myself) to switch their modes of thinking! :) Mathematics students the world over (as far as I know) are taught to represent linear transformations via matrices in a certain way in which the 'points' to be transformed are represented in column vector form. This is not the case with GDI+ in which such points are represented in row form and consequently lead to matrix representations of affine transformations which are essentially the 'transpose' of that which we might otherwise expect. Even Wikipedia details such transforms in the more traditional way, leading me to wonder why MS decided on this representation? Not that it makes any real practical difference of course, except that I have to reverse my thought processes. :)
Last edited by srod on Tue Oct 19, 2010 5:43 pm, edited 10 times in total.
I may look like a mule, but I'm not a complete ass.
User avatar
Fluid Byte
Addict
Addict
Posts: 2336
Joined: Fri Jul 21, 2006 4:41 am
Location: Berlin, Germany

Re: GDI+, the beginnings of a class-based wrapper

Post by Fluid Byte »

This is sheer awesomeness! Thank you very much Mr. Rodriguez!

PS: The file "image6.jpg" is your wife, right? :mrgreen:
Windows 10 Pro, 64-Bit / Whose Hoff is it anyway?
srod
PureBasic Expert
PureBasic Expert
Posts: 10589
Joined: Wed Oct 29, 2003 4:35 pm
Location: Beyond the pale...

Re: GDI+, the beginnings of a class-based wrapper

Post by srod »

Fluid Byte wrote:PS: The file "image6.jpg" is your wife, right? :mrgreen:
Ex-wife I'm afraid! :)

Actually, will have to ask Netmaestro where that photo came from as I stole it from him. :)
I may look like a mule, but I'm not a complete ass.
c4s
Addict
Addict
Posts: 1981
Joined: Thu Nov 01, 2007 5:37 pm
Location: Germany

Re: GDI+, the beginnings of a class-based wrapper

Post by c4s »

srod wrote:
Fluid Byte wrote:PS: The file "image6.jpg" is your wife, right? :mrgreen:
Ex-wife I'm afraid! :)

Actually, will have to ask Netmaestro where that photo came from as I stole it from him. :)
She's also in luis quantize example: http://www.purebasic.fr/english/viewtop ... 12&t=39606
:D
If any of you native English speakers have any suggestions for the above text, please let me know (via PM). Thanks!
rsts
Addict
Addict
Posts: 2736
Joined: Wed Aug 24, 2005 8:39 am
Location: Southwest OH - USA

Re: GDI+, the beginnings of a class-based wrapper

Post by rsts »

Wow :shock: This is great.

Good heavens man, where do you find the time?

Many thanks
User avatar
netmaestro
PureBasic Bullfrog
PureBasic Bullfrog
Posts: 8451
Joined: Wed Jul 06, 2005 5:42 am
Location: Fort Nelson, BC, Canada

Re: GDI+, the beginnings of a class-based wrapper

Post by netmaestro »

Support for icons seems poor, very poor in fact. GDI+ seems unable to deal with icons which exhibit an alpha-channel
:?: :shock:
BERESHEIT
User avatar
idle
Always Here
Always Here
Posts: 5899
Joined: Fri Sep 21, 2007 5:52 am
Location: New Zealand

Re: GDI+, the beginnings of a class-based wrapper

Post by idle »

you don't do things in halfs Srod, think that deserves a beer
I can't do anything about it today but will certainly help out if I can
Windows 11, Manjaro, Raspberry Pi OS
Image
srod
PureBasic Expert
PureBasic Expert
Posts: 10589
Joined: Wed Oct 29, 2003 4:35 pm
Location: Beyond the pale...

Re: GDI+, the beginnings of a class-based wrapper

Post by srod »

14th Oct 2010.
Have added the following classes (together with documentation and demos) :
  • Font
  • FontFamily
  • FontCollection
These mimic the c/c++ wrapper classes, Font, FontFamily, FontCollection, InstalledFontCollection and PrivateFontCollection.

Our full list of classes now runs as follows (c/c++ counterparts are in brackets)
  • BitmapData (BitmapData)
  • EncoderParameters (EncoderParameter and EncoderParameters)
  • Font (Font)
  • FontCollection (FontCollection, InstalledFontCollection and PrivateFontCollection)
  • FontFamily (FontFamily)
  • Image (Bitmap and Image)
  • PropertyItem (PropertyItem)
  • RectF (RectF)
More to follow. :)

Download
I may look like a mule, but I'm not a complete ass.
User avatar
DoubleDutch
Addict
Addict
Posts: 3220
Joined: Thu Aug 07, 2003 7:01 pm
Location: United Kingdom
Contact:

Re: GDI+, the beginnings of a class-based wrapper

Post by DoubleDutch »

Great stuff - thanks. :)
https://deluxepixel.com <- My Business website
https://reportcomplete.com <- School end of term reports system
srod
PureBasic Expert
PureBasic Expert
Posts: 10589
Joined: Wed Oct 29, 2003 4:35 pm
Location: Beyond the pale...

Re: GDI+, the beginnings of a class-based wrapper

Post by srod »

19th Oct 2010.
For those keeping track of progress, our full list of classes now runs as follows (c/c++ counterparts are in brackets)
  • BitmapData (BitmapData)
  • EncoderParameters (EncoderParameter and EncoderParameters)
  • Brush (Font)
  • Font (Font)
  • FontCollection (FontCollection, InstalledFontCollection and PrivateFontCollection)
  • FontFamily (FontFamily)
  • HatchBrush (HatchBrush)
  • Image (Bitmap and Image)
  • LinearGradientBrush (LinearGradientBrush)
  • Matrix (Matrix)
  • PointF (PointF)
  • PointI (Point)
  • PropertyItem (PropertyItem)
  • RectF (RectF)
  • RectI (Rect)
Each class comes with demos (all tested with x86 and x64) and some documentation. None of the demos currently render to screen etc. as that requires the 'Graphics' class which I have yet to do.

Progress will now slow down somewhat as the classes are getting bigger and bigger now. I am of course studying every facet of each function we import and so it will take a bit of time to complete this wrapper. A few weeks yet I reckon. In terms of functions imported from the GDI+ library, we are just under 25% of the way through. :)

More to follow. :)

Download
Last edited by srod on Tue Oct 19, 2010 5:44 pm, edited 3 times in total.
I may look like a mule, but I'm not a complete ass.
eesau
Enthusiast
Enthusiast
Posts: 589
Joined: Fri Apr 27, 2007 12:38 pm
Location: Finland

Re: GDI+, the beginnings of a class-based wrapper

Post by eesau »

Great work srod, I'm sure I'll find a use for this sooner or later. Two thumbs up :)
User avatar
flaith
Enthusiast
Enthusiast
Posts: 704
Joined: Mon Apr 25, 2005 9:28 pm
Location: $300:20 58 FC 60 - Rennes
Contact:

Re: GDI+, the beginnings of a class-based wrapper

Post by flaith »

i'll certainly find a way to use it, thanks for sharing srod, nice work :D
“Fear is a reaction. Courage is a decision.” - WC
eesau
Enthusiast
Enthusiast
Posts: 589
Joined: Fri Apr 27, 2007 12:38 pm
Location: Finland

Re: GDI+, the beginnings of a class-based wrapper

Post by eesau »

Does anyone have a backup copy of this? The links are sadly down.
User avatar
Danilo
Addict
Addict
Posts: 3036
Joined: Sat Apr 26, 2003 8:26 am
Location: Planet Earth

Re: GDI+, the beginnings of a class-based wrapper

Post by Danilo »

eesau wrote:Does anyone have a backup copy of this? The links are sadly down.
Backup: GDI+.zip (1,72MB)
User avatar
Teddy Rogers
User
User
Posts: 98
Joined: Sun Feb 23, 2014 2:05 am
Location: Australia
Contact:

Re: GDI+, the beginnings of a class-based wrapper

Post by Teddy Rogers »

I know this is an old topic of a few years, the dead never die! Just wanted to say thanks for this and to find out if the wrapper was ever completed?

Also does anyone have the gdiplus.chm file used here please?

http://purebasic.developpez.com/tutorie ... mentation/

Ted.
Post Reply