Sign in Join

Live chat for Free Pascal, Lazarus, Delphi and every Pascal programmer.

Mailing lists / lazarus / 2011-04

Metafile support

16 messages · 4 people · –

Reply by email Subscribe to this list Your subscription

Read-only archive. Use j and k to move between messages.

Alexander Klenin

A TAChart user requested export to WMF/EMF:
http://forum.lazarus.freepascal.org/index.php/topic,12693.0.html

It turns out that Lazarus CCR has Metafile package, but it is incomplete and apparently abandoned.

My options are:
1) Import the source into TAChart (it is only 350 lines of code), and fix/complete it there.
2) Somehow fix/complete the package in CCR,
and then create a TAChartMetafile package depending on Metafile.
3) Import the source into LCL (since Delphi contains TMetafileCanvas http://docs.embarcadero.com/products/rad_studio/delphiAndcpp2009/HelpUpdate2/EN/html/delphivclwin32/Graphics_TMetafileCanvas.html it can be argued as compatibility measure)

I personally prefer the first option.
What do others think?

Alexander S. Klenin

Reply by email

Felipe Monteiro de Carvalho
to Alexander Klenin

I think that the best would adding WMF and EMF writer modules to fpctrunk/packages/fpvectorial

A TMetafile class in Lazarus can also be added which uses fpvectorial as a backend, but for your purposes it looks to me that you could simply use fpvectorial directly. The code that you found could be reused to implement those writer, if it supports read WMF writing as opposed to using so Windows APIs. There is also a rejected patch for this here: http://bugs.freepascal.org/view.php?id=14333

I am working on fpvectorial these lasts months, but mostly in the DXF reading support and export to TFPCustomCanvas/TCanvas, not in export to WMF/EMF.

Note that I develop in lazarus-ccr/applications/fpvviewer and then I merge consolidated changes to fpctrunk/packages/fpvectorial

Felipe Monteiro de Carvalho

Reply by email

Felipe Monteiro de Carvalho
Alexander Klenin wrote 5 lines
That was my first thought too, but after looking at fpvectorial interface I found that it is not currently suitable neither for TAChart nor for WMF. This line in SVG writer illustrates some missing features: ?style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"

I'm in the process of implementing fill pattern, fill color, stroke (aka pen) color and pen width for the DXF reader as well as the generic data structure. If you verify the data structures used you will see that extending them for further capabilities is very easy because the structure is will designed.

Show quoted text 7 lines
>as opposed to using so Windows APIs The code I found does indeed use WinAPI, so it is Windows-specific. However, the upside is that it is relatively simple and possibly more efficient then hand-made implementation. Variants for other platforms may use corresponding libraries, like libwmf I think the difference is similar to LCL vs FPGUI -- "native look and speed" vs "portability and common code".

The difference is that the LCL uses libraries which are present anyway in the user system, like Gtk and Qt.

libwmf seams like an unwanted external dependency to me. It doesn't come preinstalled in my Linux, for example. Installing it in my MacBook would probably be a nightmare.

Felipe Monteiro de Carvalho

Reply by email

Felipe Monteiro de Carvalho
to Felipe Monteiro de Carvalho
Felipe Monteiro de Carvalho wrote 7 lines
>>as opposed to using so Windows APIs > The code I found does indeed use WinAPI, so it is Windows-specific. > However, the upside is that it is relatively simple and possibly more efficient > then hand-made implementation. > Variants for other platforms may use corresponding libraries, like libwmf > I think the difference is similar to LCL vs FPGUI -- "native look and speed" > vs "portability and common code".

If you really dont want to implement a WMF writer, then I suggest that you use libwmf to implement a writer backend for fpvectorial. This way when someone implements a native WMF writer TAChart can be changed with a single line of code to use the new native writer.

Adding support for the missing parts in the data structures of fpvectorial is trivial and I will do that in the next few days.

Felipe Monteiro de Carvalho

Reply by email

Alexander Klenin
Felipe Monteiro de Carvalho wrote
Could you repost your e-mails to the mailling list? It seams that they came only to me, while they might be useful for the general audience.

Oops, gmail defaults have caught me again.

----------------------------

Felipe Monteiro de Carvalho wrote
I think that the best would adding WMF and EMF writer modules to fpctrunk/packages/fpvectorial

That was my first thought too, but after looking at fpvectorial interface I found that
it is not currently suitable neither for TAChart nor for WMF. This line in SVG writer illustrates some missing features: style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"

as opposed to using so Windows APIs

The code I found does indeed use WinAPI, so it is Windows-specific. However, the upside is that it is relatively simple and possibly more efficient then hand-made implementation.
Variants for other platforms may use corresponding libraries, like libwmf I think the difference is similar to LCL vs FPGUI -- "native look and speed" vs "portability and common code".

----------------------------

Felipe Monteiro de Carvalho wrote
I'm in the process of implementing fill pattern, fill color, stroke (aka pen) color and pen width for the DXF reader as well as the generic data structure.

Good.

If you verify the data structures used you will see that extending them for further capabilities is very easy because the structure is will designed.

That is an excellent goal. Currently, however, there is some space for improvement:
1) Basic reader/writer is based on enum TvVectorialFormat, which does not allow adding new formats.
2) The data structure is very unefficient -- a class for every point in line! Also, usage of linked list makes random access to the structure very slow.
3) There is a separate function in TvVectorialDocument for each entity type, which does not allow adding new entities.

