Sign in Join
Wiki copytemporary

fpvectorial: what changed

Revision 1 to 2. Removed lines have a minus sign; added lines have a plus sign.

OldNewLine
11## Introduction
22
33FPVectorial offers support to read, modify and write vectorial images.
44
55Its counterpart library is [[fcl-image]], which works with raster images. FPVectorial comes with a unit which allows to draw a vectorial image to a TFPCustomCanvas, but no routines are provided to convert raster images to vectorial images.
66
77## Download
88
99fpvectorial is distributed along with Lazarus. You can find it in folder *components/fpvectorial* of your Lazarus installation.
1010
1111If you have a release version of Lazarus and want the latest version of fpvectorial you can download it by svn from
1212
13-`svn co `[`http://svn.freepascal.org/svn/lazarus/trunk/components/fpvectorial`](http://svn.freepascal.org/svn/lazarus/trunk/components/fpvectorial)` fpvectorial`
13+```text
14+svn co http://svn.freepascal.org/svn/lazarus/trunk/components/fpvectorial fpvectorial
15+```
1416
1517Downloading the fpvviewer project:
1618
17-`svn co `[`https://lazarus-ccr.svn.sourceforge.net/svnroot/lazarus-ccr/applications/fpvviewer`](https://lazarus-ccr.svn.sourceforge.net/svnroot/lazarus-ccr/applications/fpvviewer)` fpvviewer`
19+```text
20+svn co https://lazarus-ccr.svn.sourceforge.net/svnroot/lazarus-ccr/applications/fpvviewer fpvviewer
21+```
1822
1923## Current file list
2024
2125FPVectorial is located in the Lazarus directory *components/fpvectorial*.
2226
2327The central unit is *[[doc:fcl/fpvectorial|fpvectorial]]*.
2428
2529**Readers for various image formats**
2630
2731- **pdfvectorialreader** - Read support for PDF files, supports compression, only reads the first page
2832- **avisocncgcodereader** - Read support for the G-Code from the Aviso CNC machine
2933- **cdrvectorialreader** - Initial work of a reader support for Corel Draw CDR files
3034- **dxfvectorialreader** - Read support for DXF, the Drawing eXchange Format utilized by the AutoCAD
3135- **svgvectorialreader** - Read support for SVG
3236- **epsvectorialreader** - Read support for Encapsulated PostScript
3337- **wmfvectorialreader** - Read support for WMF (Windows metafile, cross-platform!)
3438
3539**Writers for various image formats**
3640
3741- **avisocncgcodewriter** - Write support for the G-Code from the Aviso CNC machine
3842- **svgvectorialwriter** - Write support for SVG. The most advanced writer at the moment. Supports lines, curves and text. Supports pen color and width.
3943
4044**Other units**
4145
4246- **fpvtocanvas** - Converts a vectorial document to a TFPCustomCanvas descendent (like TCanvas). Essentially converts the vectorial image to a raster image
4347- **fpvutils** - Utility functions which don't belong to fpvectorial.pas or that would bring unwanted dependencies to it. Color conversion functions.
4448- **pdfvrlexico**, **pdfvrsemantico**, **pdfvrsintatico**, **avisozlib** - Other units from the PDF reader, don't use directly
4549
4650## Formats
4751
4852### PDF
4953
5054The PDF format is developed by Adobe (tm) and it is fully documented. Inside, PDF is simply text, so it is rather easy to parse, but parts of this text are usually can be compressed.
5155
5256Link to the PDF Reference: <http://www.adobe.com/devnet/pdf/pdf_reference.html>
5357
5458### CorelDraw
5559
5660Corel does not release public documentation for its CorelDraw file format. Any information about this format depends on reverse engineering and guessing. The format is binary and consists of a tree of chunks.
5761
5862See also [[fpvectorial|fpvectorial#fpcorelexplorer]]
5963
6064### SVG
6165
6266Scalable Vectorial Graphics (SVG) is a standard from W3C for vectorial graphics. It is the native format of Inkscape and stores its data as a single, uncompressed XML file with the extension ".svg".
6367
6468Link to the specification: <http://www.w3.org/TR/SVG/>
6569
6670A very serious shortcoming in SVG is that it does not allow real world units to be specified in the drawing routines, only pixel values accepted, which makes it impossible to have a document with real world units. This can be worked around by simply hardcoding to a fixed DPI resolution, which is 90 DPI for Inkscape. Read more here:
6771
6872- <http://stackoverflow.com/questions/1346922/svg-and-dpi-absolute-units-and-user-units-inkscape-vs-firefox-vs-imagemagick>
6973- <http://www.inkscapeforum.com/viewtopic.php?f=16&t=5904>
7074- <http://www.inkscapeforum.com/viewtopic.php?f=16&t=3700&p=17179&hilit=units+path#p17179>
7175
7276Following Inkscape and the Opera Browser, FPVectorial also hardcodes to 90 DPI.
7377
7478As of February 2014 support for SVG is partial.
7579
7680### DXF
7781
7882The Drawing eXchange Format from Autodesk AutoCAD. This format is documented, but the quality of the documentation is rather low, lacking adequate explanations.
7983
8084The format itself is rather simple, composed by text. Each unit is composed of two lines, the first one being a number describing the type of data and then another line with the value itself, which might be text or a number.
8185
8286The most common problem in other DXF reading libraries is that they don't support the actual DXF writen by newer versions of AutoCAD. This is not the case with fpvectorial, which was tested with AutoCAD 2000 and also the previous simpler formats.
8387
8488Link to the documentation:
8589
8690- <http://www.autodesk.com/techpubs/autocad/acad2000/dxf/>
8791
8892The software fpvviewer can be utilized to show the internal structure of a DXF file. This software can be found in the lazarus-ccr svn in applications/fpvviewer. More info here: [[fpvectorial|fpvectorial#fpvviewer]]
8993
9094### WMF
9195
9296The Windows Metafile (WMF) format was originally designed for Microsoft Windows in the 1990s. The files can contain both vector graphics and bitmap components and consist of a list of drawing commands with parameters which are originally passed directly to the Windows Graphics Device Interface (GDI); in fpvectorial, however, they are converted to graphics objects which makes the format platform-independent.
9397
9498The file structure is documented at <http://msdn.microsoft.com/en-us/library/cc250370.aspx>
9599
96100### PostScript
97101
98102PostScript is a graphics drawing programming language and fpvectorial has an interpreter which can execute PostScript and convert its commands into its internal format. This is done by reader modules, for example epsvectorialreader. The interpreter is separated into a Tokenizer and an Executer. The tokens are classified into 3 types: Procedures, ExpressionTokens and Comments. Procedures are inside a {..} block in PostScript and in FPVectorial they are not tokenezed in the first pass, but instead on the first usage. The entire document is tokenized in one run, before executing the tokens, except for the procedures. The PostScript interpreter contains a Stack and a lookup Dictionary, as specified in PostScript.
99103
100104PostScript can be embedded into various formats, and the interpreter currently supports the EPS format.
101105
102106**References**:
103107
104108- <http://en.wikipedia.org/wiki/Encapsulated_PostScript>
105109- <http://partners.adobe.com/public/developer/en/ps/PLRM.pdf>
106110
107111### LAS
108112
109113LAS is geospatial data encoded in the ASPRS LASer (LAS) file format, which exists in versions 1.0, 1.1, 1.2, 1.3 and 1.4. Version 2.0 does not yet exist as of December 2011.
110114
111115**References**:
112116
113117- <http://en.wikipedia.org/wiki/LibLAS>
114118- <http://www.asprs.org/a/society/committees/lidar/lidar_format.html>
115119- <http://trac.liblas.org/wiki/Software>
116120- <http://www.cs.unc.edu/~isenburg/lastools/>
117121- <http://www.fugroviewer.com/>
118122- Example las file: www.appliedimagery.com/downloads/sampledata/Serpent%20Mound%20Model%20LAS%20Data.las
119123- Specification docs up to 1.3: <http://www.asprs.org/a/society/committees/standards/lidar_exchange_format.html>
120124- Specification for 1.4: <http://www.asprs.org/Press-Releases/LAS-1-4-Draft-Specification-Released-by-ASPRS.html>
121125
122126## Types of data in FPVectorial
123127
124128FPVectorial holds lists of three types of objects: paths, text and entities.
125129
126130Essentially paths are sequences of points, through which run lines and bezier curves. A path can be a line, a bezier, a polyline, a polybezier or any combination of these elements. The main characteristic of paths is that they can be utilized to guide a milling machine, also known as CNC machine, into physically executing the drawing. Before being able to execute a drawing which contains either text or entities in a CNC machine, these items need to be converted to paths.
127131
128132Text, just like the name says are strings drawn with fonts.
129133
130134Entities are things like circles, arcs, ellipses, rotated ellipses, etc.
131135
132136## Usage examples
133137
134138### Format conversion
135139
136140This example loads a PDF, converts it to G-Code and writes the G-Code to a TStrings descendent
137141
138142``` pascal
139143uses
140144 fpvectorial, pdfvectorialreader, avisocncgcodewriter;
141145
142146var
143147 Vec: TvVectorialDocument;
144148begin
145149 if dialogoAbrir.Execute() then
146150 begin
147151 Vec := TvVectorialDocument.Create;
148152 try
149153 Vec.ReadFromFile(dialogoAbrir.FileName, vfPDF);
150154 Vec.WriteToStrings(synCodigo.Lines, vfGCodeAvisoCNCPrototipoV5);
151155 finally
152156 Vec.Free;
153157 end;
154158 end;
155159end;
156160```
157161
158162### Adding paths, bezier lines and text
159163
160164This example shows how to add various elements.
161165
162166``` pascal
163167{
164168Author: Felipe Monteiro de Carvalho
165169
166170License: Public Domain
167171}
168172program fpvwritetest;
169173
170174{$mode objfpc}{$H+}
171175
172176uses
173177 fpvectorial, svgvectorialwriter;
174178
175179const
176180 cFormat = vfSVG;
177181 cExtension = '.svg';
178182var
179183 VecDoc: TvVectorialDocument;
180184 Vec: TvVectorialPage;
181185 s : String;
182186begin
183187 VecDoc := TvVectorialDocument.Create;
184188 try
185189 // All documents are 10cm x 10cm
186190 VecDoc.Width := 100;
187191 VecDoc.Height := 100;
188192
189193 Vec := VecDoc.AddPage();
190194 Vec.Width := VecDoc.Width;
191195 Vec.Height := VecDoc.Height;
192196
193197 // ...
194198
195199 // multi_test_1 Combines various elements
196200 Vec.Clear;
197201 Vec.StartPath(0, 20);
198202 Vec.AddLineToPath(30, 30);
199203 Vec.EndPath();
200204 Vec.StartPath(0, 0);
201205 Vec.AddLineToPath(100, 0);
202206 Vec.AddLineToPath(100, 100);
203207 Vec.AddLineToPath(0, 100);
204208 Vec.AddLineToPath(0, 0);
205209 Vec.EndPath();
206210 Vec.StartPath(0, 0);
207211 Vec.AddLineToPath(10, 10);
208212 Vec.AddBezierToPath(10, 20, 20, 20, 20, 10);
209213 Vec.AddLineToPath(30, 0);
210214 Vec.EndPath();
211215 Vec.AddText(10, 10, 0, '10,10 Some text in english.');
212216 s := '20, 20 Mówić, cześć, Włosku, Parabéns.';
213217 Vec.AddText(20, 20, 0, s);
214218 s := '30, 30 森林,是一个高密';
215219 Vec.AddText(30, 30, 0, s);
216220 VecDoc.WriteToFile('multi_test_1' + cExtension, cFormat);
217221 finally
218222 VecDoc.Free;
219223 end;
220224end.
221225```
222226
223227And here is the output of this example when rendered by the Opera Browser:
224228
225229![](/wiki-images/9/92/Fpvectorial_svg_output.PNG)
226230
227231### Adding Aligned Coordinates
228232
229233One can either add horizontal coordinates:
230234
231235``` pascal
232236Vec.AddAlignedDimension(Make2DPoint(100, 50), Make2DPoint(200, 100), Make2DPoint(100, 150), Make2DPoint(200, 150));
233237```
234238
235239![](/wiki-images/0/05/Aligned_dimension_horizontal.png)
236240
237241Or add vertical coordinates:
238242
239243``` pascal
240244Vec.AddAlignedDimension(Make2DPoint(50, 250), Make2DPoint(100, 200), Make2DPoint(150, 250), Make2DPoint(150, 200));
241245```
242246
243247![](/wiki-images/6/68/Aligned_dimension_vertical.png)
244248
245249### Rendering the image into a TCanvas
246250
247251To render a vectorial image into a TCanvas or TFPCustomCanvas use the unit fpvtocanvas and its routines:
248252
249253``` pascal
250254unit fpvtocanvas;
251255//..
252256{@@
253257 This function draws a FPVectorial vectorial image to a TFPCustomCanvas
254258 descendent, such as TCanvas from the LCL.
255259
256260 Be careful that by default this routine does not execute coordinate transformations,
257261 and that FPVectorial works with a start point in the bottom-left corner, with
258262 the X growing to the right and the Y growing to the top. This will result in
259263 an image in TFPCustomCanvas mirrored in the Y axis in relation with the document
260264 as seen in a PDF viewer, for example. This can be easily changed with the
261265 provided parameters. To have the standard view of an image viewer one could
262266 use this function like this:
263267
264268 DrawFPVectorialToCanvas(ASource, ADest, 0, ASource.Height, 1.0, -1.0);
265269}
266270procedure DrawFPVectorialToCanvas(ASource: TvVectorialPage;
267271 ADest: TFPCustomCanvas;
268272 ADestX: Integer = 0; ADestY: Integer = 0; AMulX: Double = 1.0; AMulY: Double = 1.0);
269273```
270274
271275And below an example taken from lazarus-ccr/application/fpvviewer
272276
273277``` pascal
274278uses fpvtocanvas;
275279
276280procedure TfrmFPVViewer.btnVisualizeClick(Sender: TObject);
277281const
278282 FPVVIEWER_MAX_IMAGE_SIZE = 1000;
279283 FPVVIEWER_MIN_IMAGE_SIZE = 100;
280284 FPVVIEWER_SPACE_FOR_NEGATIVE_COORDS = 100;
281285var
282286 Vec: TvVectorialDocument;
283287 CanvasSize: TPoint;
284288begin
285289 // First check the in input
286290 //if not CheckInput() then Exit;
287291
288292 notebook.PageIndex := 0;
289293
290294 Drawer.Clear;
291295
292296 Vec := TvVectorialDocument.Create;
293297 try
294298 Vec.ReadFromFile(editFileName.FileName);
295299
296300 // We need to be robust, because sometimes the document size won't be given
297301 // also give up drawing everything if we need more then 4MB of RAM for the image
298302 // and also give some space in the image to allow for negative coordinates
299303 if Vec.Width * spinScale.Value > FPVVIEWER_MAX_IMAGE_SIZE then CanvasSize.X := FPVVIEWER_MAX_IMAGE_SIZE
300304 else if Vec.Width < FPVVIEWER_MIN_IMAGE_SIZE then CanvasSize.X := Drawer.Width
301305 else CanvasSize.X := Round(Vec.Width * spinScale.Value);
302306 if CanvasSize.X < Drawer.Width then CanvasSize.X := Drawer.Width;
303307
304308 if Vec.Height * spinScale.Value > FPVVIEWER_MAX_IMAGE_SIZE then CanvasSize.Y := FPVVIEWER_MAX_IMAGE_SIZE
305309 else if Vec.Height < FPVVIEWER_MIN_IMAGE_SIZE then CanvasSize.Y := Drawer.Height
306310 else CanvasSize.Y := Round(Vec.Height * spinScale.Value);
307311 if CanvasSize.Y < Drawer.Height then CanvasSize.Y := Drawer.Height;
308312
309313 Drawer.Drawing.Width := CanvasSize.X;
310314 Drawer.Drawing.Height := CanvasSize.Y;
311315 Drawer.Drawing.Canvas.Brush.Color := clWhite;
312316 Drawer.Drawing.Canvas.Brush.Style := bsSolid;
313317 Drawer.Drawing.Canvas.FillRect(0, 0, Drawer.Drawing.Width, Drawer.Drawing.Height);
314318 DrawFPVectorialToCanvas(
315319 Vec.GetPage(0),
316320 Drawer.Drawing.Canvas,
317321 FPVVIEWER_SPACE_FOR_NEGATIVE_COORDS,
318322 Drawer.Drawing.Height - FPVVIEWER_SPACE_FOR_NEGATIVE_COORDS,
319323 spinScale.Value,
320324 -1 * spinScale.Value);
321325 Drawer.Invalidate;
322326 finally
323327 Vec.Free;
324328 end;
325329end;
326330```
327331
328332### Coordinates in FPVectorial
329333
330334It is important to note that FPVectorial works with two different systems of coordinates: Top-Left Coordinates and Bottom-Left Coordinates. TCanvas uses the coordinates from the Windows API, with the origin in the top-left corner and with the X axis growing to the right and the Y axis growing to the bottom. FPVectorial, besides supporting this system, also supports another one for drawing formats where this system is native such as CAD software, Inkscape, the Mac OS X APIs (Carbon and Cocoa), etc. In FPVectorial the origin is in bottom-left for all vectorial graphics formats except SVG. The X axis grows to the right and the Y axis to the top. The origin is in the top-left for SVG and all text document formats such as DOCX.
331335
332336![](/wiki-images/a/a1/Fpvectorial_coords.png)
333337
334338When the coordinates do not match TCanvas, one should be careful when converting coordinates between TCanvas and FPVectorial. To convert coordinates between TCanvas and FPVectorial, one needs the height of the Canvas. The following routine from the unit **fpvutils** can be used to execute this conversion:
335339
336340``` pascal
337341{@@ Converts the coordinate system from a TCanvas to FPVectorial
338342 The basic difference is that the Y axis is positioned differently and
339343 points upwards in FPVectorial and downwards in TCanvas.
340344 The X axis doesn't change. The fix is trivial and requires only the Height of
341345 the Canvas as extra info.
342346}
343347function CanvasCoordsToFPVectorial(AY: Integer; AHeight: Integer):
344348Integer; inline;
345349begin
346350 Result := AHeight - AY;
347351end;
348352```
349353
350354And there is also a difference regarding the text positioning. In TCanvas.TextOut the text is positioned based on the top-left coordinates of the text area. In fpvectorial it is based on the bottom-left. Again, there is a convenient routine in the unit **fpvutils** to convert between the coordinate systems:
351355
352356``` pascal
353357{@@
354358 LCL Text is positioned based on the top-left corner of the text.
355359 Besides that, one also needs to take the general coordinate change into account too.
356360
357361 @param ACanvasHeight Should receive TCanvas.Height
358362 @param ATextHeight Should receive TFont.Size
359363}
360364function CanvasTextPosToFPVectorial(AY: Integer; ACanvasHeight, ATextHeight: Integer): Integer;
361365begin
362366 Result := CanvasCoordsToFPVectorial(AY, ACanvasHeight) - ATextHeight;
363367end;
364368```
365369
366370### More examples
367371
368372Since fpvectorial is part of the Lazarus distribution, you can find the examples in the folder *components/fpvectorial/examples* of your Lazarus directory.
369373
370374## fpvviewer
371375
372376The Free Pascal Vectorial Viewer is a sample application which implements a simple CAD viewer using fpvectorial.
373377
374378Besides being able to visualize vectorial drawings, this software can also help in exploring the internal structure of DXF file:
375379
376380![](/wiki-images/3/3d/Fpvviewer_EPS.png)![](/wiki-images/7/74/Fpvviewer.png)
377381
378382Its source code can be found in the Lazarus-CCR in the directory application/fpvviewer
379383
380384Link to download the zipped source snapshot of this application: <https://sourceforge.net/p/lazarus-ccr/svn/HEAD/tree/applications/fpvviewer/>
381385
382386Link to download the entire Lazarus-CCR repository from subversion:
383387
384-`svn co `[`https://lazarus-ccr.svn.sourceforge.net/svnroot/lazarus-ccr`](https://lazarus-ccr.svn.sourceforge.net/svnroot/lazarus-ccr)` lazarus-ccr`
388+```text
389+svn co https://lazarus-ccr.svn.sourceforge.net/svnroot/lazarus-ccr lazarus-ccr
390+```
385391
386392### Contour line generation
387393
388394fpvviewer can generate contour lines from .raw files. These files can be generated with fpv3dviewer
389395
390396![](/wiki-images/c/cf/Contourlines_las.PNG)
391397
392398![](/wiki-images/5/57/Contourlines_regular.PNG)
393399
394400### FPVectorial Debug Tokens
395401
396402FPVViewer can be utilized to see the internal debug tokens from fpvectorial, see:
397403
398404![](/wiki-images/a/ae/Fpvectorial_debug_tokens.png)
399405
400406## fpcorelexplorer
401407
402408An application was developed for helping studying the CDR file format. At the moment this application can identify the version of CorelDraw files. It is located in fpctrunk/packages/fpvectorial/examples/fpcorelexplorer.lpi
403409
404410![](/wiki-images/c/cd/Fpcorelexplorer.png)
405411
406412## fpv3dviewer
407413
408414One of the examples of fpvectorial located in lazarus/components/fpvectorial/examples/fpv3dviewer.lpi is a 3D viewer.
409415
410416![](/wiki-images/1/1f/FPV3DViewer.png)
411417
412418## Articles about fpvectorial
413419
414420- Revista Clube Delphi Edition \#131: <http://www.devmedia.com.br/assgold/listmag.asp?site=3>
415421
416422Go to back [[Package List|Packages List]]
417423
418424---
419425*From the Free Pascal wiki, page "fpvectorial", as it stood on 2024-05-09 after a change by EkkehardDomning, out of the wiki's dump of 2024-05-26. Copyright stays with the author who wrote it, according to the old wiki's [[Licensing]] page. If you have concerns about this material, [message the admin](/wiki-contact).*
420426Category: Data import and export
421427Category: FPVectorial
422428Category: Graphics
423429Category: Lazarus-CCR
424430Category: Packages

Back to history