You've already forked lazarus-ccr
fpspreadsheet: OOXML reader supports background color now. Test cases passed.
git-svn-id: https://svn.code.sf.net/p/lazarus-ccr/svn@3397 8e941d3f-bd1b-0410-a28a-d453659cc2b4
This commit is contained in:
@ -819,6 +819,7 @@ type
|
|||||||
|
|
||||||
{ Color handling }
|
{ Color handling }
|
||||||
function AddColorToPalette(AColorValue: TsColorValue): TsColor;
|
function AddColorToPalette(AColorValue: TsColorValue): TsColor;
|
||||||
|
function FindClosestColor(AColorValue: TsColorValue): TsColor;
|
||||||
function FPSColorToHexString(AColor: TsColor; ARGBColor: TFPColor): String;
|
function FPSColorToHexString(AColor: TsColor; ARGBColor: TFPColor): String;
|
||||||
function GetColorName(AColorIndex: TsColor): string;
|
function GetColorName(AColorIndex: TsColor): string;
|
||||||
function GetPaletteColor(AColorIndex: TsColor): TsColorValue;
|
function GetPaletteColor(AColorIndex: TsColor): TsColorValue;
|
||||||
@ -4890,6 +4891,35 @@ begin
|
|||||||
FPalette[Result] := AColorValue;
|
FPalette[Result] := AColorValue;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
{@@
|
||||||
|
Finds the palette color index which points to a color that is closest to a
|
||||||
|
given color. "Close" means here smallest length of the rgb-difference vector.
|
||||||
|
|
||||||
|
@param AColorValue Rgb color value to be considered
|
||||||
|
@return Palette index of the color closest to AColorValue
|
||||||
|
}
|
||||||
|
function TsWorkbook.FindClosestColor(AColorValue: TsColorValue): TsColor;
|
||||||
|
type
|
||||||
|
TRGBA = record r,g,b, a: Byte end;
|
||||||
|
var
|
||||||
|
rgb: TRGBA;
|
||||||
|
rgb0: TRGBA absolute AColorValue;
|
||||||
|
dist: Double;
|
||||||
|
mindist: Double;
|
||||||
|
i: Integer;
|
||||||
|
begin
|
||||||
|
Result := scNotDefined;
|
||||||
|
mindist := 1E108;
|
||||||
|
for i:=0 to Length(FPalette)-1 do begin
|
||||||
|
rgb := TRGBA(GetPaletteColor(i));
|
||||||
|
dist := sqr(rgb.r - rgb0.r) + sqr(rgb.g - rgb0.g) + sqr(rgb.b - rgb0.b);
|
||||||
|
if dist < mindist then begin
|
||||||
|
Result := i;
|
||||||
|
mindist := dist;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
{@@
|
{@@
|
||||||
Converts a fpspreadsheet color into into a string RRGGBB.
|
Converts a fpspreadsheet color into into a string RRGGBB.
|
||||||
Note that colors are written to xls files as ABGR (where A is 0).
|
Note that colors are written to xls files as ABGR (where A is 0).
|
||||||
|
@ -67,14 +67,12 @@ type
|
|||||||
procedure TestWriteRead_ODS_Font_Biff8Pal; // official biff8 palette in BIFF8 file format
|
procedure TestWriteRead_ODS_Font_Biff8Pal; // official biff8 palette in BIFF8 file format
|
||||||
procedure TestWriteRead_ODS_Font_RandomPal; // palette 64, top 56 entries random
|
procedure TestWriteRead_ODS_Font_RandomPal; // palette 64, top 56 entries random
|
||||||
|
|
||||||
{ OpenDocument file format tests }
|
{ OOXML file format tests }
|
||||||
// Background colors...
|
// Background colors...
|
||||||
(*
|
|
||||||
procedure TestWriteRead_OOXML_Background_InternalPal; // internal palette
|
procedure TestWriteRead_OOXML_Background_InternalPal; // internal palette
|
||||||
procedure TestWriteRead_OOXML_Background_Biff5Pal; // official biff5 palette
|
procedure TestWriteRead_OOXML_Background_Biff5Pal; // official biff5 palette
|
||||||
procedure TestWriteRead_OOXML_Background_Biff8Pal; // official biff8 palette
|
procedure TestWriteRead_OOXML_Background_Biff8Pal; // official biff8 palette
|
||||||
procedure TestWriteRead_OOXML_Background_RandomPal; // palette 64, top 56 entries random
|
procedure TestWriteRead_OOXML_Background_RandomPal; // palette 64, top 56 entries random
|
||||||
*)
|
|
||||||
// Font colors...
|
// Font colors...
|
||||||
procedure TestWriteRead_OOXML_Font_InternalPal; // internal palette for BIFF8 file format
|
procedure TestWriteRead_OOXML_Font_InternalPal; // internal palette for BIFF8 file format
|
||||||
procedure TestWriteRead_OOXML_Font_Biff5Pal; // official biff5 palette in BIFF8 file format
|
procedure TestWriteRead_OOXML_Font_Biff5Pal; // official biff5 palette in BIFF8 file format
|
||||||
@ -402,7 +400,6 @@ begin
|
|||||||
end;
|
end;
|
||||||
|
|
||||||
{ Tests for OOXML file format }
|
{ Tests for OOXML file format }
|
||||||
(*
|
|
||||||
procedure TSpreadWriteReadColorTests.TestWriteRead_OOXML_Background_InternalPal;
|
procedure TSpreadWriteReadColorTests.TestWriteRead_OOXML_Background_InternalPal;
|
||||||
begin
|
begin
|
||||||
TestWriteReadBackgroundColors(sfOOXML, 0);
|
TestWriteReadBackgroundColors(sfOOXML, 0);
|
||||||
@ -422,7 +419,7 @@ procedure TSpreadWriteReadColorTests.TestWriteRead_OOXML_Background_RandomPal;
|
|||||||
begin
|
begin
|
||||||
TestWriteReadBackgroundColors(sfOOXML, 999);
|
TestWriteReadBackgroundColors(sfOOXML, 999);
|
||||||
end;
|
end;
|
||||||
*)
|
|
||||||
procedure TSpreadWriteReadColorTests.TestWriteRead_OOXML_Font_InternalPal;
|
procedure TSpreadWriteReadColorTests.TestWriteRead_OOXML_Font_InternalPal;
|
||||||
begin
|
begin
|
||||||
TestWriteReadFontColors(sfOOXML, 0);
|
TestWriteReadFontColors(sfOOXML, 0);
|
||||||
|
@ -69,6 +69,7 @@ type
|
|||||||
procedure ReadCellXfs(ANode: TDOMNode);
|
procedure ReadCellXfs(ANode: TDOMNode);
|
||||||
procedure ReadDateMode(ANode: TDOMNode);
|
procedure ReadDateMode(ANode: TDOMNode);
|
||||||
procedure ReadFileVersion(ANode: TDOMNode);
|
procedure ReadFileVersion(ANode: TDOMNode);
|
||||||
|
procedure ReadFills(ANode: TDOMNode);
|
||||||
procedure ReadFont(ANode: TDOMNode);
|
procedure ReadFont(ANode: TDOMNode);
|
||||||
procedure ReadFonts(ANode: TDOMNode);
|
procedure ReadFonts(ANode: TDOMNode);
|
||||||
procedure ReadNumFormats(ANode: TDOMNode);
|
procedure ReadNumFormats(ANode: TDOMNode);
|
||||||
@ -190,6 +191,12 @@ const
|
|||||||
MIME_STRINGS = MIME_SPREADML + '.sharedStrings+xml';
|
MIME_STRINGS = MIME_SPREADML + '.sharedStrings+xml';
|
||||||
|
|
||||||
type
|
type
|
||||||
|
TFillListData = class
|
||||||
|
PatternType: String;
|
||||||
|
FgColor: TsColor;
|
||||||
|
BgColor: Tscolor;
|
||||||
|
end;
|
||||||
|
|
||||||
TXFListData = class
|
TXFListData = class
|
||||||
NumFmtIndex: Integer;
|
NumFmtIndex: Integer;
|
||||||
FontIndex: Integer;
|
FontIndex: Integer;
|
||||||
@ -313,6 +320,7 @@ procedure TsSpreadOOXMLReader.ApplyCellFormatting(ACell: PCell; XfIndex: Integer
|
|||||||
var
|
var
|
||||||
xf: TXfListData;
|
xf: TXfListData;
|
||||||
numFmtData: TsNumFormatData;
|
numFmtData: TsNumFormatData;
|
||||||
|
fillData: TFillListData;
|
||||||
j: Integer;
|
j: Integer;
|
||||||
begin
|
begin
|
||||||
if Assigned(ACell) then begin
|
if Assigned(ACell) then begin
|
||||||
@ -350,14 +358,15 @@ begin
|
|||||||
ACell^.Border := xf.Borders;
|
ACell^.Border := xf.Borders;
|
||||||
end else
|
end else
|
||||||
Exclude(ACell^.UsedFormattingFields, uffBorder);
|
Exclude(ACell^.UsedFormattingFields, uffBorder);
|
||||||
|
*)
|
||||||
|
|
||||||
// Background color
|
// Background color
|
||||||
if xf.BackgroundColor <> scTransparent then begin
|
fillData := FFillList[xf.FillIndex];
|
||||||
|
if (fillData <> nil) and (fillData.PatternType <> 'none') then begin
|
||||||
Include(ACell^.UsedFormattingFields, uffBackgroundColor);
|
Include(ACell^.UsedFormattingFields, uffBackgroundColor);
|
||||||
ACell^.BackgroundColor := xf.BackgroundColor;
|
ACell^.BackgroundColor := fillData.FgColor;
|
||||||
end else
|
end else
|
||||||
Exclude(ACell^.UsedFormattingFields, uffBackgroundColor);
|
Exclude(ACell^.UsedFormattingFields, uffBackgroundColor);
|
||||||
*)
|
|
||||||
|
|
||||||
if xf.NumFmtIndex > 0 then begin
|
if xf.NumFmtIndex > 0 then begin
|
||||||
j := NumFormatList.FindByIndex(xf.NumFmtIndex);
|
j := NumFormatList.FindByIndex(xf.NumFmtIndex);
|
||||||
@ -526,6 +535,104 @@ begin
|
|||||||
FWrittenByFPS := GetAttrValue(ANode, 'appName') = 'fpspreadsheet';
|
FWrittenByFPS := GetAttrValue(ANode, 'appName') = 'fpspreadsheet';
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
procedure TsSpreadOOXMLReader.ReadFills(ANode: TDOMNode);
|
||||||
|
var
|
||||||
|
fillNode, patternNode, colorNode: TDOMNode;
|
||||||
|
nodeName: String;
|
||||||
|
filldata: TFillListData;
|
||||||
|
s: String;
|
||||||
|
patt: String;
|
||||||
|
fgclr: TsColor;
|
||||||
|
bgclr: TsColor;
|
||||||
|
ci: TsColor;
|
||||||
|
begin
|
||||||
|
if ANode = nil then
|
||||||
|
exit;
|
||||||
|
|
||||||
|
fillNode := ANode.FirstChild;
|
||||||
|
while Assigned(fillNode) do begin
|
||||||
|
nodename := fillNode.NodeName;
|
||||||
|
patternNode := fillNode.FirstChild;
|
||||||
|
while Assigned(patternNode) do begin
|
||||||
|
nodename := patternNode.NodeName;
|
||||||
|
if nodename = 'patternFill' then begin
|
||||||
|
patt := GetAttrValue(patternNode, 'patternType');
|
||||||
|
fgclr := scWhite;
|
||||||
|
bgclr := scBlack;
|
||||||
|
colorNode := patternNode.FirstChild;
|
||||||
|
while Assigned(colorNode) do begin
|
||||||
|
nodeName := colorNode.NodeName;
|
||||||
|
if nodeName = 'fgColor' then begin
|
||||||
|
s := GetAttrValue(colorNode, 'rgb');
|
||||||
|
if s <> '' then
|
||||||
|
fgclr := FWorkbook.AddColorToPalette(HTMLColorStrToColor('#' + s))
|
||||||
|
else begin
|
||||||
|
s := GetAttrValue(colorNode, 'indexed');
|
||||||
|
if s <> '' then
|
||||||
|
fgclr := StrToInt(s);
|
||||||
|
end;
|
||||||
|
end
|
||||||
|
else
|
||||||
|
if nodeName = 'bgColor' then begin
|
||||||
|
s := GetAttrValue(colorNode, 'rgb');
|
||||||
|
if s <> '' then
|
||||||
|
bgclr := FWorkbook.AddColorToPalette(HTMLColorStrToColor('#' + s))
|
||||||
|
else begin
|
||||||
|
s := GetAttrValue(colorNode, 'indexed');
|
||||||
|
if s <> '' then
|
||||||
|
bgclr := StrToInt(s);
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
colorNode := colorNode.NextSibling;
|
||||||
|
end;
|
||||||
|
|
||||||
|
// Store in FFillList
|
||||||
|
fillData := TFillListData.Create;
|
||||||
|
fillData.PatternType := patt;
|
||||||
|
fillData.FgColor := fgclr;
|
||||||
|
fillData.BgColor := bgclr;
|
||||||
|
FFillList.Add(fillData);
|
||||||
|
end;
|
||||||
|
patternNode := patternNode.NextSibling;
|
||||||
|
end;
|
||||||
|
fillNode := fillNode.NextSibling;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
(*
|
||||||
|
AppendToStream(AStream, Format(
|
||||||
|
'<fills count="%d">', [Length(FFillList)]));
|
||||||
|
|
||||||
|
// index 0 -- built-in empty fill
|
||||||
|
AppendToStream(AStream,
|
||||||
|
'<fill>',
|
||||||
|
'<patternFill patternType="none" />',
|
||||||
|
'</fill>');
|
||||||
|
|
||||||
|
// index 1 -- built-in gray125 pattern
|
||||||
|
AppendToStream(AStream,
|
||||||
|
'<fill>',
|
||||||
|
'<patternFill patternType="gray125" />',
|
||||||
|
'</fill>');
|
||||||
|
|
||||||
|
// user-defined fills
|
||||||
|
for i:=2 to High(FFillList) do begin
|
||||||
|
styleCell := FFillList[i];
|
||||||
|
rgb := Workbook.GetPaletteColor(styleCell^.BackgroundColor);
|
||||||
|
AppendToStream(AStream,
|
||||||
|
'<fill>',
|
||||||
|
'<patternFill patternType="solid">');
|
||||||
|
AppendToStream(AStream, Format(
|
||||||
|
'<fgColor rgb="%s" />', [Copy(ColorToHTMLColorStr(rgb), 2, 255)]),
|
||||||
|
'<bgColor indexed="64" />');
|
||||||
|
AppendToStream(AStream,
|
||||||
|
'</patternFill>',
|
||||||
|
'</fill>');
|
||||||
|
end;
|
||||||
|
|
||||||
|
AppendToStream(FSStyles,
|
||||||
|
'</fills>');
|
||||||
|
*)
|
||||||
procedure TsSpreadOOXMLReader.ReadFont(ANode: TDOMNode);
|
procedure TsSpreadOOXMLReader.ReadFont(ANode: TDOMNode);
|
||||||
var
|
var
|
||||||
node: TDOMNode;
|
node: TDOMNode;
|
||||||
@ -610,7 +717,6 @@ end;
|
|||||||
procedure TsSpreadOOXMLReader.ReadFonts(ANode: TDOMNode);
|
procedure TsSpreadOOXMLReader.ReadFonts(ANode: TDOMNode);
|
||||||
var
|
var
|
||||||
node: TDOMNode;
|
node: TDOMNode;
|
||||||
n: Integer;
|
|
||||||
begin
|
begin
|
||||||
// Clear existing fonts. They will be replaced by those from the file.
|
// Clear existing fonts. They will be replaced by those from the file.
|
||||||
FWorkbook.RemoveAllFonts;
|
FWorkbook.RemoveAllFonts;
|
||||||
@ -621,8 +727,6 @@ begin
|
|||||||
node := node.NextSibling;
|
node := node.NextSibling;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
n := FWorkbook.GetFontCount;
|
|
||||||
|
|
||||||
{ A problem is caused by the font #4 which is missing in BIFF file versions.
|
{ A problem is caused by the font #4 which is missing in BIFF file versions.
|
||||||
FPSpreadsheet writes a nil value to this position in order to keep compatibility
|
FPSpreadsheet writes a nil value to this position in order to keep compatibility
|
||||||
with other file formats. Other applications, however, have a valid font at
|
with other file formats. Other applications, however, have a valid font at
|
||||||
@ -630,9 +734,6 @@ begin
|
|||||||
by FPSpreadsheet. }
|
by FPSpreadsheet. }
|
||||||
if not FWrittenByFPS then
|
if not FWrittenByFPS then
|
||||||
FWorkbook.DeleteFont(4);
|
FWorkbook.DeleteFont(4);
|
||||||
|
|
||||||
n := FWorkbook.GetFontCount;
|
|
||||||
|
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TsSpreadOOXMLReader.ReadNumFormats(ANode: TDOMNode);
|
procedure TsSpreadOOXMLReader.ReadNumFormats(ANode: TDOMNode);
|
||||||
@ -801,6 +902,7 @@ begin
|
|||||||
DeleteFile(FilePath + OOXML_PATH_XL_STYLES);
|
DeleteFile(FilePath + OOXML_PATH_XL_STYLES);
|
||||||
ReadPalette(Doc.DocumentElement.FindNode('colors'));
|
ReadPalette(Doc.DocumentElement.FindNode('colors'));
|
||||||
ReadFonts(Doc.DocumentElement.FindNode('fonts'));
|
ReadFonts(Doc.DocumentElement.FindNode('fonts'));
|
||||||
|
ReadFills(Doc.DocumentElement.FindNode('fills'));
|
||||||
ReadNumFormats(Doc.DocumentElement.FindNode('numFmts'));
|
ReadNumFormats(Doc.DocumentElement.FindNode('numFmts'));
|
||||||
ReadCellXfs(Doc.DocumentElement.FindNode('cellXfs'));
|
ReadCellXfs(Doc.DocumentElement.FindNode('cellXfs'));
|
||||||
FreeAndNil(Doc);
|
FreeAndNil(Doc);
|
||||||
|
Reference in New Issue
Block a user