You've already forked lazarus-ccr
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:
@ -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
|
||||
|
@ -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}
|
||||
|
@ -4,7 +4,7 @@ interface
|
||||
Uses
|
||||
avisocncgcodereader,avisocncgcodewriter,avisozlib,fpvectorial,
|
||||
fpvtocanvas,pdfvectorialreader,pdfvrlexico,pdfvrsemantico,pdfvrsintatico,
|
||||
svgvectorialwriter,cdrvectorialreader;
|
||||
svgvectorialwriter,cdrvectorialreader,epsvectorialreader;
|
||||
|
||||
implementation
|
||||
end.
|
||||
end.
|
||||
|
@ -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">
|
||||
|
@ -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
|
||||
|
@ -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.
|
||||
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
Reference in New Issue
Block a user