fpvectorial: Add basic raster image support for ODT files (png), patch by Andrzej Kilijanski {{MantisLink|0031357}}

git-svn-id: trunk@54180 -
This commit is contained in:
wp 2017-02-16 22:35:33 +00:00
parent 1e8c8bdc1a
commit dcb91b088d

View File

@ -95,6 +95,8 @@ type
FAutomaticStyleID : Integer; FAutomaticStyleID : Integer;
FContentAutomaticStyles : string; // built during writedocument, used during writedocument FContentAutomaticStyles : string; // built during writedocument, used during writedocument
FRasterImageFileNames:TStringList;
FList_StyleCrossRef : TListStyle_StyleList; FList_StyleCrossRef : TListStyle_StyleList;
FNewPageSequence : Boolean; FNewPageSequence : Boolean;
@ -125,6 +127,10 @@ type
procedure WriteField(AEntity: TvField; AParagraph: TvParagraph; procedure WriteField(AEntity: TvField; AParagraph: TvParagraph;
ACurPage: TvTextPageSequence; AData: TvVectorialDocument); ACurPage: TvTextPageSequence; AData: TvVectorialDocument);
procedure WriteList(AEntity: TvList; ACurPage: TvTextPageSequence; AData: TvVectorialDocument); procedure WriteList(AEntity: TvList; ACurPage: TvTextPageSequence; AData: TvVectorialDocument);
procedure WriteRasterImage(AEntity:TvRasterImage; AParagraph: TvParagraph;
ACurPage: TvTextPageSequence; AData: TvVectorialDocument);
// Routines to write parts of those files // Routines to write parts of those files
function WriteStylesXMLAsString: string; function WriteStylesXMLAsString: string;
// //
@ -139,7 +145,7 @@ type
implementation implementation
uses uses
htmlelements; htmlelements, FPWritePNG, Math;
const const
{ OpenDocument general XML constants } { OpenDocument general XML constants }
@ -318,17 +324,28 @@ begin
end; end;
procedure TvODTVectorialWriter.WriteMetaInfManifest; procedure TvODTVectorialWriter.WriteMetaInfManifest;
var
i:integer;
begin begin
FMetaInfManifest := FMetaInfManifest :=
XML_HEADER + LineEnding + XML_HEADER + LineEnding +
'<manifest:manifest xmlns:manifest="' + SCHEMAS_XMLNS_MANIFEST + '" manifest:version="1.2">' + LineEnding + '<manifest:manifest xmlns:manifest="' + SCHEMAS_XMLNS_MANIFEST + '" manifest:version="1.2">' + LineEnding +
' <manifest:file-entry manifest:full-path="/" manifest:media-type="application/vnd.oasis.opendocument.text" />' + LineEnding + // manifest:version="1.2" ' <manifest:file-entry manifest:full-path="/" manifest:media-type="application/vnd.oasis.opendocument.text" />' + LineEnding; // manifest:version="1.2"
for i:= 0 to FRasterImageFileNames.Count-1 do
begin
FMetaInfManifest := FMetaInfManifest+
' <manifest:file-entry manifest:media-type="image/png" manifest:full-path="'+FRasterImageFileNames[i]+'" />' + LineEnding;
end;
FMetaInfManifest := FMetaInfManifest+
' <manifest:file-entry manifest:media-type="text/xml" manifest:full-path="content.xml" />' + LineEnding + ' <manifest:file-entry manifest:media-type="text/xml" manifest:full-path="content.xml" />' + LineEnding +
' <manifest:file-entry manifest:media-type="text/xml" manifest:full-path="styles.xml" />' + LineEnding + ' <manifest:file-entry manifest:media-type="text/xml" manifest:full-path="styles.xml" />' + LineEnding +
' <manifest:file-entry manifest:media-type="text/xml" manifest:full-path="meta.xml" />' + LineEnding + ' <manifest:file-entry manifest:media-type="text/xml" manifest:full-path="meta.xml" />' + LineEnding +
' <manifest:file-entry manifest:media-type="text/xml" manifest:full-path="settings.xml" />' + LineEnding + ' <manifest:file-entry manifest:media-type="text/xml" manifest:full-path="settings.xml" />' + LineEnding +
' <manifest:file-entry manifest:full-path="manifest.rdf" manifest:media-type="application/rdf+xml"/>' + LineEnding + ' <manifest:file-entry manifest:full-path="manifest.rdf" manifest:media-type="application/rdf+xml"/>' + LineEnding +
'</manifest:manifest>'; '</manifest:manifest>';
end; end;
procedure TvODTVectorialWriter.WriteManifestRDF; procedure TvODTVectorialWriter.WriteManifestRDF;
@ -1100,6 +1117,8 @@ begin
WriteTextSpan(TvText(lCurEntity), AEntity, ACurPage, AData) WriteTextSpan(TvText(lCurEntity), AEntity, ACurPage, AData)
else if (lCurEntity is TvField) then else if (lCurEntity is TvField) then
WriteField(TvField(lCurEntity), AEntity, ACurPage, AData) WriteField(TvField(lCurEntity), AEntity, ACurPage, AData)
else if (lCurEntity is TvRasterImage) then
WriteRasterImage(TvRasterImage(lCurEntity), AEntity, ACurPage, AData)
else else
raise exception.create('TvParagraph subentity '+lCurEntity.ClassName+' not handled'); raise exception.create('TvParagraph subentity '+lCurEntity.ClassName+' not handled');
end; end;
@ -1680,6 +1699,34 @@ begin
' </text:list>' + LineEnding; ' </text:list>' + LineEnding;
end; end;
procedure TvODTVectorialWriter.WriteRasterImage(AEntity: TvRasterImage; AParagraph: TvParagraph;
ACurPage: TvTextPageSequence; AData: TvVectorialDocument);
var
FRasterImageName:string;
FRasterImageHeight:double;
FRasterImageWidth:double;
begin
if AEntity.RasterImage=nil then
Exit;
if IsZero(AEntity.Height) then
FRasterImageHeight:=RoundTo((AEntity.RasterImage.Height*2.54)/96,-3) // default 96 dpi of document, unit used cm
else
FRasterImageHeight:=AEntity.Height;
if IsZero(AEntity.Width) then
FRasterImageWidth:=RoundTo((AEntity.RasterImage.Width*2.54)/96,-3) // default 96 dpi of document, unit used cm
else
FRasterImageWidth:=AEntity.Width;
FRasterImageName:='Pictures/'+IntTostr(FRasterImageFileNames.Count+1)+'.png';
FContent:=FContent+'<draw:frame draw:name="Image'+IntTostr(FRasterImageFileNames.Count+1)+'" svg:width="'+FloatToODTText(FRasterImageWidth)+'cm" svg:height="'+FloatToODTText(FRasterImageHeight)+'cm" text:anchor-type="as-char" draw:z-index="2">';
FContent:=FContent+'<draw:image xlink:href="'+FRasterImageName+'" xlink:type="simple" xlink:show="embed" xlink:actuate="onLoad"/>';
FContent:=FContent+'</draw:frame>';
FRasterImageFileNames.AddObject(FRasterImageName,AEntity);
end;
function TvODTVectorialWriter.WriteStylesXMLAsString: string; function TvODTVectorialWriter.WriteStylesXMLAsString: string;
begin begin
@ -1700,10 +1747,13 @@ begin
FList_StyleCrossRef.Writer := Self; FList_StyleCrossRef.Writer := Self;
FDateCount := 0; FDateCount := 0;
FRasterImageFileNames:=TStringList.Create;
end; end;
destructor TvODTVectorialWriter.Destroy; destructor TvODTVectorialWriter.Destroy;
begin begin
FRasterImageFileNames.Free;
FList_StyleCrossRef.Free; FList_StyleCrossRef.Free;
inherited Destroy; inherited Destroy;
@ -1732,13 +1782,15 @@ var
// Streams with the contents of files // Streams with the contents of files
FSMeta, FSSettings, FSStyles, FSContent, FSMimetype: TStringStream; FSMeta, FSSettings, FSStyles, FSContent, FSMimetype: TStringStream;
FSMetaInfManifest, FSManifestRDF: TStringStream; FSMetaInfManifest, FSManifestRDF: TStringStream;
FSRasterImage:TMemoryStream;
i:integer;
WriterPNG:TFPWriterPNG;
FRasterImageStreamList:TFPList;
begin begin
FList_StyleCrossRef.Data := AData; FList_StyleCrossRef.Data := AData;
{ Fill the strings with the contents of the files } { Fill the strings with the contents of the files }
WriteMimetype(); WriteMimetype();
WriteMetaInfManifest();
WriteManifestRDF(); WriteManifestRDF();
WriteMeta(); WriteMeta();
WriteSettings(); WriteSettings();
@ -1746,6 +1798,7 @@ begin
// built up during WriteDocument... // built up during WriteDocument...
WriteDocument(AData); WriteDocument(AData);
WriteStyles(AData); WriteStyles(AData);
WriteMetaInfManifest();
{ Write the data to streams } { Write the data to streams }
@ -1757,8 +1810,13 @@ begin
FSMetaInfManifest := TStringStream.Create(FMetaInfManifest); FSMetaInfManifest := TStringStream.Create(FMetaInfManifest);
FSManifestRDF := TStringStream.Create(FManifestRDF); FSManifestRDF := TStringStream.Create(FManifestRDF);
{ Now compress the files }
FRasterImageStreamList:=nil;
WriterPNG:=TFPWriterPNG.Create;
WriterPNG.UseAlpha:=true;
{ Now compress the files }
FZip := TZipper.Create; FZip := TZipper.Create;
try try
// MimeType must be first file, and should be uncompressed // MimeType must be first file, and should be uncompressed
@ -1773,8 +1831,25 @@ begin
FZip.Entries.AddFileEntry(FSMetaInfManifest, OPENDOC_PATH_METAINF_MANIFEST); FZip.Entries.AddFileEntry(FSMetaInfManifest, OPENDOC_PATH_METAINF_MANIFEST);
FZip.Entries.AddFileEntry(FSManifestRDF, OPENDOC_PATH_MANIFESTRDF); FZip.Entries.AddFileEntry(FSManifestRDF, OPENDOC_PATH_MANIFESTRDF);
FRasterImageStreamList:=TFPList.Create;
for i:=0 to FRasterImageFileNames.Count-1 do
begin
FSRasterImage:=TMemoryStream.Create;
TvRasterImage(FRasterImageFileNames.Objects[i]).RasterImage.SaveToStream(FSRasterImage,WriterPNG);
FRasterImageStreamList.Add(FSRasterImage);
FSRasterImage.Seek(0,soFromBeginning);
FZip.Entries.AddFileEntry(FSRasterImage, FRasterImageFileNames[i]);
end;
FZip.SaveToStream(AStream); FZip.SaveToStream(AStream);
finally finally
if FRasterImageStreamList<> nil then
begin
for i:=0 to FRasterImageStreamList.Count-1 do
TvRasterImage(FRasterImageStreamList[i]).Free;
FRasterImageStreamList.Free;
end;
FZip.Free; FZip.Free;
FSMeta.Free; FSMeta.Free;
FSSettings.Free; FSSettings.Free;
@ -1783,6 +1858,7 @@ begin
FSMimetype.Free; FSMimetype.Free;
FSMetaInfManifest.Free; FSMetaInfManifest.Free;
FSManifestRDF.Free; FSManifestRDF.Free;
WriterPNG.Free;
end; end;
end; end;