[fpc-pascal] AggPas / PTCGraph dynamic memory allocation

James Richters james at productionautomation.net
Sun Nov 12 02:27:48 CET 2017


>AggPas doesn't care where or what the data buffer is, as long as you tell AggPas where to start, width, height and stride.
> So use GetImage, assign that buffer to a pointer. Increment the pointer by (3 *Size(Word)) and give that pointer to agg.Attach().

The data is preceded by 3 Longints, not words... sorry for my mistake.  

I understand the concept but I'm having difficulty getting the syntax right.    What I Think I am doing is setting a pointer for my GetImage/Putimage then defining a second pointer that is 3 Longints into the Getimage/Putimage pointer for use with AggPas... 

Here is the a sample program that works with the non-dynamic variable
{$mode objfpc}{$H+}

uses
  shlobj,
  ptcgraph,
  ptccrt,
  sysutils,
  agg_pixfmt_rgb_packed,
  agg_2D;

const
  RGB_WIDTH =2;
  Clock_W = 120;
  Clock_h = 40;

type

TClockBitmapBuffer=packed record
  width,
  height,
  reserved :longint;
  data  :array[0..(Clock_W+1) * (Clock_H+1)] of word;
end;

var
  Newtime,Oldtime        : Double;
  Bufsize                : Longint;
  gd,gm                  : smallint;
  aggClock,aggClock2     : Agg2D_ptr;
  Font2use,FontPath      : Array[0..MaxPathLen] of Char;
  clockbuffer_Original   : TClockBitmapbuffer;
  clockbuffer_with_time  : Tclockbitmapbuffer;
  Aggclockbuffer         : TClockbitmapbuffer;

Begin
   gd:=d16Bit;
   gm:=m800x600;
   ptcgraph.Initgraph(gd,gm,'');
   SHGetSpecialFolderPath(0,FontPath,CSIDL_FONTS,false);
   font2use:=FontPath+'\Lucon.ttf';
   GetImage((GetMaxX-4)-Clock_W+1,  4, GetMaxX-4,  4+Clock_H-1, ClockBuffer_original);
   ClockBuffer_With_Time:=ClockBuffer_original;
   New(aggClock , Construct(@pixfmt_rgb565));
   aggClock^.attach(@Clockbuffer_with_time.data,Clock_W, Clock_H, -Clock_W * RGB_WIDTH);
   aggclock^.Font(font2use ,12 );
   aggclock^.LineColor($FF ,$FF ,$00 );
   aggclock^.FillColor($FF ,$FF ,$60 );
Repeat
   Newtime:=now;
   If Trunc(Newtime*346600)<>Trunc(Oldtime*345600) Then  //update every 1/4 second
   Begin
      OldTime:=NewTime;
      ClockBuffer_With_Time:=ClockBuffer_original;
      aggclock^.Text(2 ,19,FormatDateTime('hh:nn:ssam/pm',Now));
      Putimage((GetMaxX-4)-Clock_W,  4, Clockbuffer_With_Time , normalPut);
   End;
until keypressed;
End.



Here is my attempt to define it with a dynamic variable.. It compiles, but when I try to run it I get an access violation and runtime error 217
I'm pretty sure I’m not assigning the pointer for Aggclockbuffer correctly and I don't think I'm attaching it to AggPas correctly either. 
Corrections are greatly appreciated.

{$mode objfpc}{$H+}

uses
  shlobj,
  ptcgraph,
  ptccrt,
  sysutils,
  agg_pixfmt_rgb_packed,
  agg_2D;

const
  RGB_WIDTH =2;
  Clock_W = 120;
  Clock_h = 40;

Var
   Newtime,Oldtime        : Double;
   Bufsize                : Longint;
   gd,gm                  : smallint;
   aggClock,aggClock2     : Agg2D_ptr;
   Font2use,FontPath      : Array[0..MaxPathLen] of Char;
   clockbuffer_Original   : ^Byte;
   clockbuffer_with_time  : ^Byte;
   Aggclockbuffer         : ^Byte;

Begin
   gd:=d16Bit;
   gm:=m800x600;
   ptcgraph.Initgraph(gd,gm,'');
   SHGetSpecialFolderPath(0,FontPath,CSIDL_FONTS,false);
   font2use:=FontPath+'\Lucon.ttf';
   bufSize:=ImageSize((GetMaxX-4)-Clock_W, 4 , GetMaxX-4, 4+Clock_H);
   GetMem(ClockBuffer_Original, bufSize);   { Allocate memory on heap }
   GetImage((GetMaxX-4)-Clock_W+1,  4, GetMaxX-4,  4+Clock_H-1, ClockBuffer_original^);
   ClockBuffer_With_Time:=ClockBuffer_original;
   AggClockbuffer^:=ClockBuffer_With_Time^+3*Sizeof(Longint);   //Set AggClockBuffer to be 3 Longints past ClockBuffer_with_time
   New(aggClock , Construct(@pixfmt_rgb565));
   aggClock^.attach(@AggClockbuffer,Clock_W, Clock_H, -Clock_W * RGB_WIDTH);   //Try to use AggClockbuffer pointer with AggPas
   aggclock^.Font(font2use ,12 );
   aggclock^.LineColor($FF ,$FF ,$00 );
   aggclock^.FillColor($FF ,$FF ,$60 );
Repeat
   Newtime:=now;
   If Trunc(Newtime*346600)<>Trunc(Oldtime*345600) Then  //update every 1/4 second
      Begin
         OldTime:=NewTime;
         ClockBuffer_With_Time:=ClockBuffer_original;
         aggclock^.Text(2 ,19,FormatDateTime('hh:nn:ssam/pm',Now));
         Putimage((GetMaxX-4)-Clock_W,  4, Clockbuffer_With_Time^ , normalPut);
      End;
until KeyPressed;
End.


James




More information about the fpc-pascal mailing list