unit images; {$MODE OBJFPC} {$M+} interface uses framebuffers, type_fixes, colors; type // TODO make this a normal class only? IImage = interface ['{4f9799f0-e4f2-11dd-bb2e-bb73deae7270}'] function GetWidth() : TCardinal; function GetHeight() : TCardinal; property Width : TCardinal read GetWidth; property Height : TCardinal read GetHeight; // use sparingly, can result in nil: function GetFramebuffer() : TFramebufferInfoP; // can also return derived instance. // TODO hotspot? end; // this is here because of a circular dependency pixmaps <-> framebuffers. TFramebufferImage = class(TInterfacedObject, IImage, IInterface) private fFramebuffer : TFramebufferInfoP; fBOwnsFramebuffer : TBoolean; public destructor Destroy(); override; published constructor Create(aFramebuffer : TFramebufferInfoP; aBOwnsFramebuffer : TBoolean); constructor Allocate(const aPixelBitfield : TPixelBitfield; aWidth, aHeight : TCardinal); protected function GetWidth() : TCardinal; function GetHeight() : TCardinal; published property Width : TCardinal read GetWidth; property Height : TCardinal read GetHeight; function GetFramebuffer() : TFramebufferInfoP; // can also return derived instance. end; implementation uses sysutils; { TFramebufferImage } destructor TFramebufferImage.Destroy(); begin if fBOwnsFramebuffer then FreeAndNil(fFramebuffer); inherited Destroy(); end; constructor TFramebufferImage.Create(aFramebuffer : TFramebufferInfoP; aBOwnsFramebuffer : TBoolean); begin assert(Assigned(fFramebuffer)); fFramebuffer := aFramebuffer; fBOwnsFramebuffer := aBOwnsFramebuffer; end; function TFramebufferImage.GetWidth() : TCardinal; begin Result := fFramebuffer^.Width; end; function TFramebufferImage.GetHeight() : TCardinal; begin Result := fFramebuffer^.Height; end; function TFramebufferImage.GetFramebuffer() : TFramebufferInfoP; // can also return derived instance. begin Result := fFramebuffer; end; constructor TFramebufferImage.Allocate(const aPixelBitfield : TPixelBitfield; aWidth, aHeight : TCardinal); begin fBOwnsFramebuffer := True; New(fFramebuffer, Init(aPixelBitfield, aWidth, aHeight)); fFramebuffer^.SetStart(AllocMem(fFramebuffer^.Size)); // TODO what if one fails, but the other doesn't? end; end.