diff --git a/applications/fpvviewer/fpvectorialsrc/epsvectorialreader.pas b/applications/fpvviewer/fpvectorialsrc/epsvectorialreader.pas
new file mode 100644
index 000000000..6aad5abdb
--- /dev/null
+++ b/applications/fpvviewer/fpvectorialsrc/epsvectorialreader.pas
@@ -0,0 +1,203 @@
+{
+Reads EPS files
+
+License: The same modified LGPL as the Free Pascal RTL
+ See the file COPYING.modifiedLGPL for more details
+
+AUTHORS: Felipe Monteiro de Carvalho
+
+}
+unit epsvectorialreader;
+
+{$mode objfpc}{$H+}
+
+interface
+
+uses
+ Classes, SysUtils, Math,
+ fpvectorial, fpimage;
+
+type
+ TPSTokenType = (ttComment, ttFloat);
+
+ TPSTokens = TFPList;// TPSToken;
+
+ TPSToken = class
+ StrValue: string;
+ FloatValue: double;
+ IntValue: Integer;
+ Childs: TPSTokens;
+ end;
+
+ TCommentToken = class(TPSToken)
+ end;
+
+ TPostScriptScannerState = (ssSearchingToken, ssInComment);
+
+ { TPSTokenizer }
+
+ TPSTokenizer = class
+ public
+ Tokens: TPSTokens;
+ constructor Create;
+ destructor Destroy; override;
+ procedure ReadFromStream(AStream: TStream);
+ procedure DebugOut();
+ function IsValidPostScriptChar(AChar: Byte): Boolean;
+ end;
+
+ { TvEPSFVectorialReader }
+
+ { TvEPSVectorialReader }
+
+ TvEPSVectorialReader = class(TvCustomVectorialReader)
+ private
+ FPointSeparator: TFormatSettings;
+ public
+ { General reading methods }
+ Tokenizer: TPSTokenizer;
+ constructor Create; override;
+ Destructor Destroy; override;
+ procedure ReadFromStream(AStream: TStream; AData: TvVectorialDocument); override;
+ end;
+
+implementation
+
+{ TPSTokenizer }
+
+constructor TPSTokenizer.Create;
+begin
+ inherited Create;
+ Tokens := TPSTokens.Create;
+end;
+
+destructor TPSTokenizer.Destroy;
+begin
+ Tokens.Free;
+ inherited Destroy;
+end;
+
+{@@ Rules for parsing PostScript files:
+
+* Coments go from the first occurence of % outside a line to the next new line
+* The only accepted characters are printable ASCII ones, plus spacing ASCII chars
+ See IsValidPostScriptChar about that
+}
+procedure TPSTokenizer.ReadFromStream(AStream: TStream);
+var
+ i: Integer;
+ CurChar: Char;
+ State: TPostScriptScannerState = ssSearchingToken;
+ CommentToken: TCommentToken;
+begin
+ while AStream.Position < AStream.Size do
+ begin
+ CurChar := Char(AStream.ReadByte());
+ if not IsValidPostScriptChar(Byte(CurChar)) then
+ raise Exception.Create('[TPSTokenizer.ReadFromStream] Invalid char: ' + IntToHex(Byte(CurChar), 2));
+
+ case State of
+ { Searching for a token }
+ ssSearchingToken:
+ begin
+ case CurChar of
+ '%':
+ begin
+ CommentToken := TCommentToken.Create;
+ State := ssInComment;
+ end;
+ end;
+
+ end;
+
+ { Passing by comments }
+ ssInComment:
+ begin
+ CommentToken.StrValue := CommentToken.StrValue + CurChar;
+
+ case CurChar of
+ #13:
+ begin
+ // Check if this is a Windows-style #13#10 line end marker by getting one more char
+ if AStream.ReadByte() <> 10 then AStream.Seek(-1, soFromCurrent); // Go back if it wasnt a #13#10
+
+ Tokens.Add(CommentToken);
+ State := ssSearchingToken;
+ end;
+ #10:
+ begin
+ Tokens.Add(CommentToken);
+ State := ssSearchingToken;
+ end;
+ end; // case
+ end; // ssInComment
+
+ end; // case
+ end; // while
+end;
+
+procedure TPSTokenizer.DebugOut();
+var
+ i: Integer;
+ Token: TPSToken;
+begin
+ for i := 0 to Tokens.Count - 1 do
+ begin
+ Token := TPSToken(Tokens.Items[i]);
+
+ if Token is TCommentToken then
+ begin
+ WriteLn(Format('TCommentToken StrValue=%s', [Token.StrValue]));
+ end;
+ end;
+end;
+
+{@@ Valid PostScript Chars:
+
+All printable: a..zA..Z0..9
+
+Plus the following white spaces
+000 00 0 Null (nul)
+011 09 9 Tab (tab)
+012 0A 10 Line feed (LF)
+014 0C 12 Form feed (FF)
+015 0D 13 Carriage return (CR)
+040 20 32 Space (SP)
+}
+function TPSTokenizer.IsValidPostScriptChar(AChar: Byte): Boolean;
+begin
+ Result := ((AChar > 32) and (AChar < 127)) or (AChar in [0, 9, 10, 12, 13, 32]);
+end;
+
+{$ifndef Windows}
+{$define FPVECTORIALDEBUG}
+{$endif}
+
+{ TvEPSVectorialReader }
+
+constructor TvEPSVectorialReader.Create;
+begin
+ inherited Create;
+
+ Tokenizer := TPSTokenizer.Create;
+end;
+
+destructor TvEPSVectorialReader.Destroy;
+begin
+ Tokenizer.Free;
+ inherited Destroy;
+end;
+
+procedure TvEPSVectorialReader.ReadFromStream(AStream: TStream;
+ AData: TvVectorialDocument);
+begin
+ Tokenizer.ReadFromStream(AStream);
+ Tokenizer.DebugOut();
+end;
+
+initialization
+
+ RegisterVectorialReader(TvEPSVectorialReader, vfEncapsulatedPostScript);
+
+end.
+
diff --git a/applications/fpvviewer/fpvectorialsrc/fpvectorial.pas b/applications/fpvviewer/fpvectorialsrc/fpvectorial.pas
index 43ab9ba97..d7d58542b 100644
--- a/applications/fpvviewer/fpvectorialsrc/fpvectorial.pas
+++ b/applications/fpvviewer/fpvectorialsrc/fpvectorial.pas
@@ -24,9 +24,11 @@ uses
type
TvVectorialFormat = (
{ Multi-purpose document formats }
- vfPDF, vfPostScript, vfSVG, vfCorelDrawCDR, vfWindowsMetafileWMF,
+ vfPDF, vfSVG, vfCorelDrawCDR, vfWindowsMetafileWMF,
{ CAD formats }
vfDXF,
+ { Printing formats }
+ vfPostScript, vfEncapsulatedPostScript,
{ GCode formats }
vfGCodeAvisoCNCPrototipoV5, vfGCodeAvisoCNCPrototipoV6);
@@ -39,6 +41,7 @@ const
STR_CORELDRAW_EXTENSION = '.cdr';
STR_WINMETAFILE_EXTENSION = '.wmf';
STR_AUTOCAD_EXCHANGE_EXTENSION = '.dxf';
+ STR_ENCAPSULATEDPOSTSCRIPT_EXTENSION = '.eps';
type
{@@ We need our own format because TFPColor is too big for our needs and TColor has no Alpha }
@@ -1000,6 +1003,7 @@ begin
else if AnsiCompareText(lExt, STR_CORELDRAW_EXTENSION) = 0 then Result := vfCorelDrawCDR
else if AnsiCompareText(lExt, STR_WINMETAFILE_EXTENSION) = 0 then Result := vfWindowsMetafileWMF
else if AnsiCompareText(lExt, STR_AUTOCAD_EXCHANGE_EXTENSION) = 0 then Result := vfDXF
+ else if AnsiCompareText(lExt, STR_ENCAPSULATEDPOSTSCRIPT_EXTENSION) = 0 then Result := vfEncapsulatedPostScript
else
raise Exception.Create('TvVectorialDocument.GetFormatFromExtension: The extension (' + lExt + ') doesn''t match any supported formats.');
end;
diff --git a/applications/fpvviewer/fpvectorialsrc/fpvectorialpkg.lpk b/applications/fpvviewer/fpvectorialsrc/fpvectorialpkg.lpk
index 1817e7d98..e19f8bd63 100644
--- a/applications/fpvviewer/fpvectorialsrc/fpvectorialpkg.lpk
+++ b/applications/fpvviewer/fpvectorialsrc/fpvectorialpkg.lpk
@@ -11,7 +11,7 @@
-
+
@@ -66,8 +66,12 @@
-
+
+
+
+
+
diff --git a/applications/fpvviewer/fpvectorialsrc/fpvectorialpkg.pas b/applications/fpvviewer/fpvectorialsrc/fpvectorialpkg.pas
index cf589c426..281e53f97 100644
--- a/applications/fpvviewer/fpvectorialsrc/fpvectorialpkg.pas
+++ b/applications/fpvviewer/fpvectorialsrc/fpvectorialpkg.pas
@@ -10,7 +10,8 @@ uses
svgvectorialwriter, pdfvrsintatico, pdfvrsemantico, pdfvrlexico,
pdfvectorialreader, fpvtocanvas, fpvectorial, fpvectbuildunit,
dxfvectorialreader, cdrvectorialreader, avisozlib, avisocncgcodewriter,
- avisocncgcodereader, svgvectorialreader, LazarusPackageIntf;
+ avisocncgcodereader, svgvectorialreader, epsvectorialreader,
+ LazarusPackageIntf;
implementation
diff --git a/applications/fpvviewer/fpvv_mainform.lfm b/applications/fpvviewer/fpvv_mainform.lfm
index 980ad1fd0..f8bbfc291 100644
--- a/applications/fpvviewer/fpvv_mainform.lfm
+++ b/applications/fpvviewer/fpvv_mainform.lfm
@@ -76,8 +76,8 @@ object frmFPVViewer: TfrmFPVViewer
object pageViewer: TPage
end
object Page2: TPage
- ClientWidth = 4224
- ClientHeight = 4992
+ ClientWidth = 8448
+ ClientHeight = 9984
object DXFTreeView: TTreeView
Left = 8
Height = 313
diff --git a/applications/fpvviewer/fpvv_mainform.pas b/applications/fpvviewer/fpvv_mainform.pas
index 0ed21704c..d286bfbea 100644
--- a/applications/fpvviewer/fpvv_mainform.pas
+++ b/applications/fpvviewer/fpvv_mainform.pas
@@ -41,7 +41,7 @@ implementation
uses
fpvectorial, cdrvectorialreader, svgvectorialwriter, pdfvectorialreader,
- dxfvectorialreader,
+ dxfvectorialreader, epsvectorialreader,
fpvtocanvas,
dxftokentotree;