ImageEn, unit iegdiplus

TIECanvas

Properties · Methods · Examples

Declaration

TIECanvas = class;


Description

TIECanvas is a wrapper for GDI+ and TCanvas, and supports anti-aliasing, alpha merging, and advanced drawing methods.
It is available via TIEBitmap.IECanvas or by creating it from a TBitmap or TCanvas.

    

Methods and Properties


General
Public Property  Brush
Public Property  Create
Public Property  InterpolationMode
Public Property  Pen
Public Property  PenPos
Public Method  SetCompositingMode
Public Method  SetClipRect
Public Property  SmoothingMode

Draw Methods
Public Method  Arc
Public Method  DrawCurvedLine
Public Method  DrawImage
Public Method  DrawLine
Public Method  DrawLines
Public Method  DrawLinesPath
Public Method  DrawRects
Public Method  Ellipse
Public Method  LineTo
Public Method  MoveTo
Public Method  Pie
Public Method  Polygon
Public Method  PolygonD
Public Method  Polyline
Public Method  PolylineD
Public Method  Rectangle
Public Method  RoundRect

Fill Methods
Public Method  FillRect
Public Method  GradientFillRect

Text Methods
Public Method  DrawText
Public Property  Font
Public Method  MeasureText
Public Property  TextStyling
Public Method  TextExtent
Public Method  TextHeight
Public Method  TextWidth
Public Property  TextRendering
Public Property  TypographicDrawText

Advanced Draw Methods
Public Method  AdvancedDrawAngle
Public Method  AdvancedDrawLine
Public Method  AdvancedDrawPolyline
Public Method  AdvancedDrawShape
Public Method  AdvancedDrawText

Transformation Methods
Public Method  CreateMatrix
Public Method  DeleteMatrix
Public Method  ResetTransform
Public Method  Rotate
Public Method  MatrixTransform
Public Method  Translate

Examples


// Fill image with a vertical gradient from yellow to red
ImageEnView1.IEBitmap.IECanvas.GradientFillRect( Rect( 0, 0, ImageEnView1.IEBitmap.Width, ImageEnView1.IEBitmap.Height ), clYellow, clRed, gpgVertical );
ImageEnView1.Update();



