~ubuntu-branches/ubuntu/saucy/lazarus/saucy

« back to all changes in this revision

Viewing changes to components/aggpas/src/svg/agg_svg_parser_lcl.pas

  • Committer: Package Import Robot
  • Author(s): Paul Gevers, Abou Al Montacir, Bart Martens, Paul Gevers
  • Date: 2013-06-08 14:12:17 UTC
  • mfrom: (1.1.9)
  • Revision ID: package-import@ubuntu.com-20130608141217-7k0cy9id8ifcnutc
Tags: 1.0.8+dfsg-1
[ Abou Al Montacir ]
* New upstream major release and multiple maintenace release offering many
  fixes and new features marking a new milestone for the Lazarus development
  and its stability level.
  - The detailed list of changes can be found here:
    http://wiki.lazarus.freepascal.org/Lazarus_1.0_release_notes
    http://wiki.lazarus.freepascal.org/Lazarus_1.0_fixes_branch
* LCL changes:
  - LCL is now a normal package.
      + Platform independent parts of the LCL are now in the package LCLBase
      + LCL is automatically recompiled when switching the target platform,
        unless pre-compiled binaries for this target are already installed.
      + No impact on existing projects.
      + Linker options needed by LCL are no more added to projects that do
        not use the LCL package.
  - Minor changes in LCL basic classes behaviour
      + TCustomForm.Create raises an exception if a form resource is not
        found.
      + TNotebook and TPage: a new implementation of these classes was added.
      + TDBNavigator: It is now possible to have focusable buttons by setting
        Options = [navFocusableButtons] and TabStop = True, useful for
        accessibility and for devices with neither mouse nor touch screen.
      + Names of TControlBorderSpacing.GetSideSpace and GetSpace were swapped
        and are now consistent. GetSideSpace = Around + GetSpace.
      + TForm.WindowState=wsFullscreen was added
      + TCanvas.TextFitInfo was added to calculate how many characters will
        fit into a specified Width. Useful for word-wrapping calculations.
      + TControl.GetColorResolvingParent and
        TControl.GetRGBColorResolvingParent were added, simplifying the work
        to obtain the final color of the control while resolving clDefault
        and the ParentColor.
      + LCLIntf.GetTextExtentExPoint now has a good default implementation
        which works in any platform not providing a specific implementation.
        However, Widgetset specific implementation is better, when available.
      + TTabControl was reorganized. Now it has the correct class hierarchy
        and inherits from TCustomTabControl as it should.
  - New unit in the LCL:
      + lazdialogs.pas: adds non-native versions of various native dialogs,
        for example TLazOpenDialog, TLazSaveDialog, TLazSelectDirectoryDialog.
        It is used by widgetsets which either do not have a native dialog, or
        do not wish to use it because it is limited. These dialogs can also be
        used by user applications directly.
      + lazdeviceapis.pas: offers an interface to more hardware devices such
        as the accelerometer, GPS, etc. See LazDeviceAPIs
      + lazcanvas.pas: provides a TFPImageCanvas descendent implementing
        drawing in a LCL-compatible way, but 100% in Pascal.
      + lazregions.pas. LazRegions is a wholly Pascal implementation of
        regions for canvas clipping, event clipping, finding in which control
        of a region tree one an event should reach, for drawing polygons, etc.
      + customdrawncontrols.pas, customdrawndrawers.pas,
        customdrawn_common.pas, customdrawn_android.pas and
        customdrawn_winxp.pas: are the Lazarus Custom Drawn Controls -controls
        which imitate the standard LCL ones, but with the difference that they
        are non-native and support skinning.
  - New APIs added to the LCL to improve support of accessibility software
    such as screen readers.
* IDE changes:
  - Many improvments.
  - The detailed list of changes can be found here:
    http://wiki.lazarus.freepascal.org/New_IDE_features_since#v1.0_.282012-08-29.29
    http://wiki.lazarus.freepascal.org/Lazarus_1.0_release_notes#IDE_Changes
* Debugger / Editor changes:
  - Added pascal sources and breakpoints to the disassembler
  - Added threads dialog.
