Declaration
TIECanvas = class;
Description
TIECanvas is a GDI+ Graphics wrapper and VCL TCanvas wrapper.
It is available via
TIEBitmap.IECanvas or by creating it from a TBitmap or TCanvas.

Methods and Properties
GeneralDraw MethodsFill MethodsText MethodsAdvanced Draw MethodsTransformation MethodsExamples
// Draw an envelope with 50% transparency
with ImageEnView1.IEBitmap.IECanvas do
begin
Pen.Mode := pmCopy;
Pen.Style := psSolid;
Pen.Color := clBlack;
Pen.Transparency := 128;
Brush.Color := clYellow;
Brush.Style := bsSolid;
Brush.Transparency := 128;
// Draw outer rect
Rectangle( 100, 100, 500, 300 );
// Draw flap
MoveTo( 100, 100 );
LineTo( 300, 200 );
LineTo( 500, 100 );
end;
ImageEnView1.Update();
// Draw an anti-aliased ellipse onto a TBitmap
iec := TIECanvas.Create( ABitmap.Canvas );
with iec do
begin
Pen.Style := psSolid;
Pen.Mode := pmCopy;
Pen.Color := clRed;
Brush.Style := bsClear
Ellipse( Rect( 100, 100, 200, 200 ));
end;
iec.Free;
// Fill image with a vertical gradient from Red to Blue
ImageEnView1.IEBitmap.IECanvas.GradientFillRect( Rect( 0, 0, ImageEnView1.IEBitmap.Width, ImageEnView1.IEBitmap.Height ), clRed, clBlue, gpgVertical );
ImageEnView1.Update();
// Draw a semi-transparent text box onto a bitmap
const
Horz_Margin = 8;
Vert_Margin = 3;
Center_Text = False;
var
x, y: integer;
tw, rw, rh: integer;
iec: TIECanvas;
ss: string;
begin
ss := 'This is my text';
x := 100;
y := 100;
iec := TIECanvas.Create( Bitmap.Canvas );
iec.Font.Assign( GetTextFont() );
tw := iec.TextWidth(ss);
rw := imax( tw + 2 * Horz_Margin, iec.TextWidth(minText) + 2 * Horz_Margin );
rh := iec.TextHeight(ss) + 2 * Vert_Margin;
if Center_Text then
dec( x, rw div 2 );
iec.Brush.Color := clYellow;
iec.Brush.Style := bsSolid;
iec.Brush.Transparency := 196;
iec.Pen.Color := clBlack;
iec.Pen.Style := psSolid;
iec.Rectangle( x, y, x + rw, y + rh );
iec.Brush.Style := bsClear;
iec.TextOut(x + ( rw - tw ) div 2, y + Vert_Margin, ss);
iec.Free;
end;
// Highlight an area of a bitmap
iec := TIECanvas.Create( Bitmap.Canvas, false );
iec.Brush.Color := clRed;
iec.Brush.Style := bsSolid;
iec.Brush.Transparency := 125;
iec.FillRect( Rect( 100, 100, 300, 300 );
iec.Free;
// Draw a rounded, semi-transparent scrollbar (anti-aliased)
const
RX = 12; // round width
RY = 12; // round height
MINSLIDERW = 8; // minimum slider width
var
scrollPos, scrollCount: integer;
sliderWidth: double;
begin
x := 100;
y := 100;
Width := 300;
Height := 16;
scrollCount := 20;
scrollPos := 3;
with ImageEnView1.IEBitmap.IECanvas do
begin
// paint brush and border
Brush.Style := bsSolid;
Brush.Color := clWhite;
Brush.Transparency := 64;
Pen.Color := clWhite;
Pen.Style := psSolid;
Pen.Mode := pmCopy;
Pen.Width := 1;
Pen.Transparency := 128;
RoundRect( x, y, x + width, y + height, RX, RY );
// paint slider
Brush.Style := bsSolid;
Brush.Color := clBlack;
Brush.Transparency := 128;
Pen.Width := 1;
Pen.Transparency := 128;
sliderWidth := width / scrollCount;
if sliderWidth < MINSLIDERW then
sliderWidth := MINSLIDERW;
RoundRect( x + trunc(scrollPos * sliderWidth), y + 1, x + trunc(scrollPos * sliderWidth) + trunc(asliderWidth), y + height - 1, RX, RY);
end;
end;
// Draw an arrow at the end of a line that runs from x1, y1 to x2, y2
// brush and color must be already set
procedure IEDrawLineArrow(Canvas: TIECanvas; x1, y1, x2, y2: integer; w, h: integer);
const
A90 = PI / 2;
var
aa, bb, hw: double;
pp: array[0..2] of TPoint;
p1x, p1y: integer;
begin
with Canvas do
begin
hw := w / 2;
aa := IEAngle(x1, y1, x2, y2, x1, y2);
if x1 = x2 then
if y1 < y2 then
aa := -A90
else
aa := A90;
if ((x1 > x2) and (y2 < y1)) or ((x1 < x2) and (y1 < y2)) then
bb := 2 * pi - aa + A90
else
bb := aa + A90;
if ((x2 < x1) and (y2 > y1)) or ((x2 < x1) and (y2 < y1)) or ((x1 < x2) and (y1 = y2)) then
begin
p1x := x1 + trunc(cos(bb - A90) * h);
p1y := y1 + trunc(sin(bb - A90) * h);
end
else
begin
p1x := x1 + trunc(cos(bb + A90) * h);
p1y := y1 + trunc(sin(bb + A90) * h);
end;
pp[0].x := p1x + trunc(cos(bb) * hw);
pp[0].y := p1y + trunc(sin(bb) * hw);
pp[1].x := p1x + trunc(cos(bb + pi) * hw);
pp[1].y := p1y + trunc(sin(bb + pi) * hw);
pp[2].x := x1;
pp[2].y := y1;
Polygon(pp);
end;
end;
// Draw one of ImageEn's predefined shapes
procedure IEDrawShape(Canvas: TIECanvas;
Shape: TIEShape;
Left, Top, Width, Height: Integer; MaintainAspect: TIEBooleanEx;
BorderColor: TColor; BorderWidth: Integer;
FillColor: TColor; FillColor2: TColor = clNone; FillGradient: TIEGDIPlusGradient = gpgVertical;
AntiAlias: Boolean = True;
Angle: Integer = 0;
ShapeModifier: Integer = 0);
var
arPts : Array[ 0 .. Max_Shape_Array_Points ] of TPoint;
drawPts : Array[ 0 .. Max_Shape_Array_Points ] of TPoint;
currX, currY: Integer;
exWidth, exHeight: Integer;
i: Integer;
ptCount: Integer;
begin
IEGenerateShapePoints( arPts, ptCount, Shape, 0, 0, 1000, 1000,
Angle, False,
ShapeModifier,
Width / Height );
if BorderColor = clNone then
BorderWidth := 0;
exWidth := imax( 0, ( Width - BorderWidth ));
exHeight := imax( 0, ( Height - BorderWidth ));
for i := 0 to ptCount - 1 do
begin
currX := arPts[ i ].x;
currY := arPts[ i ].y;
drawPts[i].x := Left + BorderWidth div 2 + round( currX / 1000 * exWidth );
drawPts[i].y := Top + BorderWidth div 2 + round( currY / 1000 * exHeight );
end;
// PAINT TO CANVAS
if AntiAlias then
Canvas.SmoothingMode := iesmAntialias
else
Canvas.SmoothingMode := iesmBestPerformance;
with Canvas do
begin
if BorderWidth > 0 then
begin
Pen.Style := psSolid;
Pen.Width := BorderWidth;
Pen.Color := BorderColor;
end
else
Pen.Style := psClear;
Pen.Mode := pmCopy;
Pen.LineJoin := ieljRound;
if FillColor = clNone then
Brush.Style := bsClear
else
begin
Brush.Color := FillColor;
Brush.Style := bsSolid;
end;
if FillColor2 = clNone then
Brush.SetGradient( gpgNone, 0, 0 )
else
begin
Brush.SetGradient( FillGradient, Width, Height );
Brush.BackTransparency := 255;
Brush.BackColor := FillColor2;
end;
Polygon( slice( drawpts, ptCount ));
end;
end;
// Draw an ellipse
procedure IEDrawSimpleShape(Canvas: TIECanvas;
Left, Top, Width, Height: Integer;
BorderColor: TColor; BorderWidth: Integer;
FillColor: TColor; FillColor2: TColor = clNone;
FillGradient: TIEGDIPlusGradient = gpgVertical;
ZoomX: Double = 1; ZoomY: Double = 1;
AntiAlias: Boolean = True);
const
Rect_Rounding = 20;
var
drawGradient: Boolean;
minZoom: Double;
begin
drawGradient := ( FillGradient <> gpgNone ) and
( FillColor2 <> FillColor ) and
( FillColor <> clNone ) and ( FillColor2 <> clNone );
if AntiAlias then
Canvas.SmoothingMode := iesmAntialias
else
Canvas.SmoothingMode := iesmBestPerformance;
// Image has been scaled to zoom level, so ensure we scale the border too
if BorderColor = clNone then
BorderWidth := 0;
if BorderWidth > 0 then
BorderWidth := max( 1, Round( BorderWidth * minZoom ));
// Border
if ( BorderColor = clNone_ ) or ( BorderWidth < 1 ) then
Canvas.Pen.Style := psClear
else
Canvas.Pen.Style := psSolid;
Canvas.Pen.Color := BorderColor;
Canvas.Pen.Width := BorderWidth;
// Fill
if ( FillColor = clNone_ ) then
Canvas.Brush.Style := bsClear
else
Canvas.Brush.Style := bsSolid;
Canvas.Brush.Color := FillColor;
inc( Left , BorderWidth div 2 );
inc( Top , BorderWidth div 2 );
dec( Width , BorderWidth );
dec( Height, BorderWidth );
if drawGradient = False then
Canvas.Brush.SetGradient( gpgNone, 0, 0 )
else
begin
Canvas.Brush.SetGradient( FillGradient, Width, Height );
Canvas.Brush.BackTransparency := 255;
Canvas.Brush.BackColor := FillColor2;
end;
Canvas.Ellipse( Left, Top, Left + Width, Top + Height );
end;
// Draw text within a specified area onto a TIEBitmap
procedure TextOutEx(aBMP: TIEBitmap;
X, Y, W, H : Integer; const Text : String;
const sFontName : String; iFontSize : Integer; cFontColor : TColor; Style : TFontStyles;
Angle : Integer = 0;
bAntiAlias : Boolean = true; bAutoEnlarge : Boolean = False);
var
AnExtent: TSize;
Mask: TIEMask;
x1, y1, x2, y2: Integer;
CompCanvas: TIECanvas;
iAlpha: Integer;
begin
aBMP.Canvas.Font.Name := sFontName;
aBMP.Canvas.Font.Size := iFontSize;
aBMP.Canvas.Font.Color := cFontColor;
aBMP.Canvas.Font.Style := Style;
AnExtent := aBMP.IECanvas.MeasureText( Text );
if Angle <> 0 then
AnExtent := IERotatePoint2( AnExtent.cx, AnExtent.cy, Angle );
if bAutoEnlarge and (( aBMP.Width < AnExtent.cx ) or ( aBMP.Height < AnExtent.cy )) then
begin
iAlpha := 255;
if aBMP.HasAlphaChannel then
iAlpha := aBMP.Alpha[0, 0];
aBMP.Resize( iMax( aBMP.Width, AnExtent.cx ), iMax( aBMP.Height, AnExtent.cy ), Background, iAlpha);
end;
CompCanvas := aBMP.CreateROICanvas(Rect(0, 0, aBMP.Width, aBMP.Height), bAntiAlias, true, bAntiAlias);
try
if not bAntiAlias then // Cannot use together with alpha composting
CompCanvas.TextRendering := ietrTextRenderingHintSingleBitPerPixel;
CompCanvas.Brush.Color := aBMP.Canvas.Font.Color;
CompCanvas.Font.Color := aBMP.Canvas.Font.Color;
CompCanvas.Font.Name := aBMP.Canvas.Font.Name;
CompCanvas.Font.Height := aBMP.Canvas.Font.Height;
CompCanvas.Font.Style := aBMP.Canvas.Font.Style;
if ( W = 0 ) and ( H = 0 ) then
CompCanvas.DrawText( Text, X, Y, -Angle )
else
CompCanvas.DrawText( Text, Rect( X, Y, X + W, Y + H ), -Angle );
finally
CompCanvas.Free();
end;
end;