Inkscape.org
Creating New Extensions Replicate "Object to Path" in extension with inkex
  1. #1
    gmagno gmagno @gmagno

    I'm developing an extension, and one of the steps that I need is to get a list of objects and convert all of them to paths.

    If I would do it in GUI I would select all the objects then use the option `Path > Object to Path` (`Shift + Ctrl + C`).

    I tried to replicate it with this code:

    for i, elem in enumerate(layer):
      layer[i] = elem.to_path_element()

    It seems to work, it converts all objects in the layer to a Path. But if one of the Objects is originally a Text object, it will be converted to an empty path object.

    What am I missing here?

  2. #2
    inklinea inklinea @inklinea⛰️

    Bounding boxes and paths for text objects are not available in inkex.

    https://inkscape.gitlab.io/extensions/documentation/source/inkex.elements._text.html

    Returns a horrible bounding box that just contains the coord points of the text without width or height (which is impossible to calculate)

    The functions in the gui and those in inkex are not one and the same.

    To access core program actions, we have to make a command call.

    That is to call the Inkscape command line to process a temp file and then read the changes.

    The trick is to minimise the number of calls.

    For text ( or any visual bounding box - which takes account of stroke width/filters etc ) 

    We would use the command call action to get the paths, and also use the option --query-all to grab  the bounding boxes of all objects at the same time :)

    Generally would feed --query-all into a parsing function to get a dictionary of visual bounding boxes for all objects.

    However as a side note.

    The extension Scientific Inkscape has a module to get text bounding boxes using python. Its very good for most fonts, and gets better everyday.

  3. #3
    gmagno gmagno @gmagno

    Oh, that is good to know, thank you @inklinea

    In fact, I was in doubt rather it would be better for me to create an extension with inkex, or if I could use Inkscape cli actions to achieve what I wanted.

    Basically what I want to do is to create a global outline of all the objects inside a layer, and create a new layer which will have a single path object with the outline (having a transparent fill color, and a specific line contour color).

    Most of the steps I can do simply by doing keyboard shortcuts in inkscape. The most "complex" step is actually to apply an outline Path Effect.

    Do you think that what I want to do could be achieved by concatenating Inkscape actions? (for instance, is it possible to apply a Path Effect with actions?)

  4. #4
    inklinea inklinea @inklinea⛰️

    What do you mean by outline.

    Just a big rectangle ? or a special contoured outline which follows the shapes like an outset. 

    Making rectangle can sort of be done using the command line. You cannot create a rectangle. However you could insert a basic rectangle after the end of the opening <svg> tag. It would be the first object painted so at the very back.

    Then you use object-set-attribute to change the rectangle to match the size and position that you want. 

    I'm not aware of being able to apply a path effect with actions.

    On the other hand you could just do the command call in Inkex.

    You can batch process files using python 'for files in folder' etc and use the inkex load function to load each one in turn and process it. 

  5. #5
    sillyfrog sillyfrog @sillyfrog

    I needed something similar, and have come up with this, it _does_ call out to an instance of Inkscape, but it works well (based on limited testing):

    def getTextPath(s):
        svg = inkex.SvgDocumentElement()
        # Create a text element
        t = inkex.elements.TextElement()
        t.text = s
        t.set("x", "100")
        t.set("y", "100")
    
        svg.append(t)
    
        paths_svg_str = io.BytesIO(
            inkex.command.inkscape(
                "--pipe",
                "--export-text-to-path",
                "--export-filename",
                "-",
                stdin=svg.tostring(),
            ).encode()
        )
        paths_svg = inkex.extensions.load_svg(paths_svg_str)
    
        # Extract all the path elements from the document
        paths = paths_svg.xpath("//svg:path", namespaces=inkex.NSS)
    
        return paths[0]

    (This is my in progress code, so very messy, but should be enough to get you started doing the same)

Inkscape Inkscape.org Inkscape Forum Creating New Extensions Replicate "Object to Path" in extension with inkex