* Components changes:
  - TAChart: many fixes and new features
  - CodeTool: support Delphi style generics and new syntax extensions.
  - AggPas: removed to honor free licencing. (Closes: Bug#708695)
[Bart Martens]
* New debian/watch file fixing issues with upstream RC release.
[Abou Al Montacir]
* Avoid changing files in .pc hidden directory, these are used by quilt for
  internal purpose and could lead to surprises during build.
[Paul Gevers]
* Updated get-orig-source target and it compinion script orig-tar.sh so that they
  repack the source file, allowing bug 708695 to be fixed.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
//----------------------------------------------------------------------------
2
 
// Anti-Grain Geometry - Version 2.4 (Public License)
3
 
// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
4
 
//
5
 
// Anti-Grain Geometry - Version 2.4 Release Milano 3 (AggPas 2.4 RM3)
6
 
// Pascal Port By: Milan Marusinec alias Milano
7
 
//                 milan@marusinec.sk
8
 
//                 http://www.aggpas.org
9
 
// Copyright (c) 2005-2006
10
 
//
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.
15
 
//
16
 
//----------------------------------------------------------------------------
17
 
// Contact: mcseem@antigrain.com
18
 
//          mcseemagg@yahoo.com
19
 
//          http://www.antigrain.com
20
 
//
21
 
// [Pascal Port History] -----------------------------------------------------
22
 
//
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
26
 
//
27
 
{ agg_svg_parser.pas }
28
 
unit
29
 
 agg_svg_parser_lcl ;
30
 
 
31
 
INTERFACE
32
 
 
33
 
{$DEFINE EXPAT_WRAPPER }
34
 
{$I agg_mode.inc }
35
 
 
36
 
uses
37
 
 Classes, SysUtils ,
38
 
 agg_basics ,
39
 
 agg_color ,
40
 
 agg_svg_path_tokenizer ,
41
 
 agg_svg_path_renderer ,
42
 
 agg_svg_exception ,
43
 
 agg_trans_affine ,
44
 
 agg_math_stroke ,
45
 
 expat ,
46
 
 FileUtil ;
47
 
 
48
 
{ TYPES DEFINITION }
49
 
const
50
 
 buf_size = 512;
51
 
 
52
 
type
53
 
 parser_ptr = ^parser;
54
 
 
55
 
 { parser }
56
 
 
57
 
 parser = object
58
 
   m_path      : path_renderer_ptr;
59
 
   m_tokenizer : path_tokenizer;
60
 
 
61
 
   m_buf   ,
62
 
   m_title : char_ptr;
63
 
 
64
 
   m_title_len  : unsigned;
65
 
   m_title_flag ,
66
 
   m_path_flag  : boolean;
67
 
   m_attr_name  ,
68
 
   m_attr_value : char_ptr;
69
 
 
70
 
   m_attr_name_len   ,
71
 
   m_attr_name_aloc  ,
72
 
   m_attr_value_len  ,
73
 
   m_attr_value_aloc : unsigned;
74
 
 
75
 
   constructor Construct(path : path_renderer_ptr );
76
 
   destructor  Destruct;
77
 
 
78
 
   procedure parse(fname : string ); overload; // UTF8
79
 
   procedure parse(sourcestream: TStream); overload;
80
 
   function  title : char_ptr;
81
 
 
82
 
  // XML event handlers
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 );
90
 
 
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;
97
 
 
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;
100
 
 
101
 
   procedure copy_name (start ,end_ : agg_basics.char_ptr );
102
 
   procedure copy_value(start ,end_ : agg_basics.char_ptr );
103
 
 
104
 
  end;
105
 
 
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 }
110
 
 
111
 
 
112
 
IMPLEMENTATION
113
 
{ LOCAL VARIABLES & CONSTANTS }
114
 
type
115
 
 named_color_ptr = ^named_color;
116
 
 named_color = record
117
 
   name : array[0..21 ] of char;
118
 
 
119
 
   r ,g ,b ,a : int8u;
120
 
 
121
 
  end;
122
 
 
123
 
const
124
 
 colors_num = 148;
125
 
 
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   ) );
275
 
 
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;
293
 
 
294
 
{ UNIT IMPLEMENTATION }
295
 
{ START_ELEMENT }
296
 
procedure start_element;
297
 
var
298
 
 this : parser_ptr;
299
 
 
300
 
begin
301
 
 this:=parser_ptr(data );
302
 
 
303
 
 if StrComp(PChar(el ) ,'title' ) = 0 then
304
 
  this.m_title_flag:=true
305
 
 else
306
 
  if StrComp(PChar(el ) ,'g' ) = 0 then
307
 
   begin
308
 
    this.m_path.push_attr;
309
 
    this.parse_attr(attr );
310
 
 
311
 
   end
312
 
  else
313
 
   if StrComp(PChar(el ) ,'path' ) = 0 then
314
 
    begin
315
 
     if this.m_path_flag then
316
 
      raise svg_exception.Construct(PChar('start_element: Nested path' ) );
317
 
 
318
 
     this.m_path.begin_path;
319
 
     this.parse_path(attr );
320
 
     this.m_path.end_path;
321
 
 
322
 
     this.m_path_flag:=true;
323
 
 
324
 
    end
325
 
   else
326
 
    if StrComp(PChar(el ) ,'rect' ) = 0 then
327
 
     this.parse_rect(attr )
328
 
    else
329
 
     if StrComp(PChar(el ) ,'line' ) = 0 then
330
 
      this.parse_line(attr )
331
 
     else
332
 
      if StrComp(PChar(el ) ,'polyline' ) = 0 then
333
 
       this.parse_poly(attr ,false )
334
 
      else
335
 
       if StrComp(PChar(el ) ,'polygon' ) = 0 then
336
 
        this.parse_poly(attr ,true );
337
 
 
338
 
     //else
339
 
     // if StrComp(PChar(el ) ,'<OTHER_ELEMENTS>' ) = 0 then
340
 
     //  begin
341
 
     //  end
342
 
     //...
343
 
 
344
 
end;
345
 
 
346
 
{ END_ELEMENT }
347
 
procedure end_element;
348
 
var
349
 
 this : parser_ptr;
350
 
 
351
 
begin
352
 
 this:=parser_ptr(data );
353
 
 
354
 
 if StrComp(PChar(el ) ,'title' ) = 0 then
355
 
  this.m_title_flag:=false
356
 
 else
357
 
  if StrComp(PChar(el ) ,'g' ) = 0 then
358
 
   this.m_path.pop_attr
359
 
  else
360
 
   if StrComp(PChar(el ) ,'path' ) = 0 then
361
 
    this.m_path_flag:=false;
362
 
 
363
 
 //else
364
 
 // if StrComp(PChar(el ) ,'<OTHER_ELEMENTS>' ) = 0 then
365
 
 //  begin
366
 
 //  end
367
 
 // ...
368
 
 
369
 
end;
370
 
 
371
 
{ CONTENT }
372
 
procedure content;
373
 
var
374
 
 this : parser_ptr;
375
 
 
376
 
begin
377
 
 this:=parser_ptr(data );
378
 
 
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
382
 
  begin
383
 
   if len + this.m_title_len > 255 then
