Friday, 29 January 2010

gdiplus.lib is inside Windows SDK

I'm developing my C++ applications on VS2008 and Vista OS, and need to add gdiplus.lib on my Project/Properties/Linker/General/Application&Liberary&Directoris.

1- First read those links (if you prefer):
Microsoft Windows SDK Blog
Windows SDK
Which SDK is Right for Me?

Using GDI+ with MFC or native C/VC++


2- Download and install ISO image of:
Windows SDK for Windows Server 2008 and .NET Framework 3.5

It provides the documentation, samples, header files, libraries, and tools (including C++ compilers) that you need to develop applications to run on Windows Server 2008 and the .NET Framework 3.5. This SDK is compatible with Visual Studio® 2008, including Visual Studio Express Editions, which are available free of charge.

3- Download and installing exe file of:
Microsoft Visual Studio 2008 Service Pack 1 Update (KB974479)

There is a known incompatibility between the Microsoft Windows Software Development Kit for Windows Server 2008 and .NET Framework 3.5, and Microsoft Visual Studio 2008 Service Pack 1 which is manifested when the ATL Security Update (KB971092) is installed. This update addresses the issue. After you install this update, you may have to restart your computer.

Use Virtual-CD to open ISO

Allow autorun to start installing SDK

When installation is finished, then restart and then install KB974479

Right click project name and select Properties

Add libarary directory to General/Additional Library Directories

Add Gdiplus.lib to input/Aditional Dependencies, you may instead use "#pragma comment(lib,"gdiplus.lib")"

Adjust your stdafx.h by adding appropriate header, namespace and pragma "if pragma is needed"
declare tokken member in CWinAppEx drived class

Initialize GDI+ inside CwinAppEx::InitInstance

Finalize GDI+ at the end of your application CWinAppEx::ExitInstance
Start using GDI+ functionality to render your document

Wednesday, 27 January 2010

GDI+ overview

GDI+

Download details: Platform SDK Redistributable: GDI+

Purpose. Microsoft Windows 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.

Three parts of GDI+:

1- 2-D vector graphics
2- Imaging
3- Typography

The Structure of the Class-Based Interface:

The C++ interface to Microsoft Windows GDI+ contains about 40 classes, 50 enumerations, and 6 structures. There are also a few functions that are not members of any class. The Graphics class is the core of the GDI+ interface; it is the class that actually draws lines, curves, figures, images, and text.

Many classes work together with the Graphics class. For example, the Graphics::DrawLine method receives a pointer to a Pen object, which holds attributes (color, width, dash style, and the like) of the line to be drawn. The Graphics::FillRectangle method can receive a pointer to a LinearGradientBrush object, which works with the Graphics object to fill a rectangle with a gradually changing color. Font and StringFormat objects influence the way a Graphics object draws text. A Matrix object stores and manipulates the world transformation of a Graphics object, which is used to rotate, scale, and flip images.

Certain classes serve primarily as structured data types. Some of those classes (for example, Rect, Point, and Size) are for general purposes. Others are for specialized purposes and are considered helper classes. For example, the BitmapData class is a helper for the Bitmap class, and the PathData class is a helper for the GraphicsPath class. GDI+ also defines a few structures that are used for organizing data. For example, the ColorMap structure holds a pair of Color objects that form one entry in a color conversion table.

GDI+ defines several enumerations, which are collections of related constants. For example, the LineJoin enumeration contains the elements LineJoinBevel, LineJoinMiter, and LineJoinRound, which specify styles that can be used to join two lines.

GDI+ provides a few functions that are not part of any class. Two of those functions are GdiplusStartup and GdiplusShutdown. You must call GdiplusStartup before you make any other GDI+ calls, and you must call GdiplusShutdown when you have finished using GDI+.



New Features:

Gradient Brushes
GDI+ expands on Windows Graphics Device Interface (GDI) by providing linear gradient and path gradient brushes for filling shapes, paths, and regions. Gradient brushes can also be used to draw lines, curves, and paths. When you fill a shape with a linear gradient brush, the color gradually changes as you move across the shape. For example, suppose you create a horizontal gradient brush by specifying blue at the left edge of a shape and green at the right edge. When you fill that shape with the horizontal gradient brush, it will gradually change from blue to green as you move from its left edge to its right edge. Similarly, a shape filled with a vertical gradient brush will change color as you move from top to bottom. The following illustration shows an ellipse filled with a horizontal gradient brush and a region filled with a diagonal gradient brush.



