1
//----------------------------------------------------------------------------
2
// Anti-Grain Geometry - Version 2.4 (Public License)
3
// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
5
// Anti-Grain Geometry - Version 2.4 Release Milano 3 (AggPas 2.4 RM3)
6
// Pascal Port By: Milan Marusinec alias Milano
8
// http://www.aggpas.org
9
// Copyright (c) 2005-2006
11
// Permission to copy, use, modify, sell and distribute this software
12
// is granted provided this copyright notice appears in all copies.
13
// This software is provided "as is" without express or implied
14
// warranty, and with no claim as to its suitability for any purpose.
16
//----------------------------------------------------------------------------
17
// Contact: mcseem@antigrain.com
18
// mcseemagg@yahoo.com
19
// http://www.antigrain.com
21
// [Pascal Port History] -----------------------------------------------------
23
// 03.01.2007-Milano: Adjustments for ExpatWrap (Win,Linux & Mac)
24
// 23.06.2006-Milano: ptrcomp adjustments
25
// 24.04.2006-Milano: Unit port establishment
27
{ agg_svg_parser.pas }
33
{$DEFINE EXPAT_WRAPPER }
40
agg_svg_path_tokenizer ,
41
agg_svg_path_renderer ,
58
m_path : path_renderer_ptr;
59
m_tokenizer : path_tokenizer;
64
m_title_len : unsigned;
66
m_path_flag : boolean;
68
m_attr_value : char_ptr;
73
m_attr_value_aloc : unsigned;
75
constructor Construct(path : path_renderer_ptr );
78
procedure parse(fname : string ); overload; // UTF8
79
procedure parse(sourcestream: TStream); overload;
80
function title : char_ptr;
83
procedure parse_attr (attr : char_ptr_ptr ); overload;
84
procedure parse_path (attr : char_ptr_ptr );
85
procedure parse_poly (attr : char_ptr_ptr; close_flag : boolean );
86
procedure parse_rect (attr : char_ptr_ptr );
87
procedure parse_line (attr : char_ptr_ptr );
88
procedure parse_style (str : agg_basics.char_ptr );
89
procedure parse_transform(str : agg_basics.char_ptr );
91
function parse_matrix (str : agg_basics.char_ptr ) : unsigned;
92
function parse_translate(str : agg_basics.char_ptr ) : unsigned;
93
function parse_rotate (str : agg_basics.char_ptr ) : unsigned;
94
function parse_scale (str : agg_basics.char_ptr ) : unsigned;
95
function parse_skew_x (str : agg_basics.char_ptr ) : unsigned;
96
function parse_skew_y (str : agg_basics.char_ptr ) : unsigned;
98
function parse_attr (name ,value : agg_basics.char_ptr ) : boolean; overload;
99
function parse_name_value(nv_start ,nv_end : agg_basics.char_ptr ) : boolean;
101
procedure copy_name (start ,end_ : agg_basics.char_ptr );
102
procedure copy_value(start ,end_ : agg_basics.char_ptr );
106
{ GLOBAL PROCEDURES }
107
procedure start_element(data : pointer; el : char_ptr; attr : char_ptr_ptr ); {$IFDEF EXPAT_WRAPPER }cdecl; {$ENDIF }
108
procedure end_element (data : pointer; el : char_ptr ); {$IFDEF EXPAT_WRAPPER }cdecl; {$ENDIF }
109
procedure content (data : pointer; s : char_ptr; len : int ); {$IFDEF EXPAT_WRAPPER }cdecl; {$ENDIF }
113
{ LOCAL VARIABLES & CONSTANTS }
115
named_color_ptr = ^named_color;
117
name : array[0..21 ] of char;
126
colors : array[0..colors_num - 1 ] of named_color =
127
((name:'aliceblue'; r:240; g:248; b:255; a:255 ) ,
128
(name:'antiquewhite'; r:250; g:235; b:215; a:255 ) ,
129
(name:'aqua'; r:0; g:255; b:255; a:255 ) ,
130
(name:'aquamarine'; r:127; g:255; b:212; a:255 ) ,
131
(name:'azure'; r:240; g:255; b:255; a:255 ) ,
132
(name:'beige'; r:245; g:245; b:220; a:255 ) ,
133
(name:'bisque'; r:255; g:228; b:196; a:255 ) ,
134
(name:'black'; r:0; g:0; b:0; a:255 ) ,
135
(name:'blanchedalmond'; r:255; g:235; b:205; a:255 ) ,
136
(name:'blue'; r:0; g:0; b:255; a:255 ) ,
137
(name:'blueviolet'; r:138; g:43; b:226; a:255 ) ,
138
(name:'brown'; r:165; g:42; b:42; a:255 ) ,
139
(name:'burlywood'; r:222; g:184; b:135; a:255 ) ,
140
(name:'cadetblue'; r:95; g:158; b:160; a:255 ) ,
141
(name:'chartreuse'; r:127; g:255; b:0; a:255 ) ,
142
(name:'chocolate'; r:210; g:105; b:30; a:255 ) ,
143
(name:'coral'; r:255; g:127; b:80; a:255 ) ,
144
(name:'cornflowerblue'; r:100; g:149; b:237; a:255 ) ,
145
(name:'cornsilk'; r:255; g:248; b:220; a:255 ) ,
146
(name:'crimson'; r:220; g:20; b:60; a:255 ) ,
147
(name:'cyan'; r:0; g:255; b:255; a:255 ) ,
148
(name:'darkblue'; r:0; g:0; b:139; a:255 ) ,
149
(name:'darkcyan'; r:0; g:139; b:139; a:255 ) ,
150
(name:'darkgoldenrod'; r:184; g:134; b:11; a:255 ) ,
151
(name:'darkgray'; r:169; g:169; b:169; a:255 ) ,
152
(name:'darkgreen'; r:0; g:100; b:0; a:255 ) ,
153
(name:'darkgrey'; r:169; g:169; b:169; a:255 ) ,
154
(name:'darkkhaki'; r:189; g:183; b:107; a:255 ) ,
155
(name:'darkmagenta'; r:139; g:0; b:139; a:255 ) ,
156
(name:'darkolivegreen'; r:85; g:107; b:47; a:255 ) ,
157
(name:'darkorange'; r:255; g:140; b:0; a:255 ) ,
158
(name:'darkorchid'; r:153; g:50; b:204; a:255 ) ,
159
(name:'darkred'; r:139; g:0; b:0; a:255 ) ,
160
(name:'darksalmon'; r:233; g:150; b:122; a:255 ) ,
161
(name:'darkseagreen'; r:143; g:188; b:143; a:255 ) ,
162
(name:'darkslateblue'; r:72; g:61; b:139; a:255 ) ,
163
(name:'darkslategray'; r:47; g:79; b:79; a:255 ) ,
164
(name:'darkslategrey'; r:47; g:79; b:79; a:255 ) ,
165
(name:'darkturquoise'; r:0; g:206; b:209; a:255 ) ,
166
(name:'darkviolet'; r:148; g:0; b:211; a:255 ) ,
167
(name:'deeppink'; r:255; g:20; b:147; a:255 ) ,
168
(name:'deepskyblue'; r:0; g:191; b:255; a:255 ) ,
169
(name:'dimgray'; r:105; g:105; b:105; a:255 ) ,
170
(name:'dimgrey'; r:105; g:105; b:105; a:255 ) ,
171
(name:'dodgerblue'; r:30; g:144; b:255; a:255 ) ,
172
(name:'firebrick'; r:178; g:34; b:34; a:255 ) ,
173
(name:'floralwhite'; r:255; g:250; b:240; a:255 ) ,
174
(name:'forestgreen'; r:34; g:139; b:34; a:255 ) ,
175
(name:'fuchsia'; r:255; g:0; b:255; a:255 ) ,
176
(name:'gainsboro'; r:220; g:220; b:220; a:255 ) ,
177
(name:'ghostwhite'; r:248; g:248; b:255; a:255 ) ,
178
(name:'gold'; r:255; g:215; b:0; a:255 ) ,
179
(name:'goldenrod'; r:218; g:165; b:32; a:255 ) ,
180
(name:'gray'; r:128; g:128; b:128; a:255 ) ,
181
(name:'green'; r:0; g:128; b:0; a:255 ) ,
182
(name:'greenyellow'; r:173; g:255; b:47; a:255 ) ,
183
(name:'grey'; r:128; g:128; b:128; a:255 ) ,
184
(name:'honeydew'; r:240; g:255; b:240; a:255 ) ,
185
(name:'hotpink'; r:255; g:105; b:180; a:255 ) ,
186
(name:'indianred'; r:205; g:92; b:92; a:255 ) ,
187
(name:'indigo'; r:75; g:0; b:130; a:255 ) ,
188
(name:'ivory'; r:255; g:255; b:240; a:255 ) ,
189
(name:'khaki'; r:240; g:230; b:140; a:255 ) ,
190
(name:'lavender'; r:230; g:230; b:250; a:255 ) ,
191
(name:'lavenderblush'; r:255; g:240; b:245; a:255 ) ,
192
(name:'lawngreen'; r:124; g:252; b:0; a:255 ) ,
193
(name:'lemonchiffon'; r:255; g:250; b:205; a:255 ) ,
194
(name:'lightblue'; r:173; g:216; b:230; a:255 ) ,
195
(name:'lightcoral'; r:240; g:128; b:128; a:255 ) ,
196
(name:'lightcyan'; r:224; g:255; b:255; a:255 ) ,
197
(name:'lightgoldenrodyellow'; r:250; g:250; b:210; a:255 ) ,
198
(name:'lightgray'; r:211; g:211; b:211; a:255 ) ,
199
(name:'lightgreen'; r:144; g:238; b:144; a:255 ) ,
200
(name:'lightgrey'; r:211; g:211; b:211; a:255 ) ,
201
(name:'lightpink'; r:255; g:182; b:193; a:255 ) ,
202
(name:'lightsalmon'; r:255; g:160; b:122; a:255 ) ,
203
(name:'lightseagreen'; r:32; g:178; b:170; a:255 ) ,
204
(name:'lightskyblue'; r:135; g:206; b:250; a:255 ) ,
205
(name:'lightslategray'; r:119; g:136; b:153; a:255 ) ,
206
(name:'lightslategrey'; r:119; g:136; b:153; a:255 ) ,
207
(name:'lightsteelblue'; r:176; g:196; b:222; a:255 ) ,
208
(name:'lightyellow'; r:255; g:255; b:224; a:255 ) ,
209
(name:'lime'; r:0; g:255; b:0; a:255 ) ,
210
(name:'limegreen'; r:50; g:205; b:50; a:255 ) ,
211
(name:'linen'; r:250; g:240; b:230; a:255 ) ,
212
(name:'magenta'; r:255; g:0; b:255; a:255 ) ,
213
(name:'maroon'; r:128; g:0; b:0; a:255 ) ,
214
(name:'mediumaquamarine'; r:102; g:205; b:170; a:255 ) ,
215
(name:'mediumblue'; r:0; g:0; b:205; a:255 ) ,
216
(name:'mediumorchid'; r:186; g:85; b:211; a:255 ) ,
217
(name:'mediumpurple'; r:147; g:112; b:219; a:255 ) ,
218
(name:'mediumseagreen'; r:60; g:179; b:113; a:255 ) ,
219
(name:'mediumslateblue'; r:123; g:104; b:238; a:255 ) ,
220
(name:'mediumspringgreen'; r:0; g:250; b:154; a:255 ) ,
221
(name:'mediumturquoise'; r:72; g:209; b:204; a:255 ) ,
222
(name:'mediumvioletred'; r:199; g:21; b:133; a:255 ) ,
223
(name:'midnightblue'; r:25; g:25; b:112; a:255 ) ,
224
(name:'mintcream'; r:245; g:255; b:250; a:255 ) ,
225
(name:'mistyrose'; r:255; g:228; b:225; a:255 ) ,
226
(name:'moccasin'; r:255; g:228; b:181; a:255 ) ,
227
(name:'navajowhite'; r:255; g:222; b:173; a:255 ) ,
228
(name:'navy'; r:0; g:0; b:128; a:255 ) ,
229
(name:'oldlace'; r:253; g:245; b:230; a:255 ) ,
230
(name:'olive'; r:128; g:128; b:0; a:255 ) ,
231
(name:'olivedrab'; r:107; g:142; b:35; a:255 ) ,
232
(name:'orange'; r:255; g:165; b:0; a:255 ) ,
233
(name:'orangered'; r:255; g:69; b:0; a:255 ) ,
234
(name:'orchid'; r:218; g:112; b:214; a:255 ) ,
235
(name:'palegoldenrod'; r:238; g:232; b:170; a:255 ) ,
236
(name:'palegreen'; r:152; g:251; b:152; a:255 ) ,
237
(name:'paleturquoise'; r:175; g:238; b:238; a:255 ) ,
238
(name:'palevioletred'; r:219; g:112; b:147; a:255 ) ,
239
(name:'papayawhip'; r:255; g:239; b:213; a:255 ) ,
240
(name:'peachpuff'; r:255; g:218; b:185; a:255 ) ,
241
(name:'peru'; r:205; g:133; b:63; a:255 ) ,
242
(name:'pink'; r:255; g:192; b:203; a:255 ) ,
243
(name:'plum'; r:221; g:160; b:221; a:255 ) ,
244
(name:'powderblue'; r:176; g:224; b:230; a:255 ) ,
245
(name:'purple'; r:128; g:0; b:128; a:255 ) ,
246
(name:'red'; r:255; g:0; b:0; a:255 ) ,
247
(name:'rosybrown'; r:188; g:143; b:143; a:255 ) ,
248
(name:'royalblue'; r:65; g:105; b:225; a:255 ) ,
249
(name:'saddlebrown'; r:139; g:69; b:19; a:255 ) ,
250
(name:'salmon'; r:250; g:128; b:114; a:255 ) ,
251
(name:'sandybrown'; r:244; g:164; b:96; a:255 ) ,
252
(name:'seagreen'; r:46; g:139; b:87; a:255 ) ,
253
(name:'seashell'; r:255; g:245; b:238; a:255 ) ,
254
(name:'sienna'; r:160; g:82; b:45; a:255 ) ,
255
(name:'silver'; r:192; g:192; b:192; a:255 ) ,
256
(name:'skyblue'; r:135; g:206; b:235; a:255 ) ,
257
(name:'slateblue'; r:106; g:90; b:205; a:255 ) ,
258
(name:'slategray'; r:112; g:128; b:144; a:255 ) ,
259
(name:'slategrey'; r:112; g:128; b:144; a:255 ) ,
260
(name:'snow'; r:255; g:250; b:250; a:255 ) ,
261
(name:'springgreen'; r:0; g:255; b:127; a:255 ) ,
262
(name:'steelblue'; r:70; g:130; b:180; a:255 ) ,
263
(name:'tan'; r:210; g:180; b:140; a:255 ) ,
264
(name:'teal'; r:0; g:128; b:128; a:255 ) ,
265
(name:'thistle'; r:216; g:191; b:216; a:255 ) ,
266
(name:'tomato'; r:255; g:99; b:71; a:255 ) ,
267
(name:'turquoise'; r:64; g:224; b:208; a:255 ) ,
268
(name:'violet'; r:238; g:130; b:238; a:255 ) ,
269
(name:'wheat'; r:245; g:222; b:179; a:255 ) ,
270
(name:'white'; r:255; g:255; b:255; a:255 ) ,
271
(name:'whitesmoke'; r:245; g:245; b:245; a:255 ) ,
272
(name:'yellow'; r:255; g:255; b:0; a:255 ) ,
273
(name:'yellowgreen'; r:154; g:205; b:50; a:255 ) ,
274
(name:'zzzzzzzzzzz'; r:0; g:0; b:0; a:0 ) );
276
pageEqHigh : shortstring =
277
#1#2#3#4#5#6#7#8#9#10#11#12#13#14#15#16 +
278
#17#18#19#20#21#22#23#24#25#26#27#28#29#30#31#32 +
279
#33#34#35#36#37#38#39#40#41#42#43#44#45#46#47#48 +
280
#49#50#51#52#53#54#55#56#57#58#59#60#61#62#63#64 +
281
#65#66#67#68#69#70#71#72#73#74#75#76#77#78#79#80 +
282
#81#82#83#84#85#86#87#88#89#90#91#92#93#94#95#96 +
283
#65#66#67#68#69#70#71#72#73#74#75#76#77#78#79#80 +
284
#81#82#83#84#85#86#87#88#89#90#123#124#125#126#127#128 +
285
#129#130#131#132#133#134#135#136#137#138#139#140#141#142#143#144 +
286
#145#146#147#148#149#150#151#152#153#154#155#156#157#158#159#160 +
287
#161#162#163#164#165#166#167#168#169#170#171#172#173#174#175#176 +
288
#177#178#179#180#181#182#183#184#185#186#187#188#189#190#191#192 +
289
#193#194#195#196#197#198#199#200#201#202#203#204#205#206#207#208 +
290
#209#210#211#212#213#214#215#216#217#218#219#220#221#222#223#224 +
291
#225#226#227#228#229#230#231#232#233#234#235#236#237#238#239#240 +
292
#241#242#243#244#245#246#247#248#249#250#251#252#253#254#255;
294
{ UNIT IMPLEMENTATION }
296
procedure start_element;
301
this:=parser_ptr(data );
303
if StrComp(PChar(el ) ,'title' ) = 0 then
304
this.m_title_flag:=true
306
if StrComp(PChar(el ) ,'g' ) = 0 then
308
this.m_path.push_attr;
309
this.parse_attr(attr );
313
if StrComp(PChar(el ) ,'path' ) = 0 then
315
if this.m_path_flag then
316
raise svg_exception.Construct(PChar('start_element: Nested path' ) );
318
this.m_path.begin_path;
319
this.parse_path(attr );
320
this.m_path.end_path;
322
this.m_path_flag:=true;
326
if StrComp(PChar(el ) ,'rect' ) = 0 then
327
this.parse_rect(attr )
329
if StrComp(PChar(el ) ,'line' ) = 0 then
330
this.parse_line(attr )
332
if StrComp(PChar(el ) ,'polyline' ) = 0 then
333
this.parse_poly(attr ,false )
335
if StrComp(PChar(el ) ,'polygon' ) = 0 then
336
this.parse_poly(attr ,true );
339
// if StrComp(PChar(el ) ,'<OTHER_ELEMENTS>' ) = 0 then
347
procedure end_element;
352
this:=parser_ptr(data );
354
if StrComp(PChar(el ) ,'title' ) = 0 then
355
this.m_title_flag:=false
357
if StrComp(PChar(el ) ,'g' ) = 0 then
360
if StrComp(PChar(el ) ,'path' ) = 0 then
361
this.m_path_flag:=false;
364
// if StrComp(PChar(el ) ,'<OTHER_ELEMENTS>' ) = 0 then
377
this:=parser_ptr(data );
379
// m_title_flag signals that the <title> tag is being parsed now.
380
// The following code concatenates the pieces of content of the <title> tag.
381
if this.m_title_flag then
383
if len + this.m_title_len > 255 then
384
len:=255 - this.m_title_len;
390
char_ptr(ptrcomp(this.m_title ) + this.m_title_len )^ ,
393
inc(this.m_title_len ,len );
395
char_ptr(ptrcomp(this.m_title ) + this.m_title_len )^:=#0;
404
function hex_unsigned(hexstr : agg_basics.char_ptr ) : unsigned;
406
function xyint(x ,y : integer ) : integer;
443
hex : string[16 ] = '0123456789ABCDEF';
448
while hexstr^ <> #0 do
450
h:=h + pageEqHigh[byte(hexstr^ ) ];
452
inc(ptrcomp(hexstr ) );
456
if length(h ) > 0 then
458
case h[length(h ) ] of
465
num:=pos(h[length(h ) ] ,hex ) - 1;
469
if length(h ) > 1 then
470
for fcb:=length(h ) - 1 downto 1 do
479
inc(num ,(pos(h[fcb ] ,hex ) - 1 ) * mul );
499
function parse_color(str : agg_basics.char_ptr ) : aggclr;
513
u:=hex_unsigned(str );
515
result.Construct(rgb8_packed(u ) );
522
for u:=0 to colors_num - 1 do
523
if StrComp(colors[u ].name ,PChar(str ) ) = 0 then
533
m:='parse_color: Invalid color name ' + StrPas(PChar(str ) ) + #0;
535
raise svg_exception.Construct(PChar(@m[1 ] ) );
539
result.ConstrInt(p.r ,p.g ,p.b ,p.a );
546
function parse_double(str : agg_basics.char_ptr ) : double;
551
result:=get_double(pointer(PChar(str ) ) );
556
function islower(ch : char ) : boolean;
570
function is_numeric(ch : char ) : boolean;
572
result:=Pos(ch ,'0123456789+-.eE' ) <> 0;
576
{ parse_transform_args }
577
function parse_transform_args(str : agg_basics.char_ptr; args : double_ptr; max_na : unsigned; na : unsigned_ptr ) : unsigned;
579
ptr ,end_ : agg_basics.char_ptr;
585
while (ptr^ <> #0 ) and
590
raise svg_exception.Construct(PChar('parse_transform_args: Invalid syntax' ) );
594
while (end_^ <> #0 ) and
596
inc(ptrcomp(end_ ) );
599
raise svg_exception.Construct(PChar('parse_transform_args: Invalid syntax' ) );
601
while ptrcomp(ptr ) < ptrcomp(end_ ) do
602
if is_numeric(ptr^ ) then
604
if na^ >= max_na then
605
raise svg_exception.Construct(PChar('parse_transform_args: Too many arguments' ) );
607
double_ptr(ptrcomp(args ) + na^ * sizeof(double ) )^:=get_double(ptr );
611
while (ptrcomp(ptr ) < ptrcomp(end_ ) ) and
619
result:=unsigned(ptrcomp(end_ ) - ptrcomp(str ) );
624
constructor parser.Construct(path : path_renderer_ptr );
628
m_tokenizer.Construct;
630
agg_getmem(pointer(m_buf ) ,buf_size );
631
agg_getmem(pointer(m_title ) ,256 );
637
m_attr_name_aloc :=128;
638
m_attr_value_aloc:=1024;
640
agg_getmem(pointer(m_attr_name ) ,m_attr_name_aloc );
641
agg_getmem(pointer(m_attr_value ) ,m_attr_value_aloc );
643
m_attr_name_len :=127;
644
m_attr_value_len:=1023;
651
destructor parser.Destruct;
653
agg_freemem(pointer(m_attr_value ) ,m_attr_value_aloc );
654
agg_freemem(pointer(m_attr_name ) ,m_attr_name_aloc );
655
agg_freemem(pointer(m_title ) ,256 );
656
agg_freemem(pointer(m_buf ) ,buf_size );
660
procedure parser.parse(fname: string);
664
fs:=TFileStream.Create(UTF8ToSys(fname),fmOpenRead+fmShareDenyWrite);
673
procedure parser.parse(sourcestream: TStream);
683
p:=XML_ParserCreate(NIL );
686
raise svg_exception.Construct(PChar('Couldn''t allocate memory for parser' ) );
688
XML_SetUserData (p ,@self );
689
XML_SetElementHandler (p ,@start_element ,@end_element );
690
XML_SetCharacterDataHandler(p ,@content );
695
len:=sourcestream.Read(m_buf^,buf_size);
697
done:=len < buf_size;
698
writeln('parser.parse ',done,' ',len,' ',buf_size);
700
if XML_Parse(p ,pointer(m_buf ) ,len ,int(done ) ) = XML_STATUS_ERROR then
703
Msg:=PChar(XML_ErrorString(XML_GetErrorCode(p)));
704
Msg:=' at line '+IntToStr(XML_GetCurrentLineNumber(p));
705
raise svg_exception.Construct(PChar(Msg) );
715
if byte(ts^ ) < byte(' ' ) then
728
function parser.title;
735
procedure parser.parse_attr(attr : char_ptr_ptr );
742
while char_ptr_ptr(ptrcomp(attr ) + i * sizeof(char_ptr ) )^ <> NIL do
744
if StrComp(PChar(char_ptr_ptr(ptrcomp(attr ) + i * sizeof(char_ptr ) )^ ) ,'style' ) = 0 then
745
parse_style(agg_basics.char_ptr_ptr(ptrcomp(attr ) + (i + 1 ) * sizeof(char_ptr ) )^ )
748
agg_basics.char_ptr_ptr(ptrcomp(attr ) + i * sizeof(char_ptr ) )^ ,
749
agg_basics.char_ptr_ptr(ptrcomp(attr ) + (i + 1 ) * sizeof(char_ptr ) )^ );
758
procedure parser.parse_path;
762
tmp : array[0..3 ] of agg_basics.char_ptr;
767
while char_ptr_ptr(ptrcomp(attr ) + i * sizeof(char_ptr ) )^ <> NIL do
769
// The <path> tag can consist of the path itself ("d=")
770
// as well as of other parameters like "style=", "transform=", etc.
771
// In the last case we simply rely on the function of parsing
772
// attributes (see 'else' branch).
773
if StrComp(PChar(char_ptr_ptr(ptrcomp(attr ) + i * sizeof(char_ptr ) )^ ) ,'d' ) = 0 then
775
m_tokenizer.set_path_str(agg_basics.char_ptr_ptr(ptrcomp(attr ) + (i + 1 ) * sizeof(char_ptr ) )^ );
777
m_path.parse_path(@m_tokenizer );
782
// Create a temporary single pair "name-value" in order
783
// to avoid multiple calls for the same attribute.
784
tmp[0 ]:=agg_basics.char_ptr_ptr(ptrcomp(attr ) + i * sizeof(char_ptr ) )^;
785
tmp[1 ]:=agg_basics.char_ptr_ptr(ptrcomp(attr ) + (i + 1 ) * sizeof(char_ptr ) )^;
800
procedure parser.parse_poly;
814
while char_ptr_ptr(ptrcomp(attr ) + i * sizeof(char_ptr ) )^ <> NIL do
817
agg_basics.char_ptr_ptr(ptrcomp(attr ) + i * sizeof(char_ptr ) )^ ,
818
agg_basics.char_ptr_ptr(ptrcomp(attr ) + (i + 1 ) * sizeof(char_ptr ) )^ ) then
819
if StrComp(PChar(agg_basics.char_ptr_ptr(ptrcomp(attr ) + i * sizeof(char_ptr ) )^ ) ,'points' ) = 0 then
821
m_tokenizer.set_path_str(agg_basics.char_ptr_ptr(ptrcomp(attr ) + (i + 1 ) * sizeof(char_ptr ) )^ );
823
if not m_tokenizer.next then
824
raise svg_exception.Construct(PChar('parse_poly: Too few coordinates' ) );
826
x:=m_tokenizer.last_number;
828
if not m_tokenizer.next then
829
raise svg_exception.Construct(PChar('parse_poly: Too few coordinates' ) );
831
y:=m_tokenizer.last_number;
833
m_path.move_to(x ,y );
835
while m_tokenizer.next do
837
x:=m_tokenizer.last_number;
839
if not m_tokenizer.next then
840
raise svg_exception.Construct(PChar('parse_poly: Odd number of coordinates' ) );
842
y:=m_tokenizer.last_number;
844
m_path.line_to(x ,y );
859
procedure parser.parse_rect;
875
while char_ptr_ptr(ptrcomp(attr ) + i * sizeof(char_ptr ) )^ <> NIL do
878
agg_basics.char_ptr_ptr(ptrcomp(attr ) + i * sizeof(char_ptr ) )^ ,
879
agg_basics.char_ptr_ptr(ptrcomp(attr ) + (i + 1 ) * sizeof(char_ptr ) )^ ) then
881
if StrComp(PChar(char_ptr_ptr(ptrcomp(attr ) + i * sizeof(char_ptr ) )^ ) ,'x' ) = 0 then
882
x:=parse_double(agg_basics.char_ptr_ptr(ptrcomp(attr ) + (i + 1 ) * sizeof(char_ptr ) )^ );
884
if StrComp(PChar(char_ptr_ptr(ptrcomp(attr ) + i * sizeof(char_ptr ) )^ ) ,'y' ) = 0 then
885
y:=parse_double(agg_basics.char_ptr_ptr(ptrcomp(attr ) + (i + 1 ) * sizeof(char_ptr ) )^ );
887
if StrComp(PChar(char_ptr_ptr(ptrcomp(attr ) + i * sizeof(char_ptr ) )^ ) ,'width' ) = 0 then
888
w:=parse_double(agg_basics.char_ptr_ptr(ptrcomp(attr ) + (i + 1 ) * sizeof(char_ptr ) )^ );
890
if StrComp(PChar(char_ptr_ptr(ptrcomp(attr ) + i * sizeof(char_ptr ) )^ ) ,'height' ) = 0 then
891
h:=parse_double(agg_basics.char_ptr_ptr(ptrcomp(attr ) + (i + 1 ) * sizeof(char_ptr ) )^ );
893
// rx - to be implemented
894
// ry - to be implemented
906
raise svg_exception.Construct(PChar('parse_rect: Invalid width: ' ) );
909
raise svg_exception.Construct(PChar('parse_rect: Invalid height: ' ) );
911
m_path.move_to(x ,y );
912
m_path.line_to(x + w ,y );
913
m_path.line_to(x + w ,y + h );
914
m_path.line_to(x ,y + h );
915
m_path.close_subpath;
924
procedure parser.parse_line;
928
x1 ,y1 ,x2 ,y2 : double;
940
while char_ptr_ptr(ptrcomp(attr ) + i * sizeof(char_ptr ) )^ <> NIL do
943
agg_basics.char_ptr_ptr(ptrcomp(attr ) + i * sizeof(char_ptr ) )^ ,
944
agg_basics.char_ptr_ptr(ptrcomp(attr ) + (i + 1 ) * sizeof(char_ptr ) )^ ) then
946
if StrComp(PChar(char_ptr_ptr(ptrcomp(attr ) + i * sizeof(char_ptr ) )^ ) ,'x1' ) = 0 then
947
x1:=parse_double(agg_basics.char_ptr_ptr(ptrcomp(attr ) + (i + 1 ) * sizeof(char_ptr ) )^ );
949
if StrComp(PChar(char_ptr_ptr(ptrcomp(attr ) + i * sizeof(char_ptr ) )^ ) ,'y1' ) = 0 then
950
y1:=parse_double(agg_basics.char_ptr_ptr(ptrcomp(attr ) + (i + 1 ) * sizeof(char_ptr ) )^ );
952
if StrComp(PChar(char_ptr_ptr(ptrcomp(attr ) + i * sizeof(char_ptr ) )^ ) ,'x2' ) = 0 then
953
x2:=parse_double(agg_basics.char_ptr_ptr(ptrcomp(attr ) + (i + 1 ) * sizeof(char_ptr ) )^ );
955
if StrComp(PChar(char_ptr_ptr(ptrcomp(attr ) + i * sizeof(char_ptr ) )^ ) ,'y2' ) = 0 then
956
y2:=parse_double(agg_basics.char_ptr_ptr(ptrcomp(attr ) + (i + 1 ) * sizeof(char_ptr ) )^ );
964
m_path.move_to(x1 ,y1 );
965
m_path.line_to(x2 ,y2 );
971
procedure parser.parse_style;
973
nv_start ,nv_end : agg_basics.char_ptr;
979
while (str^ <> #0 ) and
985
while (str^ <> #0 ) and
992
while (ptrcomp(nv_end ) > ptrcomp(nv_start ) ) and
994
(nv_end^ = ' ' ) ) do
995
dec(ptrcomp(nv_end ) );
997
inc(ptrcomp(nv_end ) );
999
parse_name_value(nv_start ,nv_end );
1002
inc(ptrcomp(str ) );
1009
procedure parser.parse_transform;
1013
if islower(str^ ) then
1014
if StrLComp(PChar(str ) ,'matrix' ,6 ) = 0 then
1015
inc(ptrcomp(str ) ,parse_matrix(str ) )
1017
if StrLComp(PChar(str ) ,'translate' ,9 ) = 0 then
1018
inc(ptrcomp(str ) ,parse_translate(str ) )
1020
if StrLComp(PChar(str ) ,'rotate' ,6 ) = 0 then
1021
inc(ptrcomp(str ) ,parse_rotate(str ) )
1023
if StrLComp(PChar(str ) ,'scale' ,5 ) = 0 then
1024
inc(ptrcomp(str ) ,parse_scale(str ) )
1026
if StrLComp(PChar(str ) ,'skewX' ,5 ) = 0 then
1027
inc(ptrcomp(str ) ,parse_skew_x(str ) )
1029
if StrLComp(PChar(str ) ,'skewY' ,5 ) = 0 then
1030
inc(ptrcomp(str ) ,parse_skew_y(str ) )
1035
inc(ptrcomp(str ) );
1042
function parser.parse_matrix;
1044
args : array[0..5 ] of double;
1052
len:=parse_transform_args(str ,@args ,6 ,@na );
1055
raise svg_exception.Construct(PChar('parse_matrix: Invalid number of arguments' ) );
1057
ta.Construct(args[0 ] ,args[1 ] ,args[2 ] ,args[3 ] ,args[4 ] ,args[5 ] );
1059
m_path.transform.premultiply(@ta );
1066
function parser.parse_translate;
1068
args : array[0..1 ] of double;
1072
tat : trans_affine_translation;
1076
len:=parse_transform_args(str ,@args ,2 ,@na );
1081
tat.Construct(args[0 ] ,args[1 ] );
1083
m_path.transform.premultiply(@tat );
1090
function parser.parse_rotate;
1092
args : array[0..2 ] of double;
1096
tar : trans_affine_rotation;
1098
tat ,t : trans_affine_translation;
1102
len:=parse_transform_args(str ,@args ,3 ,@na );
1106
tar.Construct(deg2rad(args[0 ] ) );
1108
m_path.transform.premultiply(@tar );
1114
t.Construct(-args[1 ] ,-args[2 ] );
1116
tar.Construct(deg2rad(args[0 ] ) );
1117
tat.Construct(args[1 ] ,args[2 ] );
1122
m_path.transform.premultiply(@t );
1126
raise svg_exception.Construct(PChar('parse_rotate: Invalid number of arguments' ) );
1133
function parser.parse_scale;
1135
args : array[0..1 ] of double;
1139
tas : trans_affine_scaling;
1143
len:=parse_transform_args(str ,@args ,2 ,@na );
1148
tas.Construct(args[0 ] ,args[1 ] );
1150
m_path.transform.premultiply(@tas );
1157
function parser.parse_skew_x;
1163
tas : trans_affine_skewing;
1167
len:=parse_transform_args(str ,@arg ,1 ,@na );
1169
tas.Construct(deg2rad(arg ) ,0.0 );
1171
m_path.transform.premultiply(@tas );
1178
function parser.parse_skew_y;
1184
tas : trans_affine_skewing;
1188
len:=parse_transform_args(str ,@arg ,1 ,@na );
1190
tas.Construct(0.0 ,deg2rad(arg ) );
1192
m_path.transform.premultiply(@tas );
1199
function parser.parse_attr(name ,value : agg_basics.char_ptr ) : boolean;
1206
if StrComp(PChar(name ) ,'style' ) = 0 then
1209
if StrComp(PChar(name ) ,'fill' ) = 0 then
1210
if StrComp(PChar(value ) ,'none' ) = 0 then
1214
clr:=parse_color(value );
1220
if StrComp(PChar(name ) ,'fill-opacity' ) = 0 then
1221
m_path.fill_opacity(parse_double(value ) )
1223
if StrComp(PChar(name ) ,'stroke' ) = 0 then
1224
if StrComp(PChar(value ) ,'none' ) = 0 then
1228
clr:=parse_color(value );
1230
m_path.stroke(@clr );
1234
if StrComp(PChar(name ) ,'stroke-width' ) = 0 then
1235
m_path.stroke_width(parse_double(value ) )
1237
if StrComp(PChar(name ) ,'stroke-linecap' ) = 0 then
1239
if StrComp(PChar(value ) ,'butt' ) = 0 then
1240
m_path.line_cap(butt_cap )
1242
if StrComp(PChar(value ) ,'round' ) = 0 then
1243
m_path.line_cap(round_cap )
1245
if StrComp(PChar(value ) ,'square' ) = 0 then
1246
m_path.line_cap(square_cap );
1250
if StrComp(PChar(name ) ,'stroke-linejoin' ) = 0 then
1252
if StrComp(PChar(value ) ,'miter' ) = 0 then
1253
m_path.line_join(miter_join )
1255
if StrComp(PChar(value ) ,'round' ) = 0 then
1256
m_path.line_join(round_join )
1258
if StrComp(PChar(value ) ,'bevel' ) = 0 then
1259
m_path.line_join(bevel_join );
1263
if StrComp(PChar(name ) ,'stroke-miterlimit' ) = 0 then
1264
m_path.miter_limit(parse_double(value ) )
1266
if StrComp(PChar(name ) ,'stroke-opacity' ) = 0 then
1267
m_path.stroke_opacity(parse_double(value ) )
1269
if StrComp(PChar(name ) ,'transform' ) = 0 then
1270
parse_transform(value )
1273
// if StrComp(PChar(el ) ,'<OTHER_ATTRIBUTES>' ) = 0 then
1283
{ PARSE_NAME_VALUE }
1284
function parser.parse_name_value;
1286
str ,val : agg_basics.char_ptr;
1291
while (ptrcomp(str ) < ptrcomp(nv_end ) ) and
1293
inc(ptrcomp(str ) );
1298
while (ptrcomp(str ) > ptrcomp(nv_start ) ) and
1301
dec(ptrcomp(str ) );
1303
inc(ptrcomp(str ) );
1305
copy_name(nv_start ,str );
1307
while (ptrcomp(val ) < ptrcomp(nv_end ) ) and
1310
inc(ptrcomp(val ) );
1312
copy_value(val ,nv_end );
1314
result:=parse_attr(agg_basics.char_ptr(m_attr_name ) ,agg_basics.char_ptr(m_attr_value ) );
1319
procedure parser.copy_name;
1324
len:=ptrcomp(end_ ) - ptrcomp(start );
1326
if (m_attr_name_len = 0 ) or
1327
(len > m_attr_name_len ) then
1329
agg_freemem(pointer(m_attr_name ) ,m_attr_name_aloc );
1331
m_attr_name_aloc:=len + 1;
1333
agg_freemem(pointer(m_attr_name ) ,m_attr_name_aloc );
1335
m_attr_name_len:=len;
1340
move(start^ ,m_attr_name^ ,len );
1342
char_ptr(ptrcomp(m_attr_name ) + len )^:=#0;
1347
procedure parser.copy_value;
1352
len:=ptrcomp(end_ ) - ptrcomp(start );
1354
if (m_attr_value_len = 0 ) or
1355
(len > m_attr_value_len ) then
1357
agg_freemem(pointer(m_attr_value ) ,m_attr_value_aloc );
1359
m_attr_value_aloc:=len + 1;
1361
agg_getmem(pointer(m_attr_value ) ,m_attr_value_aloc );
1363
m_attr_value_len:=len;
1368
move(start^ ,m_attr_value^ ,len );
1370
char_ptr(ptrcomp(m_attr_value ) + len )^:=#0;