added and fixed layer clip extensions from pernsteiner

This commit is contained in:
Mario Voigt 2021-07-05 13:40:47 +02:00
parent 44d5767472
commit f54fb7f7e8
13 changed files with 445 additions and 0 deletions

View File

@ -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)

View File

@ -0,0 +1,16 @@
<?xml version="1.0" encoding="UTF-8"?>
<inkscape-extension xmlns="http://www.inkscape.org/namespace/inkscape/extension">
<name>Clip Layer Above</name>
<id>fablabchemnitz.de_clip_layer_above</id>
<effect>
<object-type>path</object-type>
<effects-menu>
<submenu name="FabLab Chemnitz">
<submenu name="Layer Clip" />
</submenu>
</effects-menu>
</effect>
<script>
<command location="inx" interpreter="python">clip_above.py</command>
</script>
</inkscape-extension>

View File

@ -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()

View File

@ -0,0 +1,16 @@
<?xml version="1.0" encoding="UTF-8"?>
<inkscape-extension xmlns="http://www.inkscape.org/namespace/inkscape/extension">
<name>Clip Layer Below</name>
<id>fablabchemnitz.de_clip_layer_below</id>
<effect>
<object-type>path</object-type>
<effects-menu>
<submenu name="FabLab Chemnitz">
<submenu name="Layer Clip" />
</submenu>
</effects-menu>
</effect>
<script>
<command location="inx" interpreter="python">clip_below.py</command>
</script>
</inkscape-extension>

View File

@ -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()

View File

@ -0,0 +1,16 @@
<?xml version="1.0" encoding="UTF-8"?>
<inkscape-extension xmlns="http://www.inkscape.org/namespace/inkscape/extension">
<name>Clip Layer Current</name>
<id>fablabchemnitz.de_clip_layer_current</id>
<effect>
<object-type>path</object-type>
<effects-menu>
<submenu name="FabLab Chemnitz">
<submenu name="Layer Clip" />
</submenu>
</effects-menu>
</effect>
<script>
<command location="inx" interpreter="python">clip_current.py</command>
</script>
</inkscape-extension>

View File

@ -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()

View File

@ -0,0 +1,16 @@
<?xml version="1.0" encoding="UTF-8"?>
<inkscape-extension xmlns="http://www.inkscape.org/namespace/inkscape/extension">
<name>Clip Layer Fix Transform</name>
<id>fablabchemnitz.de_clip_layer_fix_transform</id>
<effect>
<object-type>path</object-type>
<effects-menu>
<submenu name="FabLab Chemnitz">
<submenu name="Layer Clip" />
</submenu>
</effects-menu>
</effect>
<script>
<command location="inx" interpreter="python">clip_fixtransform.py</command>
</script>
</inkscape-extension>

View File

@ -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()

View File

@ -0,0 +1,16 @@
<?xml version="1.0" encoding="UTF-8"?>
<inkscape-extension xmlns="http://www.inkscape.org/namespace/inkscape/extension">
<name>Clip Layer Parent</name>
<id>fablabchemnitz.de_clip_layer_parent</id>
<effect>
<object-type>path</object-type>
<effects-menu>
<submenu name="FabLab Chemnitz">
<submenu name="Layer Clip" />
</submenu>
</effects-menu>
</effect>
<script>
<command location="inx" interpreter="python">clip_parent.py</command>
</script>
</inkscape-extension>

View File

@ -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()

View File

@ -0,0 +1,16 @@
<?xml version="1.0" encoding="UTF-8"?>
<inkscape-extension xmlns="http://www.inkscape.org/namespace/inkscape/extension">
<name>Clip Layer Remove</name>
<id>fablabchemnitz.de_clip_layer_remove</id>
<effect>
<object-type>path</object-type>
<effects-menu>
<submenu name="FabLab Chemnitz">
<submenu name="Layer Clip" />
</submenu>
</effects-menu>
</effect>
<script>
<command location="inx" interpreter="python">clip_remove.py</command>
</script>
</inkscape-extension>

View File

@ -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()