several updates to bbox adjust and export selection
This commit is contained in:
parent
6c69939b0f
commit
13aebd6ec1
@ -1,6 +1,6 @@
|
|||||||
# MightyScape for Inkscape 1.0+
|
# MightyScape for Inkscape 1.0+
|
||||||
|
|
||||||
In short: A maintained extension collection for Inkscape 1.0+, working on Windows and Linux. There are **233 extension folders** with **406 .inx files** inside. We also take part at https://inkscape.org/gallery/=extension/ (with single extension uploads).
|
In short: A maintained extension collection for Inkscape 1.0+, working on Windows and Linux. There are **234 extension folders** with **407 .inx files** inside. We also take part at https://inkscape.org/gallery/=extension/ (with single extension uploads).
|
||||||
|
|
||||||
# About MightyScape
|
# About MightyScape
|
||||||
|
|
||||||
|
@ -1,12 +1,14 @@
|
|||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
clear
|
clear
|
||||||
|
|
||||||
|
|
||||||
echo "--> Validating inx files with xmllint. Only errors are printed to console"
|
echo "--> Validating inx files with xmllint. Only errors are printed to console"
|
||||||
for folder in */ ; do
|
for folder in */ ; do
|
||||||
xmllint --noout --relaxng ./inkscape.extension.rng ${folder}*.inx > /dev/null 2>> 000_xmllint.out
|
xmllint --noout --relaxng ./inkscape.extension.rng ${folder}*.inx > /dev/null 2>> 000_xmllint.out
|
||||||
done
|
done
|
||||||
grep -v "validates\|warning: failed to load external entity" 000_xmllint.out; rm 000_xmllint.out
|
grep -v "validates\|warning: failed to load external entity" 000_xmllint.out; rm 000_xmllint.out
|
||||||
|
|
||||||
|
|
||||||
#complete set of meta information
|
#complete set of meta information
|
||||||
AGGLOMERATED_JSON=""
|
AGGLOMERATED_JSON=""
|
||||||
for folder in */ ; do
|
for folder in */ ; do
|
||||||
@ -23,35 +25,65 @@ done
|
|||||||
#print overall json
|
#print overall json
|
||||||
#echo $AGGLOMERATED_JSON | jq
|
#echo $AGGLOMERATED_JSON | jq
|
||||||
|
|
||||||
|
|
||||||
echo "--> Show unique license kinds used:"
|
echo "--> Show unique license kinds used:"
|
||||||
echo $AGGLOMERATED_JSON | jq -r '.[]|{license}|.[]' | sort | uniq -c
|
echo $AGGLOMERATED_JSON | jq -r '.[]|{license}|.[]' | sort | uniq -c
|
||||||
|
|
||||||
|
|
||||||
echo "--> show unique list of involved contributors (thanks/credits):"
|
echo "--> show unique list of involved contributors (thanks/credits):"
|
||||||
#echo $AGGLOMERATED_JSON | jq -r '.[]|{main_authors}|.[]|.[]' | sort | uniq -c
|
#echo $AGGLOMERATED_JSON | jq -r '.[]|{main_authors}|.[]|.[]' | sort | uniq -c
|
||||||
echo $AGGLOMERATED_JSON | jq -r '.[]|{main_authors}|.[]|.[]' | sort | uniq
|
echo $AGGLOMERATED_JSON | jq -r '.[]|{main_authors}|.[]|.[]' | sort | uniq
|
||||||
|
|
||||||
|
|
||||||
#show extensions which are in gallery
|
#show extensions which are in gallery
|
||||||
GALLERY_EXTENSIONS=$(echo $AGGLOMERATED_JSON | jq -r '.[]|{inkscape_gallery_url}|.[]' | sort | grep -v "null")
|
GALLERY_EXTENSIONS=$(echo $AGGLOMERATED_JSON | jq -r '.[]|{inkscape_gallery_url}|.[]' | sort | grep -v "null")
|
||||||
for GALLERY_EXTENSION in ${GALLERY_EXTENSIONS}; do
|
for GALLERY_EXTENSION in ${GALLERY_EXTENSIONS}; do
|
||||||
EXTENSION=$(echo ${AGGLOMERATED_JSON} | jq -r '.[]|select(.inkscape_gallery_url=="'$GALLERY_EXTENSION'")|{name}|.[]')
|
EXTENSION=$(echo ${AGGLOMERATED_JSON} | jq -r '.[]|select(.inkscape_gallery_url=="'$GALLERY_EXTENSION'")|{name}|.[]')
|
||||||
done
|
done
|
||||||
|
|
||||||
|
|
||||||
echo "--> Count of inx files:"
|
echo "--> Count of inx files:"
|
||||||
INX=$(find ./ -type f -name "*.inx" | wc -l)
|
INX=$(find ./ -type f -name "*.inx" | wc -l)
|
||||||
echo INX: $INX
|
echo INX: $INX
|
||||||
|
|
||||||
|
|
||||||
echo "--> Count of extension folders:"
|
echo "--> Count of extension folders:"
|
||||||
FOLDERS=$(ls -d */ | wc -l)
|
FOLDERS=$(ls -d */ | wc -l)
|
||||||
echo FOLDERS: $FOLDERS
|
echo FOLDERS: $FOLDERS
|
||||||
|
|
||||||
|
|
||||||
README="../../README.md"
|
README="../../README.md"
|
||||||
#replace values in README.md
|
#replace values in README.md
|
||||||
sed -i 's/\*\*.* extension folders\*\*/\*\*'${FOLDERS}' extension folders\*\*/g' ${README}
|
sed -i 's/\*\*.* extension folders\*\*/\*\*'${FOLDERS}' extension folders\*\*/g' ${README}
|
||||||
sed -i 's/\*\* with .* \.inx files\*\*/\*\* with \*\*'${INX}' \.inx files\*\*/g' ${README}
|
sed -i 's/\*\* with .* \.inx files\*\*/\*\* with \*\*'${INX}' \.inx files\*\*/g' ${README}
|
||||||
|
|
||||||
|
|
||||||
echo "Removing unrequired pyc cache files"
|
echo "Removing unrequired pyc cache files"
|
||||||
find . -type d -name "__pycache__" -exec rm -rf {} \;
|
find . -type d -name "__pycache__" -exec rm -rf {} \;
|
||||||
|
|
||||||
|
|
||||||
|
read -p "Build local gallery extension zip files?" -n 1 -r
|
||||||
|
echo
|
||||||
|
if [[ $REPLY =~ ^[Yy]$ ]]; then
|
||||||
|
echo "Building extension zip files for zipmirror"
|
||||||
|
TARGETDIR="../../../mightyscape-1.X-zipmirror"
|
||||||
|
mkdir -p $TARGETDIR > /dev/null 2>&1
|
||||||
|
|
||||||
|
for EXTENSION in */; do
|
||||||
|
EXTENSION="${EXTENSION%/}" #strip trailing slash
|
||||||
|
EXTRA=""
|
||||||
|
if [[ $EXTENSION == "styles_to_layers" ]] || [[ $EXTENSION == "ungrouper_and_element_migrator_filter" ]] || [[ $EXTENSION == "epilog_dashboard_bbox_adjust" ]]; then
|
||||||
|
EXTRA="${EXTRA} apply_transformations/"
|
||||||
|
elif [[ $EXTENSION == "styles_to_layers" ]] || [[ $EXTENSION == "ungrouper_and_element_migrator_filter" ]]; then
|
||||||
|
EXTRA="${EXTRA} remove_empty_groups/"
|
||||||
|
fi
|
||||||
|
ZIPFILE=$TARGETDIR/$EXTENSION.zip
|
||||||
|
zip -ru $ZIPFILE $EXTENSION/ 000_about_fablabchemnitz.svg $EXTRA > /dev/null 2>&1
|
||||||
|
echo "--> creating/updating $ZIPFILE"
|
||||||
|
done
|
||||||
|
fi
|
||||||
|
|
||||||
|
|
||||||
read -p "Build local gallery extension zip files?" -n 1 -r
|
read -p "Build local gallery extension zip files?" -n 1 -r
|
||||||
echo
|
echo
|
||||||
if [[ $REPLY =~ ^[Yy]$ ]]; then
|
if [[ $REPLY =~ ^[Yy]$ ]]; then
|
||||||
@ -64,7 +96,7 @@ if [[ $REPLY =~ ^[Yy]$ ]]; then
|
|||||||
for GALLERY_EXTENSION in ${GALLERY_EXTENSIONS}; do
|
for GALLERY_EXTENSION in ${GALLERY_EXTENSIONS}; do
|
||||||
EXTENSION="$(echo ${AGGLOMERATED_JSON} | jq -r '.[]|select(.inkscape_gallery_url=="'$GALLERY_EXTENSION'")|{path}|.[]')"
|
EXTENSION="$(echo ${AGGLOMERATED_JSON} | jq -r '.[]|select(.inkscape_gallery_url=="'$GALLERY_EXTENSION'")|{path}|.[]')"
|
||||||
EXTRA=""
|
EXTRA=""
|
||||||
if [[ $EXTENSION == "styles_to_layers" ]] || [[ $EXTENSION == "ungrouper_and_element_migrator_filter" ]]; then
|
if [[ $EXTENSION == "styles_to_layers" ]] || [[ $EXTENSION == "ungrouper_and_element_migrator_filter" ]] || [[ $EXTENSION == "epilog_dashboard_bbox_adjust" ]]; then
|
||||||
EXTRA="${EXTRA} apply_transformations/"
|
EXTRA="${EXTRA} apply_transformations/"
|
||||||
elif [[ $EXTENSION == "styles_to_layers" ]] || [[ $EXTENSION == "ungrouper_and_element_migrator_filter" ]]; then
|
elif [[ $EXTENSION == "styles_to_layers" ]] || [[ $EXTENSION == "ungrouper_and_element_migrator_filter" ]]; then
|
||||||
EXTRA="${EXTRA} remove_empty_groups/"
|
EXTRA="${EXTRA} remove_empty_groups/"
|
||||||
@ -72,6 +104,6 @@ if [[ $REPLY =~ ^[Yy]$ ]]; then
|
|||||||
ZIPFILE=$TARGETDIR/$EXTENSION.zip
|
ZIPFILE=$TARGETDIR/$EXTENSION.zip
|
||||||
rm $ZIPFILE > /dev/null 2>&1
|
rm $ZIPFILE > /dev/null 2>&1
|
||||||
echo "--> creating $ZIPFILE"
|
echo "--> creating $ZIPFILE"
|
||||||
zip -r $ZIPFILE $EXTENSION/ 000_about_fablabchemnitz.svg $EXTRA
|
zip -ru $ZIPFILE $EXTENSION/ 000_about_fablabchemnitz.svg $EXTRA
|
||||||
done
|
done
|
||||||
fi
|
fi
|
||||||
|
@ -4,8 +4,9 @@
|
|||||||
<id>fablabchemnitz.de.epilog_dashboard_bbox_adjust</id>
|
<id>fablabchemnitz.de.epilog_dashboard_bbox_adjust</id>
|
||||||
<param name="tab" type="notebook">
|
<param name="tab" type="notebook">
|
||||||
<page name="tab_settings" gui-text="Settings">
|
<page name="tab_settings" gui-text="Settings">
|
||||||
|
<param name="apply_transformations" type="bool" gui-text="Apply transformations (requires separate extension)" gui-description="This will call the extension 'Apply Transformations'. Helps avoiding geometry shifting">false</param>
|
||||||
<param name="offset" type="float" min="0.0" max="1000.0" precision="3" gui-text="XY Offset (mm) from top left corner">1.0</param>
|
<param name="offset" type="float" min="0.0" max="1000.0" precision="3" gui-text="XY Offset (mm) from top left corner">1.0</param>
|
||||||
<param name="removal" gui-text="Element removal" type="optiongroup" appearance="combo" gui-description="Remove all elements outside the bounding box or selection">
|
<param name="removal" gui-text="Element removal" type="optiongroup" appearance="combo" gui-description="Remove all elements outside the bounding box or selection. PObjects partially outside the canvas will be dropped too in case you selected 'outside of canvas'">
|
||||||
<option value="none">none</option>
|
<option value="none">none</option>
|
||||||
<option value="outside_canvas">outside of canvas</option>
|
<option value="outside_canvas">outside of canvas</option>
|
||||||
<option value="outside_selection">outside of selection</option>
|
<option value="outside_selection">outside of selection</option>
|
||||||
@ -19,6 +20,7 @@
|
|||||||
<option value="1219x914">1219 x 914 mm (Fusion Pro 48)</option>
|
<option value="1219x914">1219 x 914 mm (Fusion Pro 48)</option>
|
||||||
</param>
|
</param>
|
||||||
<param name="debug" type="bool" gui-text="Debug output">false</param>
|
<param name="debug" type="bool" gui-text="Debug output">false</param>
|
||||||
|
<param name="skip_errors" type="bool" gui-text="Skip on errors">false</param>
|
||||||
</page>
|
</page>
|
||||||
<page name="tab_about" gui-text="About">
|
<page name="tab_about" gui-text="About">
|
||||||
<label appearance="header">Epilog Dashboard BBox Adjust</label>
|
<label appearance="header">Epilog Dashboard BBox Adjust</label>
|
||||||
|
@ -10,7 +10,7 @@ So we add a default (small) amount of 1.0 doc units to expand the document's can
|
|||||||
Author: Mario Voigt / FabLab Chemnitz
|
Author: Mario Voigt / FabLab Chemnitz
|
||||||
Mail: mario.voigt@stadtfabrikanten.org
|
Mail: mario.voigt@stadtfabrikanten.org
|
||||||
Date: 21.04.2021
|
Date: 21.04.2021
|
||||||
Last patch: 27.05.2021
|
Last patch: 26.0510.2021
|
||||||
License: GNU GPL v3
|
License: GNU GPL v3
|
||||||
|
|
||||||
#known bugs:
|
#known bugs:
|
||||||
@ -23,8 +23,10 @@ License: GNU GPL v3
|
|||||||
'''
|
'''
|
||||||
|
|
||||||
import math
|
import math
|
||||||
|
import sys
|
||||||
import inkex
|
import inkex
|
||||||
from inkex import Transform
|
from inkex import Transform
|
||||||
|
sys.path.append("../apply_transformations")
|
||||||
|
|
||||||
class EpilogDashboardBboxAdjust(inkex.EffectExtension):
|
class EpilogDashboardBboxAdjust(inkex.EffectExtension):
|
||||||
|
|
||||||
@ -39,33 +41,105 @@ class EpilogDashboardBboxAdjust(inkex.EffectExtension):
|
|||||||
|
|
||||||
def add_arguments(self, pars):
|
def add_arguments(self, pars):
|
||||||
pars.add_argument("--tab")
|
pars.add_argument("--tab")
|
||||||
|
pars.add_argument("--apply_transformations", type=inkex.Boolean, default=False, help="Run 'Apply Transformations' extension before running vpype. Helps avoiding geometry shifting")
|
||||||
pars.add_argument("--offset", type=float, default="1.0", help="XY Offset (mm) from top left corner")
|
pars.add_argument("--offset", type=float, default="1.0", help="XY Offset (mm) from top left corner")
|
||||||
pars.add_argument("--removal", default="none", help="Remove all elements outside the bounding box or selection")
|
pars.add_argument("--removal", default="none", help="Remove all elements outside the bounding box or selection")
|
||||||
pars.add_argument("--use_machine_size", type=inkex.Boolean, default=False, help="Use machine size")
|
pars.add_argument("--use_machine_size", type=inkex.Boolean, default=False, help="Use machine size")
|
||||||
pars.add_argument("--machine_size", default="812x508", help="Machine/Size")
|
pars.add_argument("--machine_size", default="812x508", help="Machine/Size")
|
||||||
pars.add_argument("--debug", type=inkex.Boolean, default=False, help="Debug output")
|
pars.add_argument("--debug", type=inkex.Boolean, default=False, help="Debug output")
|
||||||
|
pars.add_argument("--skip_errors", type=inkex.Boolean, default=False, help="Skip on errors")
|
||||||
|
|
||||||
def effect(self):
|
def effect(self):
|
||||||
|
|
||||||
|
applyTransformationsAvailable = False # at first we apply external extension
|
||||||
|
try:
|
||||||
|
import apply_transformations
|
||||||
|
applyTransformationsAvailable = True
|
||||||
|
except Exception as e:
|
||||||
|
# self.msg(e)
|
||||||
|
self.msg("Calling 'Apply Transformations' extension failed. Maybe the extension is not installed. You can download it from official InkScape Gallery. Skipping ...")
|
||||||
|
|
||||||
|
if self.options.apply_transformations is True and applyTransformationsAvailable is True:
|
||||||
|
apply_transformations.ApplyTransformations().recursiveFuseTransform(self.document.getroot())
|
||||||
|
|
||||||
offset = self.options.offset
|
offset = self.options.offset
|
||||||
#units = self.svg.unit
|
|
||||||
units = "mm" #force millimeters
|
units = "mm" #force millimeters
|
||||||
|
scale_factor = self.svg.unittouu("1px")
|
||||||
|
#namedView = self.document.getroot().find(inkex.addNS('namedview', 'sodipodi'))
|
||||||
|
#doc_units = namedView.get(inkex.addNS('document-units', 'inkscape'))
|
||||||
|
#doc_units = self.svg.unit
|
||||||
|
#https://wiki.inkscape.org/wiki/Units_In_Inkscape
|
||||||
|
#remove sodipodi units. Some actions add units to namedview, but we already have "inkscape:document-units".
|
||||||
|
#namedView.pop('units')
|
||||||
|
#del namedView.attrib["units"] #does the same like namedView.pop('units')
|
||||||
|
|
||||||
# create a new bounding box and get the bbox size of all elements of the document (we cannot use the page's bbox)
|
# create a new bounding box and get the bbox size of all elements of the document (we cannot use the page's bbox)
|
||||||
bbox = inkex.BoundingBox()
|
bbox = inkex.BoundingBox()
|
||||||
if len(self.svg.selected) > 0:
|
if len(self.svg.selected) > 0:
|
||||||
bbox = self.svg.selection.bounding_box()
|
#bbox = self.svg.selection.bounding_box() #it could be so easy! But ...
|
||||||
#for element in self.svg.selected.values():
|
for element in self.svg.selected.values():
|
||||||
# bbox += element.bounding_box()
|
'''
|
||||||
|
...rectangles cause some strangle scaling issue, offendingly caused by namedview units.
|
||||||
|
The rectangle attributes are set in px. They ignore the real units from namedview.
|
||||||
|
Strange fact: ellipses, spirals and other primitives work flawlessly.
|
||||||
|
'''
|
||||||
|
if isinstance (element, inkex.Rectangle):
|
||||||
|
bbox += element.bounding_box() * scale_factor
|
||||||
|
elif isinstance (element, inkex.TextElement):
|
||||||
|
if self.options.skip_errors is False:
|
||||||
|
self.msg("Text elements are not supported!")
|
||||||
|
return
|
||||||
|
else:
|
||||||
|
continue
|
||||||
|
else:
|
||||||
|
bbox += element.bounding_box()
|
||||||
else:
|
else:
|
||||||
#for element in self.svg.root.getchildren():
|
#for element in self.svg.root.getchildren():
|
||||||
for element in self.document.getroot().iter("*"):
|
for element in self.document.getroot().iter("*"):
|
||||||
if isinstance (element, inkex.ShapeElement) and element.tag != inkex.addNS('use','svg') and element.get('inkscape:groupmode') != 'layer': #bbox fails for svg:use elements and layers:
|
if isinstance (element, inkex.ShapeElement) and element.tag != inkex.addNS('use','svg') and element.get('inkscape:groupmode') != 'layer': #bbox fails for svg:use elements and layers:
|
||||||
bbox += element.bounding_box()
|
if isinstance (element, inkex.Rectangle):
|
||||||
|
bbox += element.bounding_box() * scale_factor
|
||||||
|
elif isinstance (element, inkex.TextElement):
|
||||||
|
if self.options.skip_errors is False:
|
||||||
|
self.msg("Text elements are not supported!")
|
||||||
|
return
|
||||||
|
else:
|
||||||
|
continue
|
||||||
|
else:
|
||||||
|
bbox += element.bounding_box()
|
||||||
|
|
||||||
if abs(bbox.width) == math.inf or abs(bbox.height) == math.inf:
|
if abs(bbox.width) == math.inf or abs(bbox.height) == math.inf:
|
||||||
inkex.utils.debug("Error calculating bounding box! Impossible to continue!")
|
inkex.utils.debug("Error while calculating overall bounding box! Check your element types. Things like svg:text or svg:use are not supported. Impossible to continue!")
|
||||||
return
|
return
|
||||||
|
|
||||||
|
#if len(self.svg.selected) > 0:
|
||||||
|
# selected = self.svg.selected
|
||||||
|
#else:
|
||||||
|
# selected = self.svg.root.getchildren()
|
||||||
|
#for element in selected:
|
||||||
|
# transform = inkex.Transform()
|
||||||
|
# parent = element.getparent()
|
||||||
|
# if parent is not None and isinstance(parent, inkex.ShapeElement):
|
||||||
|
# transform = parent.composed_transform()
|
||||||
|
# try:
|
||||||
|
# '''
|
||||||
|
# ...rectangles cause some strangle scaling issue, offendingly caused by namedview units.
|
||||||
|
# The rectangle attributes are set in px. They ignore the real units from namedview.
|
||||||
|
# Strange fact: ellipses, spirals and other primitives work flawlessly.
|
||||||
|
# '''
|
||||||
|
# if isinstance (element, inkex.Rectangle) or isinstance (element, inkex.TextElement):
|
||||||
|
# bbox += element.bounding_box(transform) * scale_factor
|
||||||
|
# else:
|
||||||
|
# bbox += element.bounding_box(transform)
|
||||||
|
# except Exception:
|
||||||
|
# logger.exception("Bounding box not computed")
|
||||||
|
# logger.info("Skipping bounding box")
|
||||||
|
# transform = element.composed_transform()
|
||||||
|
# x1, y1 = transform.apply_to_point([0, 0])
|
||||||
|
# x2, y2 = transform.apply_to_point([1, 1])
|
||||||
|
# bbox += inkex.BoundingBox((x1, x2), (y1, y2))
|
||||||
|
|
||||||
|
|
||||||
# adjust the viewBox to the bbox size and add the desired offset
|
# adjust the viewBox to the bbox size and add the desired offset
|
||||||
if self.options.use_machine_size is True:
|
if self.options.use_machine_size is True:
|
||||||
machineWidth = float(self.options.machine_size.split('x')[0])
|
machineWidth = float(self.options.machine_size.split('x')[0])
|
||||||
|
@ -6,6 +6,14 @@
|
|||||||
<page name="tab_settings" gui-text="Settings">
|
<page name="tab_settings" gui-text="Settings">
|
||||||
<param name="wrap_transform" type="bool" gui-text="Wrap final document in transform">false</param>
|
<param name="wrap_transform" type="bool" gui-text="Wrap final document in transform">false</param>
|
||||||
<param name="border_offset" type="float" min="0.000" max="9999.000" precision="3" gui-text="Add border offset around selection">1.000</param>
|
<param name="border_offset" type="float" min="0.000" max="9999.000" precision="3" gui-text="Add border offset around selection">1.000</param>
|
||||||
|
<param name="border_offset_unit" type="optiongroup" appearance="combo" gui-text="Offset unit">
|
||||||
|
<option value="mm">mm</option>
|
||||||
|
<option value="cm">cm</option>
|
||||||
|
<option value="px">px</option>
|
||||||
|
<option value="pt">pt</option>
|
||||||
|
<option value="pc">pc</option>
|
||||||
|
<option value="in">in</option>
|
||||||
|
</param>
|
||||||
<param name="export_dir" type="path" mode="folder" gui-text="Location to save exported documents">./inkscape_export/</param>
|
<param name="export_dir" type="path" mode="folder" gui-text="Location to save exported documents">./inkscape_export/</param>
|
||||||
<param name="opendir" type="bool" gui-text="Open containing output directory after export">false</param>
|
<param name="opendir" type="bool" gui-text="Open containing output directory after export">false</param>
|
||||||
<param name="dxf_exporter_path" type="path" mode="file" filetypes="py" gui-text="Location of dxf_outlines.py" gui-description="Do not use dxf12_outlines.py! This will try to create R12 DXF files, which will fail!">/usr/share/inkscape/extensions/dxf_outlines.py</param>
|
<param name="dxf_exporter_path" type="path" mode="file" filetypes="py" gui-text="Location of dxf_outlines.py" gui-description="Do not use dxf12_outlines.py! This will try to create R12 DXF files, which will fail!">/usr/share/inkscape/extensions/dxf_outlines.py</param>
|
||||||
@ -16,6 +24,7 @@
|
|||||||
<param name="png_dpi" type="float" min="1" max="2400" precision="3" gui-text="PNG DPI (applies for export and replace)" gui-description="default is 96">96</param>
|
<param name="png_dpi" type="float" min="1" max="2400" precision="3" gui-text="PNG DPI (applies for export and replace)" gui-description="default is 96">96</param>
|
||||||
<param name="replace_by_png" type="bool" gui-text="Replace by PNG" gui-description="Please convert strokes to paths to keep exact size and prevent cutoffs!">false</param>
|
<param name="replace_by_png" type="bool" gui-text="Replace by PNG" gui-description="Please convert strokes to paths to keep exact size and prevent cutoffs!">false</param>
|
||||||
<param name="newwindow" type="bool" gui-text="Open file in new Inkscape instance">false</param>
|
<param name="newwindow" type="bool" gui-text="Open file in new Inkscape instance">false</param>
|
||||||
|
<param name="skip_errors" type="bool" gui-text="Skip on errors">false</param>
|
||||||
<label>Note: If svg/dxf/pdf already existed before, they might get accidently deleted or overwritten. Please take care!</label>
|
<label>Note: If svg/dxf/pdf already existed before, they might get accidently deleted or overwritten. Please take care!</label>
|
||||||
</page>
|
</page>
|
||||||
<page name="tab_about" gui-text="About">
|
<page name="tab_about" gui-text="About">
|
||||||
|
@ -32,6 +32,7 @@ class ExportObject(inkex.EffectExtension):
|
|||||||
pars.add_argument("--tab")
|
pars.add_argument("--tab")
|
||||||
pars.add_argument("--wrap_transform", type=inkex.Boolean, default=False, help="Wrap final document in transform")
|
pars.add_argument("--wrap_transform", type=inkex.Boolean, default=False, help="Wrap final document in transform")
|
||||||
pars.add_argument("--border_offset", type=float, default=1.000, help="Add border offset around selection")
|
pars.add_argument("--border_offset", type=float, default=1.000, help="Add border offset around selection")
|
||||||
|
pars.add_argument("--border_offset_unit", default="mm", help="Offset unit")
|
||||||
pars.add_argument("--export_dir", default="~/inkscape_export/", help="Location to save exported documents")
|
pars.add_argument("--export_dir", default="~/inkscape_export/", help="Location to save exported documents")
|
||||||
pars.add_argument("--opendir", type=inkex.Boolean, default=False, help="Open containing output directory after export")
|
pars.add_argument("--opendir", type=inkex.Boolean, default=False, help="Open containing output directory after export")
|
||||||
pars.add_argument("--dxf_exporter_path", default="/usr/share/inkscape/extensions/dxf_outlines.py", help="Location of dxf_outlines.py")
|
pars.add_argument("--dxf_exporter_path", default="/usr/share/inkscape/extensions/dxf_outlines.py", help="Location of dxf_outlines.py")
|
||||||
@ -42,6 +43,7 @@ class ExportObject(inkex.EffectExtension):
|
|||||||
pars.add_argument("--png_dpi", type=float, default=96, help="PNG DPI (applies for export and replace)")
|
pars.add_argument("--png_dpi", type=float, default=96, help="PNG DPI (applies for export and replace)")
|
||||||
pars.add_argument("--replace_by_png", type=inkex.Boolean, default=False, help="Replace selection by png export")
|
pars.add_argument("--replace_by_png", type=inkex.Boolean, default=False, help="Replace selection by png export")
|
||||||
pars.add_argument("--newwindow", type=inkex.Boolean, default=False, help="Open file in new Inkscape window")
|
pars.add_argument("--newwindow", type=inkex.Boolean, default=False, help="Open file in new Inkscape window")
|
||||||
|
pars.add_argument("--skip_errors", type=inkex.Boolean, default=False, help="Skip on errors")
|
||||||
|
|
||||||
def openExplorer(self, dir):
|
def openExplorer(self, dir):
|
||||||
if os.name == 'nt':
|
if os.name == 'nt':
|
||||||
@ -61,6 +63,7 @@ class ExportObject(inkex.EffectExtension):
|
|||||||
warnings.simplefilter("default", ResourceWarning)
|
warnings.simplefilter("default", ResourceWarning)
|
||||||
|
|
||||||
def effect(self):
|
def effect(self):
|
||||||
|
scale_factor = self.svg.unittouu("1px")
|
||||||
|
|
||||||
svg_export = self.options.export_svg
|
svg_export = self.options.export_svg
|
||||||
extra_param = "--batch-process"
|
extra_param = "--batch-process"
|
||||||
@ -90,7 +93,7 @@ class ExportObject(inkex.EffectExtension):
|
|||||||
export_dir = Path(self.absolute_href(self.options.export_dir))
|
export_dir = Path(self.absolute_href(self.options.export_dir))
|
||||||
os.makedirs(export_dir, exist_ok=True)
|
os.makedirs(export_dir, exist_ok=True)
|
||||||
|
|
||||||
offset = self.options.border_offset
|
offset = self.svg.unittouu(str(self.options.border_offset) + self.options.border_offset_unit)
|
||||||
|
|
||||||
bbox = inkex.BoundingBox()
|
bbox = inkex.BoundingBox()
|
||||||
|
|
||||||
@ -98,17 +101,31 @@ class ExportObject(inkex.EffectExtension):
|
|||||||
firstId = selected[0].get('id')
|
firstId = selected[0].get('id')
|
||||||
parent = self.svg.getElementById(firstId).getparent()
|
parent = self.svg.getElementById(firstId).getparent()
|
||||||
|
|
||||||
for elem in selected.values():
|
for element in selected.values():
|
||||||
transform = inkex.Transform()
|
transform = inkex.Transform()
|
||||||
parent = elem.getparent()
|
parent = element.getparent()
|
||||||
if parent is not None and isinstance(parent, inkex.ShapeElement):
|
if parent is not None and isinstance(parent, inkex.ShapeElement):
|
||||||
transform = parent.composed_transform()
|
transform = parent.composed_transform()
|
||||||
try:
|
try:
|
||||||
bbox += elem.bounding_box(transform)
|
'''
|
||||||
|
...rectangles cause some strangle scaling issue, offendingly caused by namedview units.
|
||||||
|
The rectangle attributes are set in px. They ignore the real units from namedview.
|
||||||
|
Strange fact: ellipses, spirals and other primitives work flawlessly.
|
||||||
|
'''
|
||||||
|
if isinstance (element, inkex.Rectangle):
|
||||||
|
bbox += element.bounding_box(transform) * scale_factor
|
||||||
|
elif isinstance (element, inkex.TextElement):
|
||||||
|
if self.options.skip_errors is False:
|
||||||
|
self.msg("Text elements are not supported!")
|
||||||
|
return
|
||||||
|
else:
|
||||||
|
continue
|
||||||
|
else:
|
||||||
|
bbox += element.bounding_box(transform)
|
||||||
except Exception:
|
except Exception:
|
||||||
logger.exception("Bounding box not computed")
|
logger.exception("Bounding box not computed")
|
||||||
logger.info("Skipping bounding box")
|
logger.info("Skipping bounding box")
|
||||||
transform = elem.composed_transform()
|
transform = element.composed_transform()
|
||||||
x1, y1 = transform.apply_to_point([0, 0])
|
x1, y1 = transform.apply_to_point([0, 0])
|
||||||
x2, y2 = transform.apply_to_point([1, 1])
|
x2, y2 = transform.apply_to_point([1, 1])
|
||||||
bbox += inkex.BoundingBox((x1, x2), (y1, y2))
|
bbox += inkex.BoundingBox((x1, x2), (y1, y2))
|
||||||
@ -120,12 +137,12 @@ class ExportObject(inkex.EffectExtension):
|
|||||||
group.attrib['id'] = GROUP_ID
|
group.attrib['id'] = GROUP_ID
|
||||||
group.attrib['transform'] = str(inkex.Transform(((1, 0, -bbox.left), (0, 1, -bbox.top))))
|
group.attrib['transform'] = str(inkex.Transform(((1, 0, -bbox.left), (0, 1, -bbox.top))))
|
||||||
|
|
||||||
for elem in self.svg.selected.values():
|
for element in self.svg.selected.values():
|
||||||
if elem.tag == inkex.addNS('image', 'svg'):
|
if element.tag == inkex.addNS('image', 'svg'):
|
||||||
continue #skip images
|
continue #skip images
|
||||||
elem_copy = deepcopy(elem)
|
elem_copy = deepcopy(element)
|
||||||
elem_copy.attrib['transform'] = str(elem.composed_transform())
|
elem_copy.attrib['transform'] = str(element.composed_transform())
|
||||||
elem_copy.attrib['style'] = str(elem.composed_style())
|
elem_copy.attrib['style'] = str(element.composed_style())
|
||||||
group.append(elem_copy)
|
group.append(elem_copy)
|
||||||
|
|
||||||
template.attrib['viewBox'] = f'{-offset} {-offset} {bbox.width + offset * 2} {bbox.height + offset * 2}'
|
template.attrib['viewBox'] = f'{-offset} {-offset} {bbox.width + offset * 2} {bbox.height + offset * 2}'
|
||||||
@ -133,7 +150,7 @@ class ExportObject(inkex.EffectExtension):
|
|||||||
template.attrib['height'] = f'{bbox.height + offset * 2}' + self.svg.unit
|
template.attrib['height'] = f'{bbox.height + offset * 2}' + self.svg.unit
|
||||||
|
|
||||||
if svg_filename is None:
|
if svg_filename is None:
|
||||||
filename_base = elem.attrib.get('id', None).replace(os.sep, '_')
|
filename_base = element.attrib.get('id', None).replace(os.sep, '_')
|
||||||
if filename_base:
|
if filename_base:
|
||||||
svg_filename = filename_base + '.svg'
|
svg_filename = filename_base + '.svg'
|
||||||
if not filename_base: #should never be the case. Inkscape might crash if the id attribute is empty or not existent due to invalid SVG
|
if not filename_base: #should never be the case. Inkscape might crash if the id attribute is empty or not existent due to invalid SVG
|
||||||
@ -241,8 +258,8 @@ class ExportObject(inkex.EffectExtension):
|
|||||||
self.msg(cli_output)
|
self.msg(cli_output)
|
||||||
#then remove the selection and replace it by png
|
#then remove the selection and replace it by png
|
||||||
#self.msg(parent.get('id'))
|
#self.msg(parent.get('id'))
|
||||||
for elem in selected.values():
|
for element in selected.values():
|
||||||
elem.delete()
|
element.delete()
|
||||||
#read png file and get base64 string from it
|
#read png file and get base64 string from it
|
||||||
try:
|
try:
|
||||||
img = Image.open(png_export)
|
img = Image.open(png_export)
|
||||||
|
Reference in New Issue
Block a user