When you fill a shape with a path gradient brush, you have a variety of options for specifying how the colors change as you move from one portion of the shape to another. One option is to have a center color and a boundary color so that the pixels change gradually from one color to the other as you move from the middle of the shape towards the outer edges. The following illustration shows a path (created from a pair of Bézier splines) filled with a path gradient brush.




Cardinal Splines
GDI+ supports cardinal splines, which are not supported in GDI. A cardinal spline is a sequence of individual curves joined to form a larger curve. The spline is specified by an array of points and passes through each point in that array. A cardinal spline passes smoothly (no sharp corners) through each point in the array and thus is more refined than a path created by connecting straight lines. The following illustration shows two paths, one created by connecting straight lines and one created as a cardinal spline.




Independent Path Objects
In GDI, a path belongs to a device context, and the path is destroyed as it is drawn. With GDI+, drawing is performed by a Graphics object, and you can create and maintain several GraphicsPath objects that are separate from the Graphics object. A GraphicsPath object is not destroyed by the drawing action, so you can use the same GraphicsPath object to draw a path several times.


Transformations and the Matrix Object
GDI+ provides the Matrix object, a powerful tool that makes transformations (rotations, translations, and so on) easy and flexible. A matrix object works in conjunction with the objects that are transformed. For example, a GraphicsPath object has a Transform method that receives the address of a Matrix object as an argument. A single 3×3 matrix can store one transformation or a sequence of transformations. The following illustration shows a path before and after a sequence of two transformations (first scale, then rotate).




Scalable Regions

GDI+ expands greatly on GDI with its support for regions. In GDI, regions are stored in device coordinates, and the only transformation that can be applied to a region is a translation. GDI+ stores regions in world coordinates and allows a region to undergo any transformation (scaling, for example) that can be stored in a transformation matrix. The following illustration shows a region before and after a sequence of three transformations: scale, rotate, and translate.

Alpha Blending
Note that in the previous figure, you can see the untransformed region (filled with red) through the transformed region (filled with a hatch brush). This is made possible by alpha blending, which is supported by GDI+. With alpha blending, you can specify the transparency of a fill color. A transparent color is blended with the background color — the more transparent you make a fill color, the more the background shows through. The following illustration shows four ellipses that are filled with the same color (red) at different transparency levels.



Support for Multiple Image Formats
GDI+ provides the Image, Bitmap, and Metafile classes, which allow you to load, save and manipulate images in a variety of formats. The following formats are supported:
BMP
Graphics Interchange Format (GIF)
JPEG
Exif
PNG
TIFF
ICON
WMF
EMF


GDI Mapping Modes Explaind


GDI Mapping Modes Explained

Date: 8 May 1997
Author: Rich Goldstein, MD (goldstei@interport.net)