384
 
    len:=255 - this.m_title_len;
385
 
 
386
 
   if len > 0 then
387
 
    begin
388
 
     move(
389
 
      s^ ,
390
 
      char_ptr(ptrcomp(this.m_title ) + this.m_title_len )^ ,
391
 
      len );
392
 
 
393
 
     inc(this.m_title_len ,len );
394
 
 
395
 
     char_ptr(ptrcomp(this.m_title ) + this.m_title_len )^:=#0;
396
 
 
397
 
    end;
398
 
 
399
 
  end;
400
 
 
401
 
end;
402
 
 
403
 
{ hex_unsigned }
404
 
function hex_unsigned(hexstr : agg_basics.char_ptr ) : unsigned;
405
 
 
406
 
function xyint(x ,y : integer ) : integer;
407
 
var
408
 
 f : integer;
409
 
 m : boolean;
410
 
 
411
 
begin
412
 
 m:=false;
413
 
 
414
 
 if y < 0 then
415
 
  begin
416
 
   y:=y * -1;
417
 
   m:=true;
418
 
 
419
 
  end;
420
 
 
421
 
 result:=x;
422
 
 
423
 
 if y > 1 then
424
 
  for f:=1 to y - 1 do
425
 
   result:=result * x;
426
 
 
427
 
 if m then
428
 
  result:=result * -1;
429
 
 
430
 
end;
431
 
 
432
 
var
433
 
 h   : shortstring;
434
 
 fcb : byte;
435
 
 yps ,
436
 
 mul ,
437
 
 num : unsigned;
438
 
 
439
 
label
440
 
 Err ,Esc ;
441
 
 
442
 
const
443
 
 hex : string[16 ] = '0123456789ABCDEF';
444
 
 
445
 
begin
446
 
 h:='';
447
 
 
448
 
 while hexstr^ <> #0 do
449
 
  begin
450
 
   h:=h + pageEqHigh[byte(hexstr^ ) ];
451
 
 
452
 
   inc(ptrcomp(hexstr ) );
453
 
 
454
 
  end;
455
 
 
456
 
 if length(h ) > 0 then
457
 
  begin
458
 
   case h[length(h ) ] of
459
 
    '0'..'9' ,'A'..'F' :
460
 
    else
461
 
     goto Err;
462
 
 
463
 
   end;
464
 
 
465
 
   num:=pos(h[length(h ) ] ,hex ) - 1;
466
 
   yps:=2;
467
 
   mul:=xyint(4 ,yps );
468
 
 
469
 
   if length(h ) > 1 then
470
 
    for fcb:=length(h ) - 1 downto 1 do
471
 
     begin
472
 
      case h[fcb ] of
473
 
       '0'..'9' ,'A'..'F' :
474
 
       else
475
 
        goto Err;
476
 
 
477
 
      end;
478
 
 
479
 
      inc(num ,(pos(h[fcb ] ,hex ) - 1 ) * mul );
480
 
      inc(yps ,2 );
481
 
 
482
 
      mul:=xyint(4 ,yps );
483
 
 
484
 
     end;
485
 
 
486
 
   goto Esc;
487
 
 
488
 
  end;
489
 
 
490
 
Err:
491
 
 num:=0;
492
 
 
493
 
Esc:
494
 
 result:=num;
495
 
 
496
 
end;
497
 
 
498
 
{ parse_color }
499
 
function parse_color(str : agg_basics.char_ptr ) : aggclr;
500
 
var
501
 
 u : unsigned;
502
 
 p : named_color_ptr;
503
 
 m : shortstring;
504
 
 
505
 
begin
506
 
 while str^ = ' ' do
507
 
  inc(ptrcomp(str ) );
508
 
 
509
 
 if str^ = '#' then
510
 
  begin
511
 
   inc(ptrcomp(str ) );
512
 
 
513
 
   u:=hex_unsigned(str );
514
 
 
515
 
   result.Construct(rgb8_packed(u ) );
516
 
 
517
 
  end
518
 
 else
519
 
  begin
520
 
   p:=NIL;
521
 
 
522
 
   for u:=0 to colors_num - 1 do
523
 
    if StrComp(colors[u ].name ,PChar(str ) ) = 0 then
524
 
     begin
525
 
      p:=@colors[u ];
526
 
 
527
 
      break;
528
 
 
529
 
     end;
530
 
 
531
 
   if p = NIL then
532
 
    begin
533
 
     m:='parse_color: Invalid color name ' + StrPas(PChar(str ) ) + #0;
534
 
 
535
 
     raise svg_exception.Construct(PChar(@m[1 ] ) );
536
 
 
537
 
    end;
538
 
 
539
 
   result.ConstrInt(p.r ,p.g ,p.b ,p.a );
540
 
 
541
 
  end;
542
 
 
543
 
end;
544
 
 
545
 
{ parse_double }
546
 
function parse_double(str : agg_basics.char_ptr ) : double;
547
 
begin
548
 
 while str^ = ' ' do
549
 
  inc(ptrcomp(str ) );
550
 
 
551
 
 result:=get_double(pointer(PChar(str ) ) );
552
 
 
553
 
end;
554
 
 
555
 
{ islower }
556
 
function islower(ch : char ) : boolean;
557
 
begin
558
 
 case ch of
559
 
  #97..#122 :
560
 
   result:=true;
561
 
 
562
 
  else
563
 
   result:=false;
564
 
 
565
 
 end;
566
 
 
567
 
end;
568
 
 
569
 
{ is_numeric }
570
 
function is_numeric(ch : char ) : boolean;
571
 
begin
572
 
 result:=Pos(ch ,'0123456789+-.eE' ) <> 0;