// 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 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.Size := 30;
  iec.Font.Style := [fsBold];

  tw := iec.TextWidth(ss);
  rw := imax( tw + 2 * Horz_Margin, iec.TextWidth( ss ) + 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;



// Gradient text with border
ImageEnView1.IEBitmap.IECanvas.Font.Size  := 54;
ImageEnView1.IEBitmap.IECanvas.Font.Style := [fsBold];
ImageEnView1.IEBitmap.IECanvas.Font.Color := clRed;
ImageEnView1.IEBitmap.IECanvas.TextStyling.BorderWidth := 3;
ImageEnView1.IEBitmap.IECanvas.TextStyling.BorderColor := clBlack;
ImageEnView1.IEBitmap.IECanvas.TextStyling.FillColor2 := clYellow;
ImageEnView1.IEBitmap.IECanvas.TextStyling.FillGradient := gpgVertical;
ImageEnView1.IEBitmap.IECanvas.DrawText( 'ImageEn!', 280, 200 );
ImageEnView1.Update();



// 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( 650, 680, 850, 780 ));
iec.Free();



// Draw an anti-aliased ellipse onto a TBitmap
iec := TIECanvas.Create( ABitmap.Canvas );
with iec do
begin
  Pen.Style := psSolid;
  Pen.Width := 3;
  Pen.Mode  := pmCopy;
  Pen.Color := clRed;
  Brush.Style := bsClear;
  Ellipse( Rect( 100, 100, 200, 200 ));
end;
iec.Free();



// Method to draw one of ImageEn's predefined shapes to a canvas
procedure IEDrawShape(Canvas: TIECanvas;
                      Shape: TIEShape;
                      Left, Top, Width, Height: Integer;
                      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;

                  


// Method to draw a styled ellipse to a canvas
procedure IEDrawSimpleShape(Canvas: TIECanvas;
                            Left, Top, Width, Height: Integer;
                            BorderColor: TColor; BorderWidth: Integer;
                            FillColor: TColor; FillColor2: TColor = clNone;
                            FillGradient: TIEGDIPlusGradient = gpgVertical;
                            AntiAlias: Boolean = True);
const
  Rect_Rounding = 20;
var
  drawGradient: Boolean;
begin
  drawGradient := ( FillGradient <> gpgNone ) and
                  ( FillColor2 <> FillColor ) and
                  ( FillColor <> clNone ) and ( FillColor2 <> clNone );

  if AntiAlias then
    Canvas.SmoothingMode := iesmAntialias
  else
    Canvas.SmoothingMode := iesmBestPerformance;

  // 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;



// Method to draw text within an area of 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;



// Draw a pointer
ImageEnView1.IEBitmap.IECanvas.AdvancedDrawLine( 40, 30, 200, 100,
                                                 clBlack, 2,
                                                 ieesArrow, ieesCircle,
                                                 20, clRed );
ImageEnView1.Update();



// Draw a line pointer with a label
ImageEnView1.IEBitmap.IECanvas.Font.Name  := 'Tahoma';
ImageEnView1.IEBitmap.IECanvas.Font.Size  := 8;
ImageEnView1.IEBitmap.IECanvas.Font.Style := [fsBold];
ImageEnView1.IEBitmap.IECanvas.Font.Color := clBlack;
ImageEnView1.IEBitmap.IECanvas.AdvancedDrawLine( 140, 30, 240, 100,
                                                 clBlack, 2,
                                                 ieesArrow, ieesNone,
                                                 20, clRed,
                                                 ielpAtEnd, 'Labeled Pointer',
                                                 nil, True,
                                                 iesRectangle, clRed, clYellow,
                                                 gpgVertical );
ImageEnView1.Update();



// Draw a filled 5-pointed star
var
  pp: array[0..10] of TPoint;
begin
  ImageEnView1.IEBitmap.IECanvas.Pen.Color := clOrangeRed;
  ImageEnView1.IEBitmap.IECanvas.Pen.Width := 3;
  ImageEnView1.IEBitmap.IECanvas.Brush.Color := clYellow;

  pp[0]  := Point(175, 50);
  pp[1]  := Point(205, 145);
  pp[2]  := Point(300, 145);
  pp[3]  := Point(225, 205);
  pp[4]  := Point(253, 300);
  pp[5]  := Point(175, 243);
  pp[6]  := Point(98 , 300);
  pp[7]  := Point(128, 205);
  pp[8]  := Point(50 , 145);
  pp[9]  := Point(148, 145);
  pp[10] := Point(175, 50);

  ImageEnView1.IEBitmap.IECanvas.Polygon(pp);
  ImageEnView1.Update();
end;



// Draw an arrow shape
ImageEnView1.IEBitmap.IECanvas.AdvancedDrawShape( 50, 50, 150, 150,
                                                  iesShootingArrowSE, 0, 0,          // Shape Props
                                                  clBlack, 2, 1.0,                   // Border Props
                                                  clYellow, clRed, gpgVertical, 1.0, // Fill Props
                                                  True );
ImageEnView1.Update();



// Draw a pink balloon
ImageEnView1.IEBitmap.Allocate( 600, 800 );
ImageEnView1.IEBitmap.Fill( clWhite );
ImageEnView1.IEBitmap.IECanvas.AdvancedDrawShape( 0, 0,
                                                  ImageEnView1.IEBitmap.Width,
                                                  ImageEnView1.IEBitmap.Height,
                                                  iesBalloon, 0, 0,                   // Shape parameters
                                                  clBlack, 2, 1.0,                    // Border parameters
                                                  $00921CF0, clNone, gpgNone, 1.0,    // Fill parameters
                                                  True );
ImageEnView1.Update();



// Draw a cross
var
  pts: array of TPoint;
begin
  SetLength( pts, 12 );
  pts[0] := Point( 50, 0 );
  pts[1] := Point( 100, 50 );
  pts[2] := Point( 150, 0 );
  pts[3] := Point( 200, 50 );
  pts[4] := Point( 150, 100 );
  pts[5] := Point( 200, 150 );
  pts[6] := Point( 150, 200 );
  pts[7] := Point( 100, 150 );
  pts[8] := Point( 50, 200 );
  pts[9] := Point( 0, 150 );
  pts[10] := Point( 50, 100 );
  pts[11] := Point( 0, 50 );

  ImageEnView1.IEBitmap.IECanvas.AdvancedDrawPolyline( pts, True,
                                                       clBlack, 2, 1.0,                       // Line Props
                                                       clYellow, clRed, gpgDiagCenter, 1.0 ); // Fill Props
  ImageEnView1.Update();
end;



// Draw a custom rounded, semi-transparent scrollbar
const
  RX         = 12;  // round width
  RY         = 12;  // round height
  MINSLIDERW = 8;   // minimum slider width
var
  scrollPos, scrollCount: integer;
  sliderWidth: double;
  x, y, Width, Height: Integer;
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(sliderWidth), y + height - 1, RX, RY);
  end;
  ImageEnView1.Update();
end;



// Method to draw a pointer arrow from LineX1,LineY1 to LineX2, LineY2
// IEDrawLineArrow( ImageEnView1.IEBitmap.IECanvas, 650, 680, 850, 780, 30, 30, clBlack, 2, clYellow );
// ImageEnView1.Update();
procedure IEDrawLineArrow(Canvas: TIECanvas; LineX1, LineY1, LineX2, LineY2: integer; ArrowW, ArrowH: integer;
                          BorderColor: TColor; BorderWidth: Integer; FillColor: TColor);
const
  A90 = PI / 2;
var
  aa, bb, hw: double;
  pp: array[0..2] of TPoint;
  p1x, p1y: integer;
begin
  // 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;

  Canvas.DrawLine( LineX1, LineY1, LineX2, LineY2 );

  hw := ArrowW / 2;
  aa := IEAngle( LineX1, LineY1, LineX2, LineY2, LineX1, LineY2 );
  if LineX1 = LineX2 then
    if LineY1 < LineY2 then
      aa := -A90
    else
      aa := A90;
  if ((LineX1 > LineX2) and (LineY2 < LineY1)) or ((LineX1 < LineX2) and (LineY1 < LineY2)) then
    bb := 2 * pi - aa + A90
  else
    bb := aa + A90;
  if ((LineX2 < LineX1) and (LineY2 > LineY1)) or ((LineX2 < LineX1) and (LineY2 < LineY1)) or ((LineX1 < LineX2) and (LineY1 = LineY2)) then
  begin
    p1x := LineX1 + trunc(cos(bb - A90) * ArrowH);
    p1y := LineY1 + trunc(sin(bb - A90) * ArrowH);
  end
  else
  begin
    p1x := LineX1 + trunc(cos(bb + A90) * ArrowH);
    p1y := LineY1 + trunc(sin(bb + A90) * ArrowH);
  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 := LineX1;
  pp[2].y := LineY1;

  Canvas.Polygon(pp);
end;