NOTE: Also, take a look this article (http://www.bobpowell.net/mappingmodes.htm)


Overview

Each device context (DC, represented by TDC and derivatives in OWL) has the ability to maintain a coordinate system separate and distinct from the device it represents. So while the display may be a 640x480 or 800x600 or whatever pixels in dimension, we can tell the DC that the coordinate space uses some other units.

The result is the existence of 2 coordinate systems: the DEVICE coordinate system, and the LOGICAL coordinate system.

In general, DEVICE coordinates are established by the device or it's related drivers. So for the monitor, the display driver determines the DEVICE coordinates (0,0 in the top left, width,height in pixels in the lower right). These are rarely if ever changed programmatically (the exceptions, of course, include changing screen or printer resolution, or paper orientation, etc.).

The LOGICAL coordinates relate to the device context (DC) and are established by the mapping mode, viewport origin and extents, and window origin and extents. All DC related functions accept LOGICAL coordinates, unless explicitly stated (e.g. DPtoLP, which converts DEVICE coordinates to LOGICAL coordinates).

The system maps your LOGICAL coordinates to the DEVICE coordinates using the viewport/window origins and extents.


So WHAT ARE THEY, ALREADY???

Origins

OK, let's start with the window, which is expressed in LOGICAL coordinates.

SetWindowOrg() tells the DC the LOGICAL point that maps to the DEVICE point (0,0). So if you call SetWindowOrg(100,100) for a window, the LOGICAL point (100,100) occurs in the top left corner. (Hold on, this was the easy one...)

SetViewportOrg() tells the DC which DEVICE coordinate maps to LOGICAL point (0,0). So calling SetViewportOrg() with half the width and height of your window (in pixels), for example, sets the LOGICAL point (0,0) to the center of the window.

SetWindowOrg() and SetViewportOrg() can be called on any Mapping Mode. They serve to offset the origin of one system within the other. They have no effect on the relative distances specified by the two coordinate systems.







Mapping Modes

There are several mapping modes, some of which are constrained to a fixed relationship between DEVICE and LOGICAL coordinate systems.
Here is the list:

Name/Constant          Constrained?           Logical Unit  
MM_TEXT (default)           Yes                             Pixel  
MM_LOENGLISH               Yes                            0.01 inch  
MM_HIENGLISH                Yes                            0.001 inch  
MM_LOMETRIC                Yes                            0.1 mm  
MM_HIMETRIC                 Yes                             0.01 mm  
MM_TWIPS                      Yes                             1/20 of a point, or 1/1440 of an inch
 
MM_ISOTROPIC              No                              User Defined  
MM_ANISOTROPIC         No                              User Defined



For the 'constrained' modes, all you are allowed is to change the origin of the logical system using either SetWindowOrg or SetViewportOrg.

This means that if I set the mapping mode to MM_LOENGLISH, the point (0,0) and (0,100) are 1 inch apart (1 Logical inch, defined by the device capabilities, see GetDeviceCaps())


Extents

The extent is the maximum value of an axis. Extents are a little trickier, because how they are interpreted depends on the mapping mode. They are only appropriate for the non-constrained modes, MM_ISOTROPIC and MM_ANISOTROPIC.

The difference between these two modes is that MM_ISOTROPIC takes the parameters you pass to SetViewportExt and SetWindowExt as 'suggestions' (see below) and adjusts the extents so the the x and y axis coordinates represent the same distance on the device. This way, a LOGICAL unit in the x direction is the same length (in terms of the output) as a LOGICAL unit in the y direction (this is not intuitive... some printers may have different resolutions in the two axes... this mode ensures that the LOGICAL units are equivalent in space).

MM_ANISOTROPIC differs in that the parameters passed to SetViewportExt and SetWindowExt are taken literally. Windows make no adjustment. Therefore, you can have very different coordinate systems in the two axes.

SetWindowExt and SetViewportExt are used as a team. These two functions set some internal members in the DC, which are used to map points between coordinate systems. As such, each is essentially meaningless taken alone.

SetWindowExt tells the DC that a rectangle with the LOGICAL width and height passed in, has the DEVICE width and height passed in via SetViewportExt. Confused yet?

Let's say that I call SetViewportExt for a display device with the parameters 100,50. Taken alone, that's rather meaningless. Now I call SetWindowExt with parameters 100,100. This means that for each LOGICAL unit in the x direction, I will move 1 DEVICE unit. On the other hand, for each LOGICAL unit I move in the y direction, I move 1/2 a unit in the DEVICE coordinate.

These functions can also be called with negative numbers. When the sign of the parameters to SetWindowExt and SetViewportExt a different, the direction of the axes changes. So that the positive y direction can be up, instead of the usual default of down, if I call:
SetWindowExt(1,-1);
SetViewportExt(1,1);

One LOGICAL x unit translates to 1 DEVICE x unit, but 1 LOGICAL y unit translates to 1 DEVICE y unit, in the opposite direction.

Basically, here is the formula used (by Windows) to convert LOGICAL points to DEVICE points:

where xD = the DEVICE coordinate
and xL = the LOGICAL coordinate

xD = (xL - xWindowOrg)*(xViewportExt/xWindowExt) + xViewportOrg

If that makes anything clearer.
How Windows handles extents for MM_ISOTROPIC

Assuming that SetWindowExt is called BEFORE SetViewportExt (recommended), how the adjustments are made depends on the actual physical dimensions of the extents passed to SetViewportExt. Since device coordinates are not necessarily in equal units in the two axes, they are probably adjusted internally according to LOGPIXELSX/LOGPIXELSY.

If the physical dimensions of the Viewport Extents are wider than they are tall, the x extent is adjusted so that it's LOGICAL units are equal to the LOGICAL units for the y axis (as defined by the y parameters passed to SetWindowExt / SetViewportExt).

If the physical dimensions of the Viewport Extents are taller than they are wide, the y extent is adjusted.