* Correct color output for background colors, see thread

http://forum.lazarus.freepascal.org/index.php/topic,19887.0.html
  and testmanual.xls from test suite.

  To do: needs verification on big-endian systems.
  To do: scWheat etc (the colors after grayx%) still don't work.



git-svn-id: https://svn.code.sf.net/p/lazarus-ccr/svn@2871 8e941d3f-bd1b-0410-a28a-d453659cc2b4
This commit is contained in:
bigchimp
2013-12-27 18:01:59 +00:00
parent 86a42c6c02
commit 9351660d56
2 changed files with 85 additions and 62 deletions

View File

@ -133,7 +133,9 @@ type
TsCellBorders = set of TsCellBorder; TsCellBorders = set of TsCellBorder;
{@@ Colors in FPSpreadsheet as given by a palette to be compatible with Excel } {@@ Colors in FPSpreadsheet as given by a palette to be compatible with Excel.
However, please note that they are physically written to XLS file as
ABGR (where A is 0) }
TsColor = ( // R G B color value: TsColor = ( // R G B color value:
scBlack , // 000000H scBlack , // 000000H
@ -1727,6 +1729,8 @@ begin
end; end;
function TsCustomSpreadWriter.FPSColorToHexString(AColor: TsColor; ARGBColor: TFPColor): string; function TsCustomSpreadWriter.FPSColorToHexString(AColor: TsColor; ARGBColor: TFPColor): string;
{ We use RGB bytes here, but please note that these are physically written
to XLS file as ABGR (where A is 0) }
begin begin
case AColor of case AColor of
scBlack: Result := '000000'; scBlack: Result := '000000';
@ -1749,10 +1753,10 @@ begin
scGrey10pct:Result := 'E6E6E6'; scGrey10pct:Result := 'E6E6E6';
scGrey20pct:Result := 'CCCCCC'; scGrey20pct:Result := 'CCCCCC';
scOrange: Result := 'FFA500'; scOrange: Result := 'FFA500';
scDarkBrown:Result := 'a0522d'; scDarkBrown:Result := 'A0522D';
scBrown: Result := 'cd853f'; scBrown: Result := 'CD853F';
scBeige: Result := 'f5f5dc'; scBeige: Result := 'F5F5DC';
scWheat: Result := 'f5deb3'; scWheat: Result := 'F5DEB3';
// //
scRGBCOLOR: Result := Format('%x%x%x', [ARGBColor.Red div $100, ARGBColor.Green div $100, ARGBColor.Blue div $100]); scRGBCOLOR: Result := Format('%x%x%x', [ARGBColor.Red div $100, ARGBColor.Green div $100, ARGBColor.Blue div $100]);
end; end;

View File

@ -133,6 +133,8 @@ type
TsSpreadBIFF8Writer = class(TsSpreadBIFFWriter) TsSpreadBIFF8Writer = class(TsSpreadBIFFWriter)
private private
// Convert our representation of RGB color to physical ARGB in Excel file
function LongRGBToExcelPhysical(const RGB: DWord): DWord;
// Writes index to XF record according to cell's formatting // Writes index to XF record according to cell's formatting
procedure WriteXFIndex(AStream: TStream; ACell: PCell); procedure WriteXFIndex(AStream: TStream; ACell: PCell);
procedure WriteXFFieldsForFormattingStyles(AStream: TStream); procedure WriteXFFieldsForFormattingStyles(AStream: TStream);
@ -288,6 +290,24 @@ const
{ TsSpreadBIFF8Writer } { TsSpreadBIFF8Writer }
function TsSpreadBIFF8Writer.LongRGBToExcelPhysical(const RGB: DWord): DWord;
// Converts RGB part of a LongRGB logical structure
// to its physical representation
// IOW: RGBA (where A is 0 and omitted in the function call) => ABGR
begin
{$IFDEF FPC}
{$IFDEF ENDIAN_LITTLE}
result:=(RGB shl 8); //tags $00 at end for the A byte
result:=NtoBE(LEtoN(result)); //flip byte order
{$ELSE}
//Big endian
result:=RGB; //leave value as is //todo: verify if this turns out ok
{$ENDIF}
{$ELSE}
// messed up result
{$ENDIF}
end;
{ Index to XF record, according to formatting } { Index to XF record, according to formatting }
procedure TsSpreadBIFF8Writer.WriteXFIndex(AStream: TStream; ACell: PCell); procedure TsSpreadBIFF8Writer.WriteXFIndex(AStream: TStream; ACell: PCell);
var var
@ -1197,71 +1217,70 @@ begin
AStream.WriteWord(WordToLE(56)); AStream.WriteWord(WordToLE(56));
{ Now the colors, first the standard 16 from Excel } { Now the colors, first the standard 16 from Excel }
AStream.WriteDWord(DWordToLE($000000)); // $08 AStream.WriteDWord(LongRGBToExcelPhysical($000000)); // $08
AStream.WriteDWord(DWordToLE($FFFFFF)); AStream.WriteDWord(LongRGBToExcelPhysical($FFFFFF));
AStream.WriteDWord(DWordToLE($FF0000)); AStream.WriteDWord(LongRGBToExcelPhysical($FF0000));
AStream.WriteDWord(DWordToLE($00FF00)); AStream.WriteDWord(LongRGBToExcelPhysical($00FF00));
AStream.WriteDWord(DWordToLE($0000FF)); AStream.WriteDWord(LongRGBToExcelPhysical($0000FF));
AStream.WriteDWord(DWordToLE($FFFF00)); AStream.WriteDWord(LongRGBToExcelPhysical($FFFF00));
AStream.WriteDWord(DWordToLE($FF00FF)); AStream.WriteDWord(LongRGBToExcelPhysical($FF00FF));
AStream.WriteDWord(DWordToLE($00FFFF)); AStream.WriteDWord(LongRGBToExcelPhysical($00FFFF));
AStream.WriteDWord(DWordToLE($800000)); AStream.WriteDWord(LongRGBToExcelPhysical($800000));
AStream.WriteDWord(DWordToLE($008000)); AStream.WriteDWord(LongRGBToExcelPhysical($008000));
AStream.WriteDWord(DWordToLE($000080)); AStream.WriteDWord(LongRGBToExcelPhysical($000080));
AStream.WriteDWord(DWordToLE($808000)); AStream.WriteDWord(LongRGBToExcelPhysical($808000));
AStream.WriteDWord(DWordToLE($800080)); AStream.WriteDWord(LongRGBToExcelPhysical($800080));
AStream.WriteDWord(DWordToLE($008080)); AStream.WriteDWord(LongRGBToExcelPhysical($008080));
AStream.WriteDWord(DWordToLE($C0C0C0)); AStream.WriteDWord(LongRGBToExcelPhysical($C0C0C0));
AStream.WriteDWord(DWordToLE($808080)); //$17 AStream.WriteDWord(LongRGBToExcelPhysical($808080)); //$17
{ Now some colors which we define ourselves } { Now some colors which we define ourselves }
AStream.WriteDWord(LongRGBToExcelPhysical($E6E6E6)); //$18 //todo: shouldn't we write $18..$3F and add this color later? see 5.74.3 Built-In Default Colour Tables
AStream.WriteDWord(DWordToLE($E6E6E6)); //$18 //todo: shouldn't we write $18..$3F and add this color later? see 5.74.3 Built-In Default Colour Tables AStream.WriteDWord(LongRGBToExcelPhysical($CCCCCC)); //$19 //todo: shouldn't we write $18..$3F and add this color later? see 5.74.3 Built-In Default Colour Tables
AStream.WriteDWord(DWordToLE($CCCCCC)); //$19 //todo: shouldn't we write $18..$3F and add this color later? see 5.74.3 Built-In Default Colour Tables
{ And padding } { And padding }
AStream.WriteDWord(DWordToLE($FFFFFF)); AStream.WriteDWord(LongRGBToExcelPhysical($FFFFFF));
AStream.WriteDWord(DWordToLE($FFFFFF)); AStream.WriteDWord(LongRGBToExcelPhysical($FFFFFF));
AStream.WriteDWord(DWordToLE($FFFFFF)); AStream.WriteDWord(LongRGBToExcelPhysical($FFFFFF));
AStream.WriteDWord(DWordToLE($FFFFFF)); AStream.WriteDWord(LongRGBToExcelPhysical($FFFFFF));
AStream.WriteDWord(DWordToLE($FFFFFF)); AStream.WriteDWord(LongRGBToExcelPhysical($FFFFFF));
AStream.WriteDWord(DWordToLE($FFFFFF)); AStream.WriteDWord(LongRGBToExcelPhysical($FFFFFF));
AStream.WriteDWord(DWordToLE($FFFFFF)); //$20 AStream.WriteDWord(LongRGBToExcelPhysical($FFFFFF)); //$20 //todo: is this still correct?
AStream.WriteDWord(DWordToLE($FFFFFF)); AStream.WriteDWord(LongRGBToExcelPhysical($FFFFFF));
AStream.WriteDWord(DWordToLE($FFFFFF)); AStream.WriteDWord(LongRGBToExcelPhysical($FFFFFF));
AStream.WriteDWord(DWordToLE($FFFFFF)); AStream.WriteDWord(LongRGBToExcelPhysical($FFFFFF));
AStream.WriteDWord(DWordToLE($FFFFFF)); AStream.WriteDWord(LongRGBToExcelPhysical($FFFFFF));
AStream.WriteDWord(DWordToLE($FFFFFF)); AStream.WriteDWord(LongRGBToExcelPhysical($FFFFFF));
AStream.WriteDWord(DWordToLE($FFFFFF)); AStream.WriteDWord(LongRGBToExcelPhysical($FFFFFF));
AStream.WriteDWord(DWordToLE($FFFFFF)); AStream.WriteDWord(LongRGBToExcelPhysical($FFFFFF));
AStream.WriteDWord(DWordToLE($FFFFFF)); AStream.WriteDWord(LongRGBToExcelPhysical($FFFFFF));
AStream.WriteDWord(DWordToLE($FFFFFF)); AStream.WriteDWord(LongRGBToExcelPhysical($FFFFFF));
AStream.WriteDWord(DWordToLE($FFFFFF)); AStream.WriteDWord(LongRGBToExcelPhysical($FFFFFF));
AStream.WriteDWord(DWordToLE($FFFFFF)); AStream.WriteDWord(LongRGBToExcelPhysical($FFFFFF));
AStream.WriteDWord(DWordToLE($FFFFFF)); AStream.WriteDWord(LongRGBToExcelPhysical($FFFFFF));
AStream.WriteDWord(DWordToLE($FFFFFF)); AStream.WriteDWord(LongRGBToExcelPhysical($FFFFFF));
AStream.WriteDWord(DWordToLE($FFFFFF)); AStream.WriteDWord(LongRGBToExcelPhysical($FFFFFF));
AStream.WriteDWord(DWordToLE($FFFFFF)); AStream.WriteDWord(LongRGBToExcelPhysical($FFFFFF));
AStream.WriteDWord(DWordToLE($FFFFFF)); //$30 AStream.WriteDWord(LongRGBToExcelPhysical($FFFFFF)); //$30
AStream.WriteDWord(DWordToLE($FFFFFF)); AStream.WriteDWord(LongRGBToExcelPhysical($FFFFFF));
AStream.WriteDWord(DWordToLE($FFFFFF)); AStream.WriteDWord(LongRGBToExcelPhysical($FFFFFF));
AStream.WriteDWord(DWordToLE($FFFFFF)); AStream.WriteDWord(LongRGBToExcelPhysical($FFFFFF));
AStream.WriteDWord(DWordToLE($FFFFFF)); AStream.WriteDWord(LongRGBToExcelPhysical($FFFFFF));
AStream.WriteDWord(DWordToLE($FFFFFF)); AStream.WriteDWord(LongRGBToExcelPhysical($FFFFFF));
AStream.WriteDWord(DWordToLE($FFFFFF)); AStream.WriteDWord(LongRGBToExcelPhysical($FFFFFF));
AStream.WriteDWord(DWordToLE($FFFFFF)); AStream.WriteDWord(LongRGBToExcelPhysical($FFFFFF));
AStream.WriteDWord(DWordToLE($FFFFFF)); AStream.WriteDWord(LongRGBToExcelPhysical($FFFFFF));
AStream.WriteDWord(DWordToLE($FFFFFF)); AStream.WriteDWord(LongRGBToExcelPhysical($FFFFFF));
AStream.WriteDWord(DWordToLE($FFFFFF)); AStream.WriteDWord(LongRGBToExcelPhysical($FFFFFF));
AStream.WriteDWord(DWordToLE($FFFFFF)); AStream.WriteDWord(LongRGBToExcelPhysical($FFFFFF));
AStream.WriteDWord(DWordToLE($FFFFFF)); AStream.WriteDWord(LongRGBToExcelPhysical($FFFFFF));
AStream.WriteDWord(DWordToLE($FFFFFF)); AStream.WriteDWord(LongRGBToExcelPhysical($FFFFFF));
AStream.WriteDWord(DWordToLE($FFFFFF)); AStream.WriteDWord(LongRGBToExcelPhysical($FFFFFF));
AStream.WriteDWord(DWordToLE($FFFFFF)); AStream.WriteDWord(LongRGBToExcelPhysical($FFFFFF));
end; end;
{******************************************************************* {*******************************************************************