573
 
 
574
 
end;
575
 
 
576
 
{ parse_transform_args }
577
 
function parse_transform_args(str : agg_basics.char_ptr; args : double_ptr; max_na : unsigned; na : unsigned_ptr ) : unsigned;
578
 
var
579
 
 ptr ,end_ : agg_basics.char_ptr;
580
 
 
581
 
begin
582
 
 na^:=0;
583
 
 ptr:=str;
584
 
 
585
 
 while (ptr^ <> #0 ) and
586
 
       (ptr^ <> '(' ) do
587
 
  inc(ptrcomp(ptr ) );
588
 
 
589
 
 if ptr^ = #0 then
590
 
  raise svg_exception.Construct(PChar('parse_transform_args: Invalid syntax' ) );
591
 
 
592
 
 end_:=ptr;
593
 
 
594
 
 while (end_^ <> #0 ) and
595
 
       (end_^ <> ')' ) do
596
 
  inc(ptrcomp(end_ ) );
597
 
 
598
 
 if end_^ = #0 then
599
 
  raise svg_exception.Construct(PChar('parse_transform_args: Invalid syntax' ) );
600
 
 
601
 
 while ptrcomp(ptr ) < ptrcomp(end_ ) do
602
 
  if is_numeric(ptr^ ) then
603
 
   begin
604
 
    if na^ >= max_na then
605
 
     raise svg_exception.Construct(PChar('parse_transform_args: Too many arguments' ) );
606
 
 
607
 
    double_ptr(ptrcomp(args ) + na^ * sizeof(double ) )^:=get_double(ptr );
608
 
 
609
 
    inc(na^ );
610
 
 
611
 
    while (ptrcomp(ptr ) < ptrcomp(end_ ) ) and
612
 
          is_numeric(ptr^ ) do
613
 
     inc(ptrcomp(ptr ) );
614
 
 
615
 
   end
616
 
  else
617
 
   inc(ptrcomp(ptr ) );
618
 
 
619
 
 result:=unsigned(ptrcomp(end_ ) - ptrcomp(str ) );
620
 
 
621
 
end;
622
 
 
623
 
{ CONSTRUCT }
624
 
constructor parser.Construct(path : path_renderer_ptr );
625
 
begin
626
 
 m_path:=path;
627
 
 
628
 
 m_tokenizer.Construct;
629
 
 
630
 
 agg_getmem(pointer(m_buf ) ,buf_size );
631
 
 agg_getmem(pointer(m_title ) ,256 );
632
 
 
633
 
 m_title_len :=0;
634
 
 m_title_flag:=false;
635
 
 m_path_flag :=false;
636
 
 
637
 
 m_attr_name_aloc :=128;
638
 
 m_attr_value_aloc:=1024;
639
 
 
640
 
 agg_getmem(pointer(m_attr_name ) ,m_attr_name_aloc );
641
 
 agg_getmem(pointer(m_attr_value ) ,m_attr_value_aloc );
642
 
 
643
 
 m_attr_name_len :=127;
644
 
 m_attr_value_len:=1023;
645
 
 
646
 
 m_title^:=#0;
647
 
 
648
 
end;
649
 
 
650
 
{ DESTRUCT }
651
 
destructor parser.Destruct;
652
 
begin
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 );
657
 
 
658
 
end;
659
 
 
660
 
procedure parser.parse(fname: string);
661
 
var
662
 
  fs: TFileStream;
663
 
begin
664
 
  fs:=TFileStream.Create(UTF8ToSys(fname),fmOpenRead+fmShareDenyWrite);
665
 
  try
666
 
    parse(fs);
667
 
  finally
668
 
    fs.Free;
669
 
  end;
670
 
end;
671
 
 
672
 
{ PARSE }
673
 
procedure parser.parse(sourcestream: TStream);
674
 
var
675
 
 p  : XML_Parser;
676
 
 ts : char_ptr;
677
 
 
678
 
 done : boolean;
679
 
 len  : int;
680
 
 
681
 
 Msg : ansistring;
682
 
begin
683
 
 p:=XML_ParserCreate(NIL );
684
 
 
685
 
 if p = NIL then
686
 
  raise svg_exception.Construct(PChar('Couldn''t allocate memory for parser' ) );
687
 
 try
688
 
   XML_SetUserData            (p ,@self );
689
 
   XML_SetElementHandler      (p ,@start_element ,@end_element );
690
 
   XML_SetCharacterDataHandler(p ,@content );
691
 
 
692
 
   done:=false;
693
 
 
694
 
   repeat
695
 
    len:=sourcestream.Read(m_buf^,buf_size);
696
 
 
697
 
    done:=len < buf_size;
698
 
    writeln('parser.parse ',done,' ',len,' ',buf_size);
699
 
 
700
 
    if XML_Parse(p ,pointer(m_buf ) ,len ,int(done ) ) = XML_STATUS_ERROR then
701
 
     begin
702
 
      XML_ParserFree(p );
703
 
      Msg:=PChar(XML_ErrorString(XML_GetErrorCode(p)));
704
 
      Msg:=' at line '+IntToStr(XML_GetCurrentLineNumber(p));
705
 
      raise svg_exception.Construct(PChar(Msg) );
706
 
 
707
 
     end;
708
 
 
709
 
   until done;
710
 
 
711
 
   ts:=m_title;
712
 
 
713
 
   while ts^ <> #0 do
714
 
    begin
715
 
     if byte(ts^ ) < byte(' ' ) then
716
 
      ts^:=' ';
717
 
 
718
 
     inc(ptrcomp(ts ) );
719
 
 
720
 
    end;
721
 
 
722
 
 finally
723
 
   XML_ParserFree(p );
724
 
 end;
725
 
end;
726
 
 
727
 
{ TITLE }
728
 
function parser.title;
729
 
begin
730
 
 result:=m_title;
731
 
 
732
 
end;
733
 
 
734
 
{ PARSE_ATTR }
735
 
procedure parser.parse_attr(attr : char_ptr_ptr );
736
 
var
737
 
 i : int;
738
 
 
739
 
begin
740
 
 i:=0;
741
 
 
742
 
 while char_ptr_ptr(ptrcomp(attr ) + i * sizeof(char_ptr ) )^ <> NIL do
743
 
  begin
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 ) )^ )
746
 
   else
