[fpc-pascal] Implementing AggPas with PtcGraph
Stefan V. Pantazi
svpantazi at gmail.com
Mon Jun 19 04:31:16 CEST 2017
Good find and great sleuth work.
It is possible that the original reason for switching R and B channels
was to make the agg color object more compatible with LCL which seems to
prefer BGR, order, but who knows... One obvious problem seems to be
function AggToLCLColor(const c: TAggColor): TColor;
in Agg_LCL, that relies for conversion on RGBToColor in the Graphics unit.
function RGBToColor(R, G, B: Byte): TColor;
begin
Result := (B shl 16) or (G shl 8) or R;
end;
Anyway, a quick search of the agg source code shows that the rgba8
object is used only by a handful of units directly. Most agg units and
demos use the more complicated aggclr object to represent color. I tried
a few demos and seem unaffected by your fix. This explains why the bug
was only clearly visible in your case, most of the other agg demos seem
indiferent to the bug. On the other hand, besides agg_2D there are
agg_fpimage, Agg2D (the one that integrates with LCL) that also use the
rgba8 (through the TAggColor alias) and are clearly affected by the R
and B swap when using canvas methods that involve the TAggColor object
(e.g., AggClearAll, AggClearClipBox, etc). These would need to be
updated as well. As an example, after your fix, the call
canvas.AggClearAll(255,0,0) to TAggFPCanvas.AggClearAll(const r ,g ,b :
byte; a : byte = 255 ) produces a blue background, which is clearly wrong.
On 06/18/2017 08:35 PM, James Richters wrote:
>
> I finally partially figured out the red / blue color problem.
> After single stepping through tons of the aggpas code for hours (it's quite complicated even to draw a line) with a sample program that just made a red line at the top, I discovered that it's actually doing everything exactly correct! The problem is not with rendering with rgb565, the problem is something in the original that was patched with the setcolor function:
>
> Line 122 of agg_color pas has:
> constructor rgba8.Construct;
> begin
> b{*}:=int8u(r_ );
> g:=int8u(g_ );
> r:=int8u(b_ );
> a:=int8u(a_ );
>
> end;
>
> This switches red and blue... if I correct it to:
> constructor rgba8.Construct;
> begin
> b{*}:=int8u(b_ );
> g:=int8u(g_ );
> r:=int8u(r_ );
> a:=int8u(a_ );
>
> end;
>
> now my colors with rgb565 are correct. Since this is no logical reason to make b:=R_ and r:=B_ it seems more likely that with the rgba format somewhere along the way someone got lazy and just switched red and blue instead of fixing the pixelformat.
>
More information about the fpc-pascal
mailing list