Show quoted text 6 lines
The difference is that the LCL uses libraries which are present anyway in the user system, like Gtk and Qt. libwmf seams like an unwanted external dependency to me. It doesn't come preinstalled in my Linux, for example. Installing it in my MacBook would probably be a nightmare.

Yes, but this is true for half of the packages present in FPC, see recent freetype problems for example.
So I do not think one more dependency is a serious problem.

----------------------------

Felipe Monteiro de Carvalho wrote 6 lines
On Thu, Apr 7, 2011 at 1:46 PM, Felipe Monteiro de Carvalho wrote: If you really dont want to implement a WMF writer, then I suggest that you use libwmf to implement a writer backend for fpvectorial. This way when someone implements a native WMF writer TAChart can be changed with a single line of code to use the new native writer.

Generally, I plan to implement fpvectorial back-end as soon as fpvectorial will have required features.
Exporting TAChart to DXF would be cool, even if not useful ;-)

After taking a closer look at libwmf, I noticed that it is mostly for _reading_ wmf,
so I am afraid a native writer is the only way for fpvectorial.

Alexander S. Klenin

Reply by email

Marco van de Voort
to Alexander Klenin: A TAChart user requested export to WMF/EMF: http://forum.lazarus.freepascal.org/index.php/…
Alexander Klenin wrote 17 lines
A TAChart user requested export to WMF/EMF: http://forum.lazarus.freepascal.org/index.php/topic,12693.0.html It turns out that Lazarus CCR has Metafile package, but it is incomplete and apparently abandoned. My options are: 1) Import the source into TAChart (it is only 350 lines of code), and fix/complete it there. 2) Somehow fix/complete the package in CCR, and then create a TAChartMetafile package depending on Metafile. 3) Import the source into LCL (since Delphi contains TMetafileCanvas http://docs.embarcadero.com/products/rad_studio/delphiAndcpp2009/HelpUpdate2/EN/html/delphivclwin32/Graphics_TMetafileCanvas.html it can be argued as compatibility measure) I personally prefer the first option. What do others think?

First consider if you are on the right OP wanted EMF because of font problems with SVG etc. EMF will have the same issues.

If you don't full font processing through the GDI, the resulting EMF will not look the same with GDI and without.

Example: DIA (the image editors) export.

Reply by email

Alexander Klenin
to Marco van de Voort
Marco van de Voort wrote
First consider if you are on the right OP wanted EMF because of font problems with SVG etc.

Why do you think so? To quote OP:

SVG would be cool with me but some people on windows would not know what to do with an SVG file. If it cannot be imported straight into office...

As you can see, his motivation has nothing to do with fonts.

EMF will have the same issues. If you don't full font processing through the GDI, the resulting EMF will not look the same with GDI and without.

I have already implemented both SVG and WMF/EMF backends, and EMF, as expected, represents exact copy of on-screen image (on Windows only, of course).
AFAIK, EMF will not work without GDI at all, so I am not sure what you are talking about.

Alexander S. Klenin

Reply by email

Felipe Monteiro de Carvalho
to Felipe Monteiro de Carvalho
Alexander Klenin wrote
Meanwhile, font support is also needed.
  TvText = class
  public
    X, Y, Z: Double; // Z is ignored in 2D formats
    Value: utf8string;
    FontColor: TvColor;
    FontSize: integer;
    FontName: utf8string;
  end;

What else do you need in the font support?

Felipe Monteiro de Carvalho

Reply by email

Hans-Peter Diettrich
to Felipe Monteiro de Carvalho
Show quoted text 7 lines
Alexander Klenin wrote: > Meanwhile, font support is also needed. TvText = class public X, Y, Z: Double; // Z is ignored in 2D formats Value: utf8string;

-----------------------------

Show quoted text 6 lines
FontColor: TvColor; FontSize: integer; FontName: utf8string; end; What else do you need in the font support?

Is this a mix of both a font declaration and usage? IMO metafiles contain different instructions for these.

