[fpc-pascal] FPC Graphics options?

Graeme Geldenhuys mailinglists at geldenhuys.co.uk
Mon May 15 13:32:34 CEST 2017


On 2017-05-15 11:51, James Richters wrote:
ication to be a 64bit
> application.  I have installed
> 'fpc-3.0.2.i386-win32.cross.x86_64-win64.exe'  but I don't see any
> fp.exe to run so I'm a bit lost with it.

Yes, I don't know why the Free Pascal team doesn't make official 64-bit 
versions of FPC. I always end up having to compile my own full 64-bit 
FPC - which is very easy by the way.


> AggPas looks awesome, but can I use it with my console application?

Yes, you definitely can. I use AggPas in multiple headless servers too 
as console or CGI applications.


> I downloaded it and can't even run the sample programs included with
> it.. maybe they are Delphi examples or something?

Correct, unfortunately the demos are all GUI based demos at this time, 
but any of the actual drawing code inside those demos will be exactly 
the same for a console application.

Probably the easiest way to get your feet wet with AggPas is to use the 
agg_2D.pas (for non-GUI apps) unit. It doesn't give you the full power 
of AggPas, but presents you with a Agg2D object where you simply need to 
make graphic drawing method calls.

For example:
   // Star shape
   agg^.LineCap(CapRound);
   agg^.LineWidth(5);
   agg^.LineColor($32 ,$cd ,$32 );
   c1.Construct(0, 0 , 255, 200);
   c2.Construct(0, 0, 255, 50);
   agg^.FillLinearGradient(100, 100, 150, 150, c1, c2);
   agg^.Star(100 ,150 ,30 ,70 ,55 ,5 );


Attached is a console app example using the agg_2D.pas unit. It also 
uses the FPImage units (included with FPC) to generate a "test.png" 
image as output. You could use Memory Images too, depending on your 
application needs.

Compile the example with the following command

   $ fpc -FUunits -Fu../ -Fi../ Agg2DConsole.dpr

Adjust the -Fu and -Fi paths to match your environment, or simply save 
the Agg2DConsole.dpr into the "agg-demos" directory and compile with the 
above command.



Regards,
   Graeme

-- 
fpGUI Toolkit - a cross-platform GUI toolkit using Free Pascal
http://fpgui.sourceforge.net/

My public PGP key:  http://tinyurl.com/graeme-pgp
-------------- next part --------------
{
  This is a console application demo. It uses the Agg2D object,
  which has a much friendlier API, to do all the drawing. We then
  save the image buffer to a JPG, using the fcl-image package,
  which comes standard with the Free Pascal Compiler.

// Paths: ..\;..\svg;..\util;expat-wrap
}
program console_aggpas_2;

{$mode objfpc}{$H+}

uses
  sysutils,
  FPimage,
  FPWritePNG,
  agg_2D,
  agg_basics;

const
  ImageWidth = 800;
  ImageHeight = 480;
  RGBA_Width = 4;
  LineCount = 30;
  {$IFDEF Unix}
  FontFile = '../../arial.ttf';
  {$ENDIF}
  {$IFDEF Windows}
  FontFile = 'Arial';
  {$ENDIF}

type
  TPainter = class(TObject)
  public
    procedure HandlePlug;
    procedure DrawStuff(agg: Agg2D_ptr);
  end;


procedure TPainter.HandlePlug;
var
  agg: Agg2D_ptr;
  buf: array of int8;
  image: TFPMemoryImage;
  writer: TFPWriterPNG;
  x, y: Integer;
  c: TFPColor;
  time, totalTime: TDateTime;
  function getBufItemAsWord(aDelta: byte): Word;
  var
    actualY: Integer;
  begin
    actualY := ImageHeight - y - 1;
    result :=
      Word(buf[x * RGBA_Width + actualY * ImageWidth * RGBA_Width + aDelta] shl 8)
      or Word(128);
  end;