747
 
    parse_attr(
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 ) )^ );
750
 
 
751
 
   inc(i ,2 );
752
 
 
753
 
  end;
754
 
 
755
 
end;
756
 
 
757
 
{ PARSE_PATH }
758
 
procedure parser.parse_path;
759
 
var
760
 
 i : int;
761
 
 
762
 
 tmp : array[0..3 ] of agg_basics.char_ptr;
763
 
 
764
 
begin
765
 
 i:=0;
766
 
 
767
 
 while char_ptr_ptr(ptrcomp(attr ) + i * sizeof(char_ptr ) )^ <> NIL do
768
 
  begin
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
774
 
    begin
775
 
     m_tokenizer.set_path_str(agg_basics.char_ptr_ptr(ptrcomp(attr ) + (i + 1 ) * sizeof(char_ptr ) )^ );
776
 
 
777
 
     m_path.parse_path(@m_tokenizer );
778
 
 
779
 
    end
780
 
   else
781
 
    begin
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 ) )^;
786
 
     tmp[2 ]:=NIL;
787
 
     tmp[3 ]:=NIL;
788
 
 
789
 
     parse_attr(@tmp );
790
 
 
791
 
    end;
792
 
 
793
 
   inc(i ,2 );
794
 
 
795
 
  end;
796
 
 
797
 
end;
798
 
 
799
 
{ PARSE_POLY }
800
 
procedure parser.parse_poly;
801
 
var
802
 
 i : int;
803
 
 
804
 
 x ,y : double;
805
 
 
806
 
begin
807
 
 x:=0.0;
808
 
 y:=0.0;
809
 
 
810
 
 m_path.begin_path;
811
 
 
812
 
 i:=0;
813
 
 
814
 
 while char_ptr_ptr(ptrcomp(attr ) + i * sizeof(char_ptr ) )^ <> NIL do
815
 
  begin
816
 
   if not parse_attr(
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
820
 
     begin
821
 
      m_tokenizer.set_path_str(agg_basics.char_ptr_ptr(ptrcomp(attr ) + (i + 1 ) * sizeof(char_ptr ) )^ );
822
 
 
823
 
      if not m_tokenizer.next then
824
 
       raise svg_exception.Construct(PChar('parse_poly: Too few coordinates' ) );
825
 
 
826
 
      x:=m_tokenizer.last_number;
827
 
 
828
 
      if not m_tokenizer.next then
829
 
       raise svg_exception.Construct(PChar('parse_poly: Too few coordinates' ) );
830
 
 
831
 
      y:=m_tokenizer.last_number;
832
 
 
833
 
      m_path.move_to(x ,y );
834
 
 
835
 
      while m_tokenizer.next do
836
 
       begin
837
 
        x:=m_tokenizer.last_number;
838
 
 
839
 
        if not m_tokenizer.next then
840
 
         raise svg_exception.Construct(PChar('parse_poly: Odd number of coordinates' ) );
841
 
 
842
 
        y:=m_tokenizer.last_number;
843
 
 
844
 
        m_path.line_to(x ,y );
845
 
 
846
 
       end;
847
 
 
848
 
     end;
849
 
 
850
 
   inc(i ,2 );
851
 
 
852
 
  end;
853
 
 
854
 
 m_path.end_path; 
855
 
 
856
 
end;
857
 
 
858
 
{ PARSE_RECT }
859
 
procedure parser.parse_rect;
860
 
var
861
 
 i : int;
862
 
 
863
 
 x ,y ,w ,h : double;
864
 
 
865
 
begin
866
 
 x:=0.0;
867
 
 y:=0.0;
868
 
 w:=0.0;
869
 
 h:=0.0;
870
 
 
871
 
 m_path.begin_path;
872
 
 
873
 
 i:=0;
874
 
 
875
 
 while char_ptr_ptr(ptrcomp(attr ) + i * sizeof(char_ptr ) )^ <> NIL do
876
 
  begin
877
 
   if not parse_attr(
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
880
 
    begin
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 ) )^ );
883
 
 
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 ) )^ );
886
 
 
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 ) )^ );
889
 
 
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 ) )^ );
892
 
 
893
 
     // rx - to be implemented
894
 
     // ry - to be implemented
895
 
 
896
 
    end;
897
 
 
898
 
   inc(i ,2 );
899
 
 
900
 
  end;
901
 
 
902
 
 if (w <> 0.0 ) and
903
 
    (h <> 0.0 ) then
904
 
  begin
905
 
   if w < 0.0 then
906
 
    raise svg_exception.Construct(PChar('parse_rect: Invalid width: ' ) );
907
 
 
908
 
   if h < 0.0 then
909
 
    raise svg_exception.Construct(PChar('parse_rect: Invalid height: ' ) );
910
 
 
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;
916
 
 
917
 
  end;
918
 
 
919
 
 m_path.end_path;
920
 
 
921
 
end;
922
 
 
923
 
{ PARSE_LINE }
924
 
procedure parser.parse_line;
925
 
var
926
 
 i : int;
927
 
 
928
 
 x1 ,y1 ,x2 ,y2 : double;
929
 
 
930
 
begin
931
 
 x1:=0.0;
932
 
 y1:=0.0;
933
 
 x2:=0.0;
934
 
 y2:=0.0;
935
 
 
936
 
 m_path.begin_path;
937
 
 
938
 
 i:=0;
939
 
 
940
 
 while char_ptr_ptr(ptrcomp(attr ) + i * sizeof(char_ptr ) )^ <> NIL do
941
 
  begin
942
 
   if not parse_attr(
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
945
 
    begin
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 ) )^ );
948
 
 
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 ) )^ );
951
 
 
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 ) )^ );
954
 
 
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 ) )^ );
957
 
 
958
 
    end;
959
 
 
960
 
   inc(i ,2 );
961
 
 
962
 
  end;
963
 
 
964
 
 m_path.move_to(x1 ,y1 );
965
 
 m_path.line_to(x2 ,y2 );
966
 
 m_path.end_path;
967
 
 
968
 
end;
969
 
 
970
 
{ PARSE_STYLE }
971
 
procedure parser.parse_style;
972
 
var
973
 
 nv_start ,nv_end : agg_basics.char_ptr;
974
 
 
975
 
begin
976
 
 while str^ <> #0 do
977
 
  begin
978
 
  // Left Trim
979
 
   while (str^ <> #0 ) and
980
 
         (str^ = ' ' ) do
981
 
    inc(ptrcomp(str ) );
982
 
 
983
 
   nv_start:=str;
984
 
 
985
 
   while (str^ <> #0 ) and
986
 
         (str^ <> ';' ) do
987
 
    inc(ptrcomp(str ) );
988
 
 
989
 
   nv_end:=str;
990
 
 
991
 
  // Right Trim
992
 
   while (ptrcomp(nv_end ) > ptrcomp(nv_start ) ) and
993
 
         ((nv_end^ = ';' ) or
994
 
          (nv_end^ = ' ' ) ) do
995
 
    dec(ptrcomp(nv_end ) );
996
 
 
997
 
   inc(ptrcomp(nv_end ) );
998
 
 
999
 
   parse_name_value(nv_start ,nv_end );
1000
 
 
1001
 
   if str^ <> #0 then
1002
 
    inc(ptrcomp(str ) );
1003
 
 
1004
 
  end;
1005
 
 
1006
 
end;
1007
 
 
1008
 
{ PARSE_TRANSFORM }
1009
 
procedure parser.parse_transform;
1010
 
begin
1011
 
 while str^ <> #0 do
1012
 
  begin
1013
 
   if islower(str^ ) then
1014
 
    if StrLComp(PChar(str ) ,'matrix' ,6 ) = 0 then
1015
 
     inc(ptrcomp(str ) ,parse_matrix(str ) )
1016
 
    else
1017
 
     if StrLComp(PChar(str ) ,'translate' ,9 ) = 0 then
1018
 
      inc(ptrcomp(str ) ,parse_translate(str ) )
1019
 
     else
1020
 
      if StrLComp(PChar(str ) ,'rotate' ,6 ) = 0 then
1021
 
       inc(ptrcomp(str ) ,parse_rotate(str ) )
1022
 
      else
1023
 
       if StrLComp(PChar(str ) ,'scale' ,5 ) = 0 then
1024
 
        inc(ptrcomp(str ) ,parse_scale(str ) )
1025
 
       else
1026
 
        if StrLComp(PChar(str ) ,'skewX' ,5 ) = 0 then
1027
 
         inc(ptrcomp(str ) ,parse_skew_x(str ) )
1028
 
        else
1029
 
         if StrLComp(PChar(str ) ,'skewY' ,5 ) = 0  then
1030
 
          inc(ptrcomp(str ) ,parse_skew_y(str ) )
1031
 
         else
1032
 
          inc(ptrcomp(str ) )
1033
 
 
1034
 
   else
1035
 
    inc(ptrcomp(str ) );
1036
 
 
1037
 
  end;
1038
 
 
1039
 
end;
1040
 
 
1041
 
{ PARSE_MATRIX }
1042
 
function parser.parse_matrix;
1043
 
var
1044
 
 args : array[0..5 ] of double;
1045
 
 
1046
 
 na ,len : unsigned;
1047
 
 
1048
 
 ta : trans_affine;
1049
 
 
1050
 
begin
1051
 
 na :=0;
1052
 
 len:=parse_transform_args(str ,@args ,6 ,@na );
1053
 
 
1054
 
 if na <> 6 then
1055
 
  raise svg_exception.Construct(PChar('parse_matrix: Invalid number of arguments' ) );
1056
 
 
1057
 
 ta.Construct(args[0 ] ,args[1 ] ,args[2 ] ,args[3 ] ,args[4 ] ,args[5 ] );
1058
 
 
1059
 
 m_path.transform.premultiply(@ta );
1060
 
 
1061
 
 result:=len;
1062
 
 
1063
 
end;
1064
 
 
1065
 
{ PARSE_TRANSLATE }
1066
 
function parser.parse_translate;
1067
 
var
1068
 
 args : array[0..1 ] of double;
1069
 
 
1070
 
 na ,len : unsigned;
1071
 
 
1072
 
 tat : trans_affine_translation;
1073
 
 
1074
 
begin
1075
 
 na :=0;
1076
 
 len:=parse_transform_args(str ,@args ,2 ,@na );
1077
 
 
1078
 
 if na = 1 then
1079
 
  args[1 ]:=0.0;
1080
 
 
1081
 
 tat.Construct(args[0 ] ,args[1 ] );
1082
 
 
1083
 
 m_path.transform.premultiply(@tat );
1084
 
 
1085
 
 result:=len;
1086
 
 
1087
 
end;
1088
 
 
1089
 
{ PARSE_ROTATE }
1090
 
function parser.parse_rotate;
1091
 
var
1092
 
 args : array[0..2 ] of double;
1093
 
 
1094
 
 na ,len : unsigned;
1095
 
 
1096
 
 tar : trans_affine_rotation;
1097
 
 
1098
 
 tat ,t : trans_affine_translation;
1099
 
 
1100
 
begin
1101
 
 na :=0;
1102
 
 len:=parse_transform_args(str ,@args ,3 ,@na );
1103
 
 
1104
 
 if na = 1 then
1105
 
  begin
1106
 
   tar.Construct(deg2rad(args[0 ] ) );
1107
 
 
1108
 
   m_path.transform.premultiply(@tar  );
1109
 
 
1110
 
  end
1111
 
 else
1112
 
  if na = 3 then
1113
 
   begin
1114
 
    t.Construct(-args[1 ] ,-args[2 ] );
1115
 
 
1116
 
    tar.Construct(deg2rad(args[0 ] ) );
1117
 
    tat.Construct(args[1 ] ,args[2 ] );
1118
 
 
1119
 
    t.multiply(@tar );
1120
 
    t.multiply(@tat );
1121
 
 
1122
 
    m_path.transform.premultiply(@t );
1123
 
 
1124
 
   end
1125
 
  else
1126
 
   raise svg_exception.Construct(PChar('parse_rotate: Invalid number of arguments' ) );
1127
 
 
1128
 
 result:=len;
1129
 
 
1130
 
end;
1131
 
 
1132
 
{ PARSE_SCALE }
1133
 
function parser.parse_scale;
1134
 
var
1135
 
 args : array[0..1 ] of double;
1136
 
 
1137
 
 na ,len : unsigned;
1138
 
 
1139
 
 tas : trans_affine_scaling;
1140
 
 
1141
 
begin
1142
 
 na :=0;
1143
 
 len:=parse_transform_args(str ,@args ,2 ,@na );
1144
 
 
1145
 
 if na = 1 then
1146
 
  args[1 ]:=args[0 ];
1147
 
 
1148
 
 tas.Construct(args[0 ] ,args[1 ] );
1149
 
 
1150
 
 m_path.transform.premultiply(@tas );
1151
 
 
1152
 
 result:=len;
1153
 
 
1154
 
end;
1155
 
 
1156
 
{ PARSE_SKEW_X }
1157
 
function parser.parse_skew_x;
1158
 
var
1159
 
 arg : double;
1160
 
 
1161
 
 na ,len : unsigned;
1162
 
 
1163
 
 tas : trans_affine_skewing;
1164
 
 
1165
 
begin
1166
 
 na :=0;
1167
 
 len:=parse_transform_args(str ,@arg ,1 ,@na );
1168
 
 
1169
 
 tas.Construct(deg2rad(arg ) ,0.0 );
1170
 
 
1171
 
 m_path.transform.premultiply(@tas );
1172
 
 
1173
 
 result:=len;
1174
 
 
1175
 
end;
1176
 
 
1177
 
{ PARSE_SKEW_Y }
1178
 
function parser.parse_skew_y;
1179
 
var
1180
 
 arg : double;
1181
 
 
1182
 
 na ,len : unsigned;
1183
 
 
1184
 
 tas : trans_affine_skewing;
1185
 
 
1186
 
begin
1187
 
 na :=0;
1188
 
 len:=parse_transform_args(str ,@arg ,1 ,@na );
1189
 
 
1190
 
 tas.Construct(0.0 ,deg2rad(arg ) );
1191
 
 
1192
 
 m_path.transform.premultiply(@tas );
1193
 
 
1194
 
 result:=len;
1195
 
 
1196
 
end;
1197
 
 
1198
 
{ PARSE_ATTR }
1199
 
function parser.parse_attr(name ,value : agg_basics.char_ptr ) : boolean;
1200
 
var
1201
 
 clr : aggclr;
1202
 
 
1203
 
begin
1204
 
 result:=true;
1205
 
 
1206
 
 if StrComp(PChar(name ) ,'style' ) = 0 then
1207
 
  parse_style(value )
1208
 
 else
1209
 
  if StrComp(PChar(name ) ,'fill' ) = 0 then
1210
 
   if StrComp(PChar(value ) ,'none' ) = 0 then
1211
 
    m_path.fill_none
1212
 
   else
1213
 
    begin
1214
 
     clr:=parse_color(value );
1215
 
 
1216
 
     m_path.fill(@clr );
1217
 
 
1218
 
    end
1219
 
  else
1220
 
   if StrComp(PChar(name ) ,'fill-opacity' ) = 0 then
1221
 
    m_path.fill_opacity(parse_double(value ) )
1222
 
   else
1223
 
    if StrComp(PChar(name ) ,'stroke' ) = 0 then
1224
 
     if StrComp(PChar(value ) ,'none' ) = 0 then
1225
 
      m_path.stroke_none
1226
 
     else
1227
 
      begin
1228
 
       clr:=parse_color(value );
1229
 
 
1230
 
       m_path.stroke(@clr );
1231
 
 
1232
 
      end
1233
 
    else
1234
 
     if StrComp(PChar(name ) ,'stroke-width' ) = 0 then
1235
 
      m_path.stroke_width(parse_double(value ) )
1236
 
     else
1237
 
      if StrComp(PChar(name ) ,'stroke-linecap' ) = 0 then
1238
 
       begin
1239
 
        if StrComp(PChar(value ) ,'butt' ) = 0 then
1240
 
         m_path.line_cap(butt_cap )
1241
 
        else
1242
 
         if StrComp(PChar(value ) ,'round' ) = 0 then
1243
 
          m_path.line_cap(round_cap )
1244
 
         else
1245
 
          if StrComp(PChar(value ) ,'square' ) = 0 then
1246
 
           m_path.line_cap(square_cap );
1247
 
 
1248
 
       end
1249
 
      else
1250
 
       if StrComp(PChar(name ) ,'stroke-linejoin' ) = 0 then
1251
 
        begin
1252
 
         if StrComp(PChar(value ) ,'miter' ) = 0 then
1253
 
          m_path.line_join(miter_join )
1254
 
         else
1255
 
          if StrComp(PChar(value ) ,'round' ) = 0 then
1256
 
           m_path.line_join(round_join )
1257
 
          else
1258
 
           if StrComp(PChar(value ) ,'bevel' ) = 0 then
1259
 
            m_path.line_join(bevel_join );
1260
 
 
1261
 
        end
1262
 
       else
1263
 
        if StrComp(PChar(name ) ,'stroke-miterlimit' ) = 0 then
1264
 
         m_path.miter_limit(parse_double(value ) )
1265
 
        else
1266
 
         if StrComp(PChar(name ) ,'stroke-opacity' ) = 0 then
1267
 
          m_path.stroke_opacity(parse_double(value ) )
1268
 
         else
1269
 
          if StrComp(PChar(name ) ,'transform' ) = 0 then
1270
 
           parse_transform(value )
1271
 
 
1272
 
        //else
1273
 
        // if StrComp(PChar(el ) ,'<OTHER_ATTRIBUTES>' ) = 0 then
1274
 
        //  begin
1275
 
        //  end
1276
 
        // ...
1277
 
 
1278
 
          else
1279
 
           result:=false;
1280
 
 
1281
 
end;
1282
 
 
1283
 
{ PARSE_NAME_VALUE }
1284
 
function parser.parse_name_value;
1285
 
var
1286
 
 str ,val : agg_basics.char_ptr;
1287
 
 
1288
 
begin
1289
 
 str:=nv_start;
1290
 
 
1291
 
 while (ptrcomp(str ) < ptrcomp(nv_end ) ) and
1292
 
       (str^ <> ':' ) do
1293
 
  inc(ptrcomp(str ) );
1294
 
 
1295
 
 val:=str;
1296
 
 
1297
 
// Right Trim
1298
 
 while (ptrcomp(str ) > ptrcomp(nv_start ) ) and
1299
 
       ((str^ = ':' ) or
1300
 
        (str^ = ' ' ) ) do
1301
 
  dec(ptrcomp(str ) );
1302
 
 
1303
 
 inc(ptrcomp(str ) );
1304
 
 
1305
 
 copy_name(nv_start ,str );
1306
 
 
1307
 
 while (ptrcomp(val ) < ptrcomp(nv_end ) ) and
1308
 
       ((val^ = ':' ) or
1309
 
        (val^ = ' ' ) ) do
1310
 
  inc(ptrcomp(val ) );
1311
 
 
1312
 
 copy_value(val ,nv_end );
1313
 
 
1314
 
 result:=parse_attr(agg_basics.char_ptr(m_attr_name ) ,agg_basics.char_ptr(m_attr_value ) );
1315
 
 
1316
 
end;
1317
 
 
1318
 
{ COPY_NAME }
1319
 
procedure parser.copy_name;
1320
 
var
1321
 
 len : unsigned;
1322
 
 
1323
 
begin
1324
 
 len:=ptrcomp(end_ ) - ptrcomp(start );
1325
 
 
1326
 
 if (m_attr_name_len = 0 ) or
1327
 
    (len > m_attr_name_len ) then
1328
 
  begin
1329
 
   agg_freemem(pointer(m_attr_name ) ,m_attr_name_aloc );
1330
 
 
1331
 
   m_attr_name_aloc:=len + 1;
1332
 
 
1333
 
   agg_freemem(pointer(m_attr_name ) ,m_attr_name_aloc );
1334
 
 
1335
 
   m_attr_name_len:=len;
1336
 
 
1337
 
  end;
1338
 
 
1339
 
 if len <> 0 then
1340
 
  move(start^ ,m_attr_name^ ,len );
1341
 
 
1342
 
 char_ptr(ptrcomp(m_attr_name ) + len )^:=#0;
1343
 
 
1344
 
end;
1345
 
 
1346
 
{ COPY_VALUE }
1347
 
procedure parser.copy_value;
1348
 
var
1349
 
 len : unsigned;
1350
 
 
1351
 
begin
1352
 
 len:=ptrcomp(end_ ) - ptrcomp(start );
1353
 
 
1354
 
 if (m_attr_value_len = 0 ) or
1355
 
    (len > m_attr_value_len ) then
1356
 
  begin
1357
 
   agg_freemem(pointer(m_attr_value ) ,m_attr_value_aloc );
1358
 
 
1359
 
   m_attr_value_aloc:=len + 1;
1360
 
 
1361
 
   agg_getmem(pointer(m_attr_value ) ,m_attr_value_aloc );
1362
 
 
1363
 
   m_attr_value_len:=len;
1364
 
 
1365
 
  end;
1366
 
 
1367
 
 if len <> 0 then
1368
 
  move(start^ ,m_attr_value^ ,len );
1369
 
 
1370
 
 char_ptr(ptrcomp(m_attr_value ) + len )^:=#0;
1371
 
 
1372
 
end;
1373
 
 
1374
 
END.
1375