fpvectorial: Advances the EPS reader

git-svn-id: https://svn.code.sf.net/p/lazarus-ccr/svn@1669 8e941d3f-bd1b-0410-a28a-d453659cc2b4
This commit is contained in:
sekelsenmat
2011-06-08 13:53:25 +00:00
parent 3711a7c172
commit b38dc79b7e
8 changed files with 158 additions and 70 deletions

View File

@ -30,12 +30,9 @@ interface
uses
Classes, SysUtils, Math,
fpvectorial, fpimage;
fpvectorial, fpimage, fpvutils;
type
{ Used by tcutils.SeparateString }
T10Strings = array[0..9] of shortstring;
TDXFToken = class;
TDXFTokens = TFPList;// TDXFToken;
@ -90,7 +87,6 @@ type
IsReadingPolyline: Boolean;
Polyline: array of TPolylineElement;
//
function SeparateString(AString: string; ASeparator: Char): T10Strings;
procedure ReadHEADER(ATokens: TDXFTokens; AData: TvVectorialDocument);
procedure ReadENTITIES(ATokens: TDXFTokens; AData: TvVectorialDocument);
procedure ReadENTITIES_LINE(ATokens: TDXFTokens; AData: TvVectorialDocument);
@ -347,39 +343,6 @@ end;
{ TvDXFVectorialReader }
{@@
Reads a string and separates it in substring
using ASeparator to delimite them.
Limits:
Number of substrings: 10 (indexed 0 to 9)
Length of each substring: 255 (they are shortstrings)
}
function TvDXFVectorialReader.SeparateString(AString: string; ASeparator: Char): T10Strings;
var
i, CurrentPart: Integer;
begin
CurrentPart := 0;
{ Clears the result }
for i := 0 to 9 do Result[i] := '';
{ Iterates througth the string, filling strings }
for i := 1 to Length(AString) do
begin
if Copy(AString, i, 1) = ASeparator then
begin
Inc(CurrentPart);
{ Verifies if the string capacity wasn't exceeded }
if CurrentPart > 9 then Exit;
end
else
Result[CurrentPart] := Result[CurrentPart] + Copy(AString, i, 1);
end;
end;
procedure TvDXFVectorialReader.ReadHEADER(ATokens: TDXFTokens;
AData: TvVectorialDocument);
var

View File

@ -15,7 +15,7 @@ interface
uses
Classes, SysUtils, Math,
fpvectorial, fpimage;
fpvectorial, fpimage, fpvutils;
type
TPSTokenType = (ttComment, ttFloat);
@ -32,7 +32,13 @@ type
TCommentToken = class(TPSToken)
end;
TPostScriptScannerState = (ssSearchingToken, ssInComment);
TDefinitionToken = class(TPSToken)
end;
TExpressionToken = class(TPSToken)
end;
TPostScriptScannerState = (ssSearchingToken, ssInComment, ssInDefinition, ssInExpressionElement);
{ TPSTokenizer }
@ -44,6 +50,8 @@ type
procedure ReadFromStream(AStream: TStream);
procedure DebugOut();
function IsValidPostScriptChar(AChar: Byte): Boolean;
function IsPostScriptSpace(AChar: Byte): Boolean;
function IsEndOfLine(ACurChar: Byte; AStream: TStream): Boolean;
end;
{ TvEPSVectorialReader }
@ -85,8 +93,13 @@ procedure TPSTokenizer.ReadFromStream(AStream: TStream);
var
i: Integer;
CurChar: Char;
CurLine: Integer = 1;
State: TPostScriptScannerState = ssSearchingToken;
CommentToken: TCommentToken;
DefinitionToken: TDefinitionToken;
ExpressionToken: TExpressionToken;
Len: Integer;
lIsEndOfLine: Boolean;
begin
while AStream.Position < AStream.Size do
begin
@ -94,42 +107,72 @@ begin
if not IsValidPostScriptChar(Byte(CurChar)) then
raise Exception.Create('[TPSTokenizer.ReadFromStream] Invalid char: ' + IntToHex(Byte(CurChar), 2));
lIsEndOfLine := IsEndOfLine(Byte(CurChar), AStream);
if lIsEndOfLine then Inc(CurLine);
case State of
{ Searching for a token }
ssSearchingToken:
begin
case CurChar of
'%':
begin
CommentToken := TCommentToken.Create;
State := ssInComment;
end;
end;
if CurChar = '%' then
begin
CommentToken := TCommentToken.Create;
State := ssInComment;
end
else if CurChar = '/' then
begin
DefinitionToken := TDefinitionToken.Create;
State := ssInDefinition;
end
else if CurChar in ['a'..'z'] + ['A'..'Z'] + ['0'..'9'] then
begin
ExpressionToken := TExpressionToken.Create;
State := ssInExpressionElement;
end
else if lIsEndOfLine then Continue
else
raise Exception.Create(Format('[TPSTokenizer.ReadFromStream] Unexpected char while searching for token: $%s in Line %d',
[IntToHex(Byte(CurChar), 2), CurLine]));
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
if lIsEndOfLine then
begin
Tokens.Add(CommentToken);
State := ssSearchingToken;
end;
end; // ssInComment
// Dictionary definitions end in "def"
ssInDefinition:
begin
DefinitionToken.StrValue := DefinitionToken.StrValue + CurChar;
Len := Length(DefinitionToken.StrValue);
if Len >= 3 then
begin
if (DefinitionToken.StrValue[Len-2] = 'd') and (DefinitionToken.StrValue[Len-1] = 'e') and (DefinitionToken.StrValue[Len] = 'f') then
begin
Tokens.Add(DefinitionToken);
State := ssSearchingToken;
end;
end;
end;
// Goes until a space comes
ssInExpressionElement:
begin
if IsPostScriptSpace(Byte(CurChar)) then
begin
Tokens.Add(ExpressionToken);
State := ssSearchingToken;
end
else
ExpressionToken.StrValue := ExpressionToken.StrValue + CurChar;
end;
end; // case
end; // while
end;
@ -146,6 +189,14 @@ begin
if Token is TCommentToken then
begin
WriteLn(Format('TCommentToken StrValue=%s', [Token.StrValue]));
end
else if Token is TDefinitionToken then
begin
WriteLn(Format('TDefinitionToken StrValue=%s', [Token.StrValue]));
end
else if Token is TExpressionToken then
begin
WriteLn(Format('TExpressionToken StrValue=%s', [Token.StrValue]));
end;
end;
end;
@ -167,6 +218,32 @@ begin
Result := ((AChar > 32) and (AChar < 127)) or (AChar in [0, 9, 10, 12, 13, 32]);
end;
function TPSTokenizer.IsPostScriptSpace(AChar: Byte): Boolean;
begin
Result := AChar in [0, 9, 10, 12, 13, 32];
end;
function TPSTokenizer.IsEndOfLine(ACurChar: Byte; AStream: TStream): Boolean;
var
HasNextChar: Boolean = False;
NextChar: Byte;
begin
Result := False;
if ACurChar = 13 then
begin
if AStream.Position < AStream.Size then
begin
HasNextChar := True;
NextChar := AStream.ReadByte();
if NextChar <> 10 then AStream.Seek(-1, soFromCurrent); // Go back if it wasnt a #13#10
Exit(True);
end;
end;
if ACurChar = 10 then Result := True;
end;
{$ifndef Windows}
{$define FPVECTORIALDEBUG}
{$endif}

View File

@ -4,7 +4,7 @@ interface
Uses
avisocncgcodereader,avisocncgcodewriter,avisozlib,fpvectorial,
fpvtocanvas,pdfvectorialreader,pdfvrlexico,pdfvrsemantico,pdfvrsintatico,
svgvectorialwriter,cdrvectorialreader;
svgvectorialwriter,cdrvectorialreader,epsvectorialreader;
implementation
end.
end.

View File

@ -11,7 +11,7 @@
<CompilerPath Value="$(CompPath)"/>
</Other>
</CompilerOptions>
<Files Count="15">
<Files Count="16">
<Item1>
<Filename Value="svgvectorialwriter.pas"/>
<UnitName Value="svgvectorialwriter"/>
@ -72,6 +72,10 @@
<Filename Value="epsvectorialreader.pas"/>
<UnitName Value="epsvectorialreader"/>
</Item15>
<Item16>
<Filename Value="fpvutils.pas"/>
<UnitName Value="fpvutils"/>
</Item16>
</Files>
<Type Value="RunAndDesignTime"/>
<RequiredPkgs Count="2">

View File

@ -10,7 +10,7 @@ uses
svgvectorialwriter, pdfvrsintatico, pdfvrsemantico, pdfvrlexico,
pdfvectorialreader, fpvtocanvas, fpvectorial, fpvectbuildunit,
dxfvectorialreader, cdrvectorialreader, avisozlib, avisocncgcodewriter,
avisocncgcodereader, svgvectorialreader, epsvectorialreader,
avisocncgcodereader, svgvectorialreader, epsvectorialreader, fpvutils,
LazarusPackageIntf;
implementation

View File

@ -21,10 +21,14 @@ uses
Classes, SysUtils, Math,
fpvectorial, fpimage;
type
T10Strings = array[0..9] of shortstring;
// Color Conversion routines
function VColorToFPColor(AVColor: TvColor): TFPColor; inline;
function VColorToRGBHexString(AVColor: TvColor): string;
function RGBToVColor(AR, AG, AB: Byte): TvColor; inline;
function SeparateString(AString: string; ASeparator: Char): T10Strings;
implementation
@ -49,5 +53,38 @@ begin
Result.Alpha := 255;
end;
{@@
Reads a string and separates it in substring
using ASeparator to delimite them.
Limits:
Number of substrings: 10 (indexed 0 to 9)
Length of each substring: 255 (they are shortstrings)
}
function SeparateString(AString: string; ASeparator: Char): T10Strings;
var
i, CurrentPart: Integer;
begin
CurrentPart := 0;
{ Clears the result }
for i := 0 to 9 do Result[i] := '';
{ Iterates througth the string, filling strings }
for i := 1 to Length(AString) do
begin
if Copy(AString, i, 1) = ASeparator then
begin
Inc(CurrentPart);
{ Verifies if the string capacity wasn't exceeded }
if CurrentPart > 9 then Exit;
end
else
Result[CurrentPart] := Result[CurrentPart] + Copy(AString, i, 1);
end;
end;
end.

View File

@ -76,8 +76,8 @@ object frmFPVViewer: TfrmFPVViewer
object pageViewer: TPage
end
object Page2: TPage
ClientWidth = 16896
ClientHeight = 19968
ClientWidth = 33792
ClientHeight = 39936
object DXFTreeView: TTreeView
Left = 8
Height = 313

View File

@ -126,6 +126,7 @@ end;
procedure TfrmFPVViewer.buttonRenderingTestClick(Sender: TObject);
var
Vec: TvVectorialDocument;
lClYellow: TvColor = (Red: $FF; Green: $FF; Blue: $00; Alpha: FPValphaOpaque);
begin
notebook.PageIndex := 0;
@ -136,6 +137,12 @@ begin
Vec.AddAlignedDimension(Make2DPoint(100, 50), Make2DPoint(200, 100), Make2DPoint(100, 150), Make2DPoint(200, 150));
Vec.AddAlignedDimension(Make2DPoint(50, 250), Make2DPoint(100, 200), Make2DPoint(150, 250), Make2DPoint(150, 200));
Vec.StartPath(0, 0);
Vec.SetPenColor(lClYellow);
Vec.SetPenWidth(1);
Vec.AddLineToPath(100, 100);
Vec.EndPath();
Drawer.Drawing.Width := 400;
Drawer.Drawing.Height := 400;
Drawer.Drawing.Canvas.Brush.Color := clWhite;