begin
  totalTime := Now;
  time := Now;
  SetLength(buf, ImageWidth * ImageHeight * RGBA_Width);
  New(agg, Construct);
  agg^.attach(@(buf[0]), ImageWidth, ImageHeight, -(ImageWidth * RGBA_Width));
  DrawStuff(agg);
  Dispose(agg, Destruct); // not necessary to keep it after rendering is finished
  time := Now - time;
//  Logger.Emit('Draw: time spent: ' + TimeStampToString(time));
  time := Now;
  image := TFPMemoryImage.create(ImageWidth, ImageHeight);
  for x := 0 to ImageWidth - 1 do
    for y := 0 to ImageHeight - 1 do
    begin
      c.red := getBufItemAsWord(2);
      c.green := getBufItemAsWord(1);
      c.blue := getBufItemAsWord(0);
      c.alpha := getBufItemAsWord(3);
      image.Colors[x, y] := c;
    end;
  time := Now - time;
//  WriteLn('Image copy: time spent: ' + DateTimeToString(time));
  time := Now;
  writer := TFPWriterPNG.Create;
  image.SaveToFile('test.png', writer);
  image.Free;
  writer.Free;
  time := Now - time;
//  WriteLn('Image encode: time spent: ' + DateTimeToString(time));
  totalTime := Now - totalTime;
//  WriteLn('Total time: ' + DateTimeToString(totalTime));
end;

procedure TPainter.DrawStuff(agg: Agg2D_ptr);
var
  i: Integer;
  x, y, px, py, d: Double;
  c1, c2: Color;
begin
  // draw a full screen graph with grid
  agg^.clearAll(0, 0, 0);
  agg^.lineColor(0, 0, 0, 255);
  agg^.lineWidth(3);
  agg^.rectangle(0, 0, ImageWidth, ImageHeight);
//  agg^.font(fontfile, 16);
  d := ImageWidth / LineCount;
  agg^.lineColor(0, 0, 0, 100);
  agg^.lineWidth(1);
  for i := 1 to LineCount - 1 do
  begin
    x := i * d;
    agg^.line(x, 0, x, ImageHeight);
  end;
  for i := 1 to trunc(ImageHeight / d) do
  begin
    y := i * d;
    agg^.line(0, y, ImageWidth, y);
  end;
  x := 0;
  y := ImageHeight / 2;
  px := x;
  py := y;
  agg^.lineColor(255, 0, 0, 200);
  agg^.fillColor(0, 0, 0, 200);
  agg^.lineWidth(3);
  for i := 0 to LineCount - 1 do
  begin
    x := x + d;
    y := y + Random(Round(ImageHeight / 3)) - ImageHeight / 6;
    if y < 0 then
      y := ImageHeight / 6;
    if y >= ImageHeight then
      y := ImageHeight - ImageHeight / 6;
    agg^.line(px, py, x, y);
//    agg^.text(x, y, char_ptr(IntToStr(i) + ' point'));
    px := x;
    py := y;
  end;
  
  // Star shape
  agg^.LineCap(CapRound);
  agg^.LineWidth(5);
  agg^.LineColor($32 ,$cd ,$32 );
  c1.Construct(0, 0 , 255, 200);
  c2.Construct(0, 0, 255, 50);
  agg^.FillLinearGradient(100, 100, 150, 150, c1, c2);
  agg^.Star(100 ,150 ,30 ,70 ,55 ,5 );

  // Draw Arc from 45 degrees to 270 degrees 
  agg^.LineColor($4C, $6C, $9C);
  agg^.LineWidth(5 );
  agg^.Arc(300 ,320 ,80 ,50 ,Deg2Rad(45 ) ,Deg2Rad(270 ) );
end;


var
  p: TPainter;
begin
  Randomize;
  p := TPainter.Create;
  p.HandlePlug;
  p.Free;
end.



More information about the fpc-pascal mailing list