[fpc-devel] Rect drawing inconsistency in TFPCanvas

Ondrej Pokorny lazarus at kluug.net
Thu Feb 7 12:35:01 CET 2019


Hello,

when working with TFPCanvas, I face an annoying inconsistency between 
fcl-image and all other image libraries I know (including LCL Graphics).

The problem is that TFPCustomCanvas.FillRect and all other rect-aware 
methods (FillEllipse, etc...) fill 1 more pixel to the right and bottom.

E.g.

       MyCanvas.FillRect(0, 0, 50, 50);

- FP canvas draws a rectangle with 51x51 pixels.

- LCL Graphics draws a rectangle with 50x50 pixels. (And all other 
libraries like Delphi Graphics, BGRABitmap etc. do the same.)

---

IMO TFPCanvas is wrong because

1.) The rectangle should be filled up until the right/bottom coordinate 
- that means excluding the pixel at (50, 50). And not including it.

2.) Rect(0, 0, 50, 50) has a width/height of 50 pixels - see "function 
TRect.getWidth" in FPC sources. In FPCanvas if you draw Rect(0, 0, 50, 
50) it is 51x51 pixels, which is inconsistent.

3.) In FPCanvas if you draw Rect(0, 0, 50, 50) and Rect(50, 0, 100, 50) 
there is a 1px overlay between them! (That is wrong - Seen e.g. with 
dmAlphaBlend painting as in https://bugs.freepascal.org/view.php?id=34266 ).

4.) In FPCanvas if you draw Rect(0, 0, 0, 0) you get a 1px dot. (That is 
wrong.)

---

See the attached example project.

Should I report it in Mantis?

Ondrej

-------------- next part --------------
program FPCanvasDraw;

{$mode objfpc}{$H+}

uses
  FPImage, FPImgCanv, FPCanvas, FPWriteBMP, Classes, SysUtils, Graphics, Interfaces;

procedure DrawFPC;
var
  xNew: TFPMemoryImage;
  xCanvas: TFPImageCanvas;
  xRect: TRect;
begin
  xNew := nil;
  xCanvas := nil;
  try
    xNew := TFPMemoryImage.Create(5, 5);
    xCanvas := TFPImageCanvas.Create(xNew);

    xCanvas.Pen.Style := psClear;
    xCanvas.Brush.FPColor := colRed;

    xCanvas.FillRect(0, 0, xNew.Width, xNew.Height);

    // draw rectagle
    xRect.Top := 1;
    xRect.Left := 1;
    xRect.Width := 3;
    xRect.Height := 3;

    xCanvas.Brush.FPColor := colYellow;
    xCanvas.FillRect(xRect); // draws a 4x4 rectangle !!!

    xNew.SaveToFile('fpc.bmp');
  finally
    xCanvas.Free;
    xNew.Free;
  end;
end;

procedure DrawLCL;
var
  xNew: TBitmap;
  xCanvas: TCanvas;
  xRect: TRect;
begin
  xNew := TBitmap.Create;
  try
    xNew.SetSize(5, 5);
    xCanvas := xNew.Canvas;

    xCanvas.Pen.Style := psClear;
    xCanvas.Brush.Color := clRed;

    xCanvas.FillRect(0, 0, xNew.Width, xNew.Height);

    // draw rectagle
    xRect.Top := 1;
    xRect.Left := 1;
    xRect.Width := 3;
    xRect.Height := 3;

    xCanvas.Brush.Color := clYellow;
    xCanvas.FillRect(xRect);

    xNew.SaveToFile('lcl.bmp');
  finally
    xNew.Free;
  end;
end;

begin
  DrawFPC;
  DrawLCL;
end.



More information about the fpc-devel mailing list