Did you also notice that metafile fonts are managed by the metafile, i.e. the (GDI) objects must never be destroyed in explicit code?

DoDi

Reply by email

Felipe Monteiro de Carvalho
to Hans-Peter Diettrich
Hans-Peter Diettrich wrote
Is this a mix of both a font declaration and usage? IMO metafiles contain different instructions for these.

Well, it can always be separated if this is useful. I didn't do that right away because then I would need to write code to manage this new object. And because DXF puts the font size and color in the declaration of the text, so for DXF I would need to create one new font object for each Text object ... maybe a mixed solution is the best. If you assign a font object then it will be used, if not, then the inlined data will be used.

Did you also notice that metafile fonts are managed by the metafile, i.e. the (GDI) objects must never be destroyed in explicit code?

I'm not sure what you mean here. fpvectorial does not use platform-specific Metafile APIs.

Felipe Monteiro de Carvalho

Reply by email

Felipe Monteiro de Carvalho
to Felipe Monteiro de Carvalho
Hans-Peter Diettrich wrote
My remarks were about importing and interpreting WMF files. If you don't intend to support that format, you are free to handle everything as you like.

? Maybe we are not understanding each other. Basically you are saying that to support WMF you need to use some Windows APIs which deal with it, correct?

Then my answer is that this is neither necessary, nor desirable. You can read the specification of the WMF file format (or reverse engineer it) and implement importing it with our own code. And you can render it to the screen using fpvtocanvas.

For which task exactly would a Windows Metafile API be necessary?

Windows also has APIs for handling .ICO files, but Lazarus doesn't use them, because they are not desired. Nevertheless Lazarus still manages to have an excellent support for .ICO icons. The same applies to Metafiles, just the kind of object changed (raster to vectorial image).

Felipe Monteiro de Carvalho

Reply by email

Felipe Monteiro de Carvalho
to Felipe Monteiro de Carvalho
Hans-Peter Diettrich wrote
Rendering text in WMF files requires to remember the last specified font, that applies to all subsequent output. For other metafile formats it may be desireable to check given font parameters, and to reuse an previously specified font.

I still see no problem. We can simply start with a default font and then pass the entire file calculating the resulting font for each object/draw operation and store that font in it's data.

Consider the following Metafile:

SetFontWidth(X);
DrawArc();
SetFontColor(Y);
DrawCircle;

In my representation it is:

Arc with FontWidth=X and FontColor=default
Circle with FontWidth=X and FontColor=Y

The way that the data is represented is different, but the screen output will be the same. But now I follow up what you mean: Yes, my data model is different from the Metafile data model, but it is equivalent.

Surely fpvectorial could be changed to use the Metafile data model internally, but this also has drawbacks for other formats.

Felipe Monteiro de Carvalho

Reply by email

Felipe Monteiro de Carvalho
to Felipe Monteiro de Carvalho
Felipe Monteiro de Carvalho wrote
Surely fpvectorial could be changed to use the Metafile data model internally, but this also has drawbacks for other formats.

Actually I am quite divided about which is the best model to use =)

Metafile is faster to draw

The list of Entities is easier to manipulate, because each entity can be modified independently.

Felipe Monteiro de Carvalho

Reply by email

Felipe Monteiro de Carvalho
to Felipe Monteiro de Carvalho
Hans-Peter Diettrich wrote 15 lines
I'd separate the construction of metafiles from their use (drawing). Once a file has been created - be metafile, BMP, PNG, HTML, PDF etc. - its main purpose is distribution and presentation, not editing. In the simplest case drawing primitives are recorded in an metafile by e.g. switching the canvas, and all editing can occur in another application, independent from any metafile recorder and player. When an editor (AutoCad...) uses metafiles to store the entire state of a project (including invisible objects, symbols...), for later reload and continued editing, these parts can stay application-specific, and better should be stored in accordingly application-specific files. A general metafile should not contain more than the final drawing primitives. For editable metafiles it will be sufficient to allow for application-specific extensions, which can be skipped easily by the player base class (like unknown XML tags). Specific handling then can be built into derived classes.

I am totally lost about how this all applies to fpvectorial. Maybe you could explain more specifically how your ideas would apply to fpvectorial? wiki page: http://wiki.lazarus.freepascal.org/fpvectorial

Felipe Monteiro de Carvalho

Reply by email

Felipe Monteiro de Carvalho
to Felipe Monteiro de Carvalho

Forwarding to the mailling list:

Hans-Peter Diettrich wrote 10 lines
Felipe Monteiro de Carvalho schrieb: > I am totally lost about how this all applies to fpvectorial. I was talking about metafiles in general, not about specific metafile formats and conversions. DoDi

Reply by email