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.
_______________________________________________
fpc-pascal maillist - fpc-pascal@lists.freepascal.org
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal