Jump to content
Sign in to follow this  
Rollo62

[Image32 - SVG] Is there a feature to control the XmlTree ?

Recommended Posts

@angusj

Hi Angus, I'm still playing with your nice Image32 library.

It behaves really well under all circumstances.

 

What I'm trying to achieve is to open an SVG, and to have the ability to access certain elements and/or layers,

to make them visible/invisible, including all their possible sub-elements in the tree.

So my goal is to have a complex SVG, with certain layers, where I can control the rendering on-the-fly at runtime, like on/off changing color, etc..

 

The internal structures are somewhat hidden, and the SvgReader/SvgParser seems to decode sub-elements on demand from text of TAnsi record.

I have tried to make the internal SvgTree structures accessible, but that doesn't help much to get easy control over the certain elements.

 

The .text property seems to hold the whole node data as string text, with the text.AsUTF8String; it only returns a certain part, I assume only the <style> part.

Since .text is a pointer, I'm not sure if the following text is usuable at all, but its looks that its containing the current node as string.

 

The Id and other identifiers seems all to be hashed, so I cannot retrieve and find nodes easily in the tree.

 

I can see that the internal structures are optimized for best rendering SVG, which it does very well ( even SVG that fails elsewhere ).

My question is, if there is a simple way to access and control the SVG-tree on the fly, to control parts of that rendering process ?

 

 

 

Share this post


Link to post

@Rollo62

Thank you for the encouraging feedback. I'm glad Image32 is behaving as advertised 😁.

9 hours ago, Rollo62 said:

So my goal is to have a complex SVG, with certain layers, where I can control the rendering on-the-fly at runtime

I'm afraid Image32's SVG support is pretty much read-only.

There is an extremely basic SVG writer, that's separate from the reader, and really just proof of concept.

The reader was designed for speed, not for editing as you've discovered.

Regarding hashing:  I'm assuming it's faster than string comparing, which there are many, but honestly I haven't tested if it makes a difference and how much (and yes it does complicate the code).

Regarding UTF8String: Just about every SVG is written in UTF-8 which given it was initially created for web graphics makes sense. So again for performance the file isn't converted to Unicode, and the XML parser just creates pointers into the UTF-8 stream.

 

9 hours ago, Rollo62 said:

My question is, if there is a simple way to access and control the SVG-tree on the fly

No, not at the moment. I do intend to convert the reader to read-write at some stage. However I'm not sure when that will happen as I'm taking a much needed breather after spending a lot of time on this. I also have another project (my Clipper library) that's been stuck in a partial update for several years that's probably my next priority. If there was huge demand for read-write SVGs I might make that the higher priority but my perception is that reading SVGs is/was by far the bigger need.

Cheers.

Share this post


Link to post

@angusj

Thanks for the answers, yes I have seen that it has included a fast reader/parser basically.

 

So the best possible approach would be to re-load complete SVG's from string,
while controlling visibility and change properties outside of the SvgReader, by a standard XML tree object.

I will check into that direction then.

Share this post


Link to post

@Rollo62

On 8/24/2021 at 9:07 PM, Rollo62 said:

So my goal is to have a complex SVG, with certain layers, where I can control the rendering on-the-fly at runtime, like on/off changing color, etc..

I've just uploaded to Image32's SourceForge repository another update to the SVG reader. The changes are primarily in anticipation of future animation but they should also allow you to dynamically change (most) element properties including fill and stroke colors, opacity etc.

 

https://sourceforge.net/p/image32/code/ci/master/tree/source/

 

Example:

 

procedure ChangeNearBlackPenToNavy(element: TElement);
var
  i: integer;
  dd: TDrawData;
begin
  if (element.DrawData.strokeColor <> clInvalid) and 
    (element.DrawData.strokeColor <> clNone32) and
    (RgbToHsl(element.DrawData.strokeColor).lum < 5) then
  begin
    dd := element.DrawData;
    dd.strokeColor := clNavy32;
    element.DrawData := dd;
  end;
  //recursively call all children
  for i := 0 to element.ChildCount -1 do
    ChangeNearBlackPenToNavy(element[i]);
end;
//and to use the above procedure
begin
  if not svgReader.LoadFromFile(fn) then Exit;
  //edit the loaded SVG elements
  ChangeNearBlackPenToNavy(svgReader.RootElement);
  //draw the edited SVG elements
  svgReader.DrawImage(ImagePanel.Image, true);
end;

 

Edited by angusj
Added an example
  • Like 1

Share this post


Link to post

@angusj

Thanks a lot.

Yes the properties can be set in the Elements DrawData dynamically, works nicely.

 

Unfortunately the missing link right now is how to identify the desired element(s) in the first place.

Either a "FindById" function, or some kind of "Id" property in the TElement might help to identify and grab the desired element.

Maybe I can find that in a future releases one day.,

I'm curious to see where this nice library might evolve into, I see a huge potential.

 

 

 

Share this post


Link to post
1 hour ago, Rollo62 said:

Either a "FindById" function, or some kind of "Id" property in the TElement

Try this ...

unit Img32.SVG.Reader;
....

  TElement = class
  private
    ....
    fId             : UTF8String;
  public
    ....
    property Id: UTF8String read fId;
  end;

procedure Id_Attrib(aOwnerEl: TElement; const value: UTF8String);
begin
  aOwnerEl.fId := value; //ADD THIS LINE
  aOwnerEl.fReader.fIdList.AddObject(string(value), aOwnerEl);
end;

 

Share this post


Link to post

@angusj

Thanks for the proposal, yes that works well in some tests.

 

I had considered before that this might add too much additional redudancy, since the same data is copied or hashed maybe in other places still,

and I have tried to restore the hashed data before.

In reality, after a second thought, this additional data doesn't matter much.

 

The reason is that only a few "Id's" will be used in the whole SVG, so thats irrelevant regarding redundancy.

Edited by Rollo62

Share this post


Link to post

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
Sign in to follow this  

×