From f54fb7f7e83c07baba7c557117f8992223559431 Mon Sep 17 00:00:00 2001 From: Mario Voigt Date: Mon, 5 Jul 2021 13:40:47 +0200 Subject: [PATCH] added and fixed layer clip extensions from pernsteiner --- extensions/fablabchemnitz/layer_clip/clip.py | 73 +++++++++++++++++++ .../fablabchemnitz/layer_clip/clip_above.inx | 16 ++++ .../fablabchemnitz/layer_clip/clip_above.py | 52 +++++++++++++ .../fablabchemnitz/layer_clip/clip_below.inx | 16 ++++ .../fablabchemnitz/layer_clip/clip_below.py | 52 +++++++++++++ .../layer_clip/clip_current.inx | 16 ++++ .../fablabchemnitz/layer_clip/clip_current.py | 36 +++++++++ .../layer_clip/clip_fixtransform.inx | 16 ++++ .../layer_clip/clip_fixtransform.py | 41 +++++++++++ .../fablabchemnitz/layer_clip/clip_parent.inx | 16 ++++ .../fablabchemnitz/layer_clip/clip_parent.py | 45 ++++++++++++ .../fablabchemnitz/layer_clip/clip_remove.inx | 16 ++++ .../fablabchemnitz/layer_clip/clip_remove.py | 50 +++++++++++++ 13 files changed, 445 insertions(+) create mode 100644 extensions/fablabchemnitz/layer_clip/clip.py create mode 100644 extensions/fablabchemnitz/layer_clip/clip_above.inx create mode 100644 extensions/fablabchemnitz/layer_clip/clip_above.py create mode 100644 extensions/fablabchemnitz/layer_clip/clip_below.inx create mode 100644 extensions/fablabchemnitz/layer_clip/clip_below.py create mode 100644 extensions/fablabchemnitz/layer_clip/clip_current.inx create mode 100644 extensions/fablabchemnitz/layer_clip/clip_current.py create mode 100644 extensions/fablabchemnitz/layer_clip/clip_fixtransform.inx create mode 100644 extensions/fablabchemnitz/layer_clip/clip_fixtransform.py create mode 100644 extensions/fablabchemnitz/layer_clip/clip_parent.inx create mode 100644 extensions/fablabchemnitz/layer_clip/clip_parent.py create mode 100644 extensions/fablabchemnitz/layer_clip/clip_remove.inx create mode 100644 extensions/fablabchemnitz/layer_clip/clip_remove.py diff --git a/extensions/fablabchemnitz/layer_clip/clip.py b/extensions/fablabchemnitz/layer_clip/clip.py new file mode 100644 index 00000000..f62338f6 --- /dev/null +++ b/extensions/fablabchemnitz/layer_clip/clip.py @@ -0,0 +1,73 @@ +# Copyright (c) 2012 Stuart Pernsteiner +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are met: +# +# 1. Redistributions of source code must retain the above copyright notice, +# this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright notice, +# this list of conditions and the following disclaimer in the documentation +# and/or other materials provided with the distribution. +# +# THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR IMPLIED +# WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +# MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO +# EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +# OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +# ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +import sys +import inkex +import gettext +from lxml import etree +_ = gettext.gettext + +class ClipEffect(inkex.EffectExtension): + + def __init__(self, dirmark): + inkex.Effect.__init__(self) + self.dirmark = dirmark + + def effect(self): + defs = self.svg.getElement('//svg:defs') + + if len(self.svg.selected) != 1: + die(_("Error: You must select exactly one path")) + # Create the svg:clipPath inside of svg:defs + pathId = list(self.svg.selected.values())[0].get('id') + + #inkex.utils.debug(pathId) + clippath = etree.SubElement(defs, 'clipPath', + {'clipPathUnits': 'userSpaceOnUse' + ,'id': self.svg.get_unique_id("clipPath")}) + use = etree.SubElement(clippath, 'use', + {inkex.addNS('href','xlink'): '#' + pathId + ,'id': self.svg.get_unique_id("use")}) + + # Find the target layer and set its clip-path attribute + layer = self.svg.selected[pathId].getparent() + target = self.find_target(pathId) + + target.set('clip-path', 'url(#%s)' % clippath.get('id')) + + # Update layer names + label_attr = inkex.addNS('label', 'inkscape') + + layer_label = layer.get(label_attr) + layer.set(label_attr, layer_label + ' (c%s)' % self.dirmark) + + target_label = target.get(label_attr) + target.set(label_attr, target_label + ' (C)') + +def layername(layer): + return layer.get(inkex.addNS('label','inkscape')) + +def die(msg): + inkex.errormsg(msg) + sys.exit(1) + diff --git a/extensions/fablabchemnitz/layer_clip/clip_above.inx b/extensions/fablabchemnitz/layer_clip/clip_above.inx new file mode 100644 index 00000000..d328de0b --- /dev/null +++ b/extensions/fablabchemnitz/layer_clip/clip_above.inx @@ -0,0 +1,16 @@ + + + Clip Layer Above + fablabchemnitz.de_clip_layer_above + + path + + + + + + + + \ No newline at end of file diff --git a/extensions/fablabchemnitz/layer_clip/clip_above.py b/extensions/fablabchemnitz/layer_clip/clip_above.py new file mode 100644 index 00000000..c0570eb9 --- /dev/null +++ b/extensions/fablabchemnitz/layer_clip/clip_above.py @@ -0,0 +1,52 @@ +#!/usr/bin/env python3 + +# Copyright (c) 2012 Stuart Pernsteiner +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are met: +# +# 1. Redistributions of source code must retain the above copyright notice, +# this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright notice, +# this list of conditions and the following disclaimer in the documentation +# and/or other materials provided with the distribution. +# +# THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR IMPLIED +# WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +# MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO +# EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +# OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +# ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +import clip +import inkex +import gettext +_ = gettext.gettext + +class ClipAboveEffect(clip.ClipEffect): + def __init__(self): + clip.ClipEffect.__init__(self, '+') + + def find_target(self, pathId): + layer = self.svg.selected[pathId].getparent() + parent = layer.getparent() + sibling = None + last = None + + children = parent.getchildren() + children.reverse() + for child in children: + if child == layer and last is not None: + return last + last = child + + clip.die(_("Error: There is no layer above '%s'") % clip.layername(layer)) + +# Create effect instance and apply it. +ClipAboveEffect().run() + diff --git a/extensions/fablabchemnitz/layer_clip/clip_below.inx b/extensions/fablabchemnitz/layer_clip/clip_below.inx new file mode 100644 index 00000000..1fb896a0 --- /dev/null +++ b/extensions/fablabchemnitz/layer_clip/clip_below.inx @@ -0,0 +1,16 @@ + + + Clip Layer Below + fablabchemnitz.de_clip_layer_below + + path + + + + + + + + \ No newline at end of file diff --git a/extensions/fablabchemnitz/layer_clip/clip_below.py b/extensions/fablabchemnitz/layer_clip/clip_below.py new file mode 100644 index 00000000..6d1a1fa6 --- /dev/null +++ b/extensions/fablabchemnitz/layer_clip/clip_below.py @@ -0,0 +1,52 @@ +#!/usr/bin/env python3 + +# Copyright (c) 2012 Stuart Pernsteiner +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are met: +# +# 1. Redistributions of source code must retain the above copyright notice, +# this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright notice, +# this list of conditions and the following disclaimer in the documentation +# and/or other materials provided with the distribution. +# +# THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR IMPLIED +# WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +# MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO +# EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +# OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +# ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +import clip +import inkex +import gettext +_ = gettext.gettext + +class ClipBelowEffect(clip.ClipEffect): + def __init__(self): + clip.ClipEffect.__init__(self, '-') + + def find_target(self, pathId): + layer = self.svg.selected[pathId].getparent() + parent = layer.getparent() + sibling = None + last = None + + if clip.layername(parent) is None: + layer = parent + + for child in parent.getchildren(): + if child == layer and last is not None: + return last + last = child + + clip.die(_("Error: There is no layer below '%s'") % clip.layername(layer)) + +# Create effect instance and apply it. +ClipBelowEffect().run() diff --git a/extensions/fablabchemnitz/layer_clip/clip_current.inx b/extensions/fablabchemnitz/layer_clip/clip_current.inx new file mode 100644 index 00000000..d3769e93 --- /dev/null +++ b/extensions/fablabchemnitz/layer_clip/clip_current.inx @@ -0,0 +1,16 @@ + + + Clip Layer Current + fablabchemnitz.de_clip_layer_current + + path + + + + + + + + \ No newline at end of file diff --git a/extensions/fablabchemnitz/layer_clip/clip_current.py b/extensions/fablabchemnitz/layer_clip/clip_current.py new file mode 100644 index 00000000..0afbf251 --- /dev/null +++ b/extensions/fablabchemnitz/layer_clip/clip_current.py @@ -0,0 +1,36 @@ +#!/usr/bin/env python3 + +# Copyright (c) 2012 Stuart Pernsteiner +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are met: +# +# 1. Redistributions of source code must retain the above copyright notice, +# this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright notice, +# this list of conditions and the following disclaimer in the documentation +# and/or other materials provided with the distribution. +# +# THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR IMPLIED +# WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +# MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO +# EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +# OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +# ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +import clip +from lxml import etree +class ClipCurrentEffect(clip.ClipEffect): + def __init__(self): + clip.ClipEffect.__init__(self, '*') + + def find_target(self, pathId): + return self.svg.selected[pathId].getparent() + +# Create effect instance and apply it. +ClipCurrentEffect().run() diff --git a/extensions/fablabchemnitz/layer_clip/clip_fixtransform.inx b/extensions/fablabchemnitz/layer_clip/clip_fixtransform.inx new file mode 100644 index 00000000..cb1ea5fc --- /dev/null +++ b/extensions/fablabchemnitz/layer_clip/clip_fixtransform.inx @@ -0,0 +1,16 @@ + + + Clip Layer Fix Transform + fablabchemnitz.de_clip_layer_fix_transform + + path + + + + + + + + \ No newline at end of file diff --git a/extensions/fablabchemnitz/layer_clip/clip_fixtransform.py b/extensions/fablabchemnitz/layer_clip/clip_fixtransform.py new file mode 100644 index 00000000..6c6a5ab3 --- /dev/null +++ b/extensions/fablabchemnitz/layer_clip/clip_fixtransform.py @@ -0,0 +1,41 @@ +#!/usr/bin/env python3 + +# Copyright (c) 2012 Stuart Pernsteiner +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are met: +# +# 1. Redistributions of source code must retain the above copyright notice, +# this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright notice, +# this list of conditions and the following disclaimer in the documentation +# and/or other materials provided with the distribution. +# +# THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR IMPLIED +# WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +# MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO +# EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +# OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +# ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +import sys +import inkex + +class FixTransformEffect(inkex.EffectExtension): + + def effect(self): + defs = self.document.xpath('//svg:defs/svg:clipPath/svg:use', + namespaces=inkex.NSS) + + for d in defs: + del d.attrib['transform'] + +# Create effect instance and apply it. +FixTransformEffect().run() + + diff --git a/extensions/fablabchemnitz/layer_clip/clip_parent.inx b/extensions/fablabchemnitz/layer_clip/clip_parent.inx new file mode 100644 index 00000000..9d4dd650 --- /dev/null +++ b/extensions/fablabchemnitz/layer_clip/clip_parent.inx @@ -0,0 +1,16 @@ + + + Clip Layer Parent + fablabchemnitz.de_clip_layer_parent + + path + + + + + + + + \ No newline at end of file diff --git a/extensions/fablabchemnitz/layer_clip/clip_parent.py b/extensions/fablabchemnitz/layer_clip/clip_parent.py new file mode 100644 index 00000000..d1ea55fd --- /dev/null +++ b/extensions/fablabchemnitz/layer_clip/clip_parent.py @@ -0,0 +1,45 @@ +#!/usr/bin/env python3 + +# Copyright (c) 2012 Stuart Pernsteiner +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are met: +# +# 1. Redistributions of source code must retain the above copyright notice, +# this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright notice, +# this list of conditions and the following disclaimer in the documentation +# and/or other materials provided with the distribution. +# +# THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR IMPLIED +# WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +# MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO +# EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +# OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +# ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +import clip +import inkex +import gettext +_ = gettext.gettext + +class ClipParentEffect(clip.ClipEffect): + def __init__(self): + clip.ClipEffect.__init__(self, '**') + + def find_target(self, pathId): + layer = self.svg.getElementById(pathId).getparent() + parent = layer.getparent() + + if parent.get(inkex.addNS('groupmode','inkscape')) != 'layer': + clip.die(_("Error: Layer '%s' has no parent layer") % + clip.layername(layer)) + return parent + +# Create effect instance and apply it. +ClipParentEffect().run() diff --git a/extensions/fablabchemnitz/layer_clip/clip_remove.inx b/extensions/fablabchemnitz/layer_clip/clip_remove.inx new file mode 100644 index 00000000..612591f7 --- /dev/null +++ b/extensions/fablabchemnitz/layer_clip/clip_remove.inx @@ -0,0 +1,16 @@ + + + Clip Layer Remove + fablabchemnitz.de_clip_layer_remove + + path + + + + + + + + \ No newline at end of file diff --git a/extensions/fablabchemnitz/layer_clip/clip_remove.py b/extensions/fablabchemnitz/layer_clip/clip_remove.py new file mode 100644 index 00000000..b37b13c8 --- /dev/null +++ b/extensions/fablabchemnitz/layer_clip/clip_remove.py @@ -0,0 +1,50 @@ +#!/usr/bin/env python3 + +# Copyright (c) 2012 Stuart Pernsteiner +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are met: +# +# 1. Redistributions of source code must retain the above copyright notice, +# this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright notice, +# this list of conditions and the following disclaimer in the documentation +# and/or other materials provided with the distribution. +# +# THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR IMPLIED +# WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +# MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO +# EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +# OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +# ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +import sys +import inkex + +class RemoveClipEffect(inkex.Effect): + def __init__(self): + inkex.Effect.__init__(self) + + def effect(self): + path = list(self.svg.selected.values())[0] + layer = path.getparent() + if layer.attrib.has_key('clip-path'): + del layer.attrib['clip-path'] + + # Update layer name + label_attr = inkex.addNS('label', 'inkscape') + + layer_label = layer.get(label_attr) + if layer_label[-4:] == " (C)": + layer.set(label_attr, layer_label[:-4]) + + +# Create effect instance and apply it. +RemoveClipEffect().run() + +