added Label Color extension
This commit is contained in:
parent
92e163a793
commit
00b275bacc
16
extensions/fablabchemnitz_label_color.inx
Normal file
16
extensions/fablabchemnitz_label_color.inx
Normal file
@ -0,0 +1,16 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<inkscape-extension xmlns="http://www.inkscape.org/namespace/inkscape/extension">
|
||||
<name>Label Feature With Fill Color</_ame>
|
||||
<id>fablabchemnitz.de.label_color</id>
|
||||
<effect>
|
||||
<object-type>all</object-type>
|
||||
<effects-menu>
|
||||
<submenu name="FabLab Chemnitz">
|
||||
<submenu name="Various"/>
|
||||
</submenu>
|
||||
</effects-menu>
|
||||
</effect>
|
||||
<script>
|
||||
<command reldir="extensions" interpreter="python">fablabchemnitz_label_color.py</command>
|
||||
</script>
|
||||
</inkscape-extension>
|
144
extensions/fablabchemnitz_label_color.py
Normal file
144
extensions/fablabchemnitz_label_color.py
Normal file
@ -0,0 +1,144 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
|
||||
"""
|
||||
A inkscape plugin to label features with their fill colour
|
||||
|
||||
|
||||
Copyright (C) 2019 Christoph Fink
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
"""
|
||||
|
||||
import inkex
|
||||
from inkex.paths import CubicSuperPath, Path
|
||||
from lxml import etree
|
||||
|
||||
class LabelColour(inkex.Effect):
|
||||
def __init__(self):
|
||||
inkex.Effect.__init__(self)
|
||||
|
||||
def effect(self):
|
||||
if len(self.svg.selected) > 0:
|
||||
for id, node in self.svg.selected.items():
|
||||
self.labelFeature(node)
|
||||
|
||||
def labelFeature(self, node):
|
||||
style = node.get('style')
|
||||
if style:
|
||||
nodeStyle = dict(inkex.Style.parse_str(node.attrib["style"]))
|
||||
nodeColour, labelColour = self.getNodeAndLabelColours(nodeStyle["fill"])
|
||||
nodeX, nodeY, nodeWidth, nodeHeight = self.getNodeDimensions(node)
|
||||
parent = node.getparent()
|
||||
label = etree.SubElement(
|
||||
parent,
|
||||
inkex.addNS("text", "svg"),
|
||||
{
|
||||
"font-size": str(nodeHeight/4),
|
||||
"x": str(nodeX + (nodeWidth/2)),
|
||||
"y": str(nodeY + (nodeHeight/2)),
|
||||
"dy": "0.5em",
|
||||
"style": str(inkex.Style({
|
||||
"fill": labelColour,
|
||||
"stroke": "none",
|
||||
"text-anchor": "middle"
|
||||
}))
|
||||
}
|
||||
)
|
||||
labelTextSpan = etree.SubElement(
|
||||
label,
|
||||
inkex.addNS("tspan", "svg"),
|
||||
{}
|
||||
)
|
||||
labelTextSpan.text = nodeColour
|
||||
|
||||
|
||||
def getNodeAndLabelColours(self, nodeStyleFill):
|
||||
if nodeStyleFill[:5] == "url(#":
|
||||
nodeFill = self.svg.getElementById(nodeStyleFill[5:-1])
|
||||
if "Gradient" in nodeFill.tag:
|
||||
nodeColour, labelColour = self.getNodeAndLabelColourForGradient(nodeFill)
|
||||
else:
|
||||
nodeColour = ""
|
||||
labelColour = ""
|
||||
|
||||
else:
|
||||
nodeColour = nodeStyleFill
|
||||
labelColour = self.getLabelColour(nodeColour)
|
||||
|
||||
return (nodeColour, labelColour)
|
||||
|
||||
def getNodeAndLabelColourForGradient(self, gradientNode):
|
||||
stops = self.getGradientStops(gradientNode)
|
||||
|
||||
nodeColours = []
|
||||
|
||||
for stop in stops:
|
||||
offset = float(stop[0])
|
||||
colour = stop[1]
|
||||
nodeColours.append("{colour:s}{offset:s}".format(
|
||||
colour=colour,
|
||||
offset="" if offset in (0, 1) else " ({:0.2f})".format(offset)
|
||||
))
|
||||
nodeColour = u" ↔ ".join(nodeColours)
|
||||
|
||||
avgNodeColour = [sum([inkex.Color(stop[1]).to_rgb()[c] for stop in stops]) / len(stops) for c in range(3)]
|
||||
|
||||
labelColour = str(inkex.Color(avgNodeColour))
|
||||
|
||||
return (nodeColour, labelColour)
|
||||
|
||||
def getGradientStops(self, gradientNode):
|
||||
while "{http://www.w3.org/1999/xlink}href" in gradientNode.attrib:
|
||||
gradientNode = self.svg.getElementById(gradientNode.attrib["{http://www.w3.org/1999/xlink}href"][1:]) # noqa:E129
|
||||
|
||||
stops = []
|
||||
|
||||
for child in gradientNode:
|
||||
if "stop" in child.tag:
|
||||
stopStyle = dict(inkex.Style.parse_str(child.attrib["style"]))
|
||||
stops.append((child.attrib["offset"], stopStyle["stop-color"]))
|
||||
|
||||
# if only opacity differs (colour == same), return one stop only:
|
||||
if len(set([s[1] for s in stops])) == 1:
|
||||
stops = [(0, stops[0][1])]
|
||||
|
||||
return stops
|
||||
|
||||
def getLabelColour(self, nodeColour):
|
||||
labelColour = "#000000"
|
||||
|
||||
try:
|
||||
nodeColour = inkex.Color(nodeColour).to_rgb()
|
||||
if sum(nodeColour) / len(nodeColour) < 128:
|
||||
labelColour = "#ffffff"
|
||||
except (
|
||||
TypeError,
|
||||
ZeroDivisionError # if parseColor returns ""
|
||||
):
|
||||
pass
|
||||
|
||||
return labelColour
|
||||
|
||||
def getNodeDimensions(self, node):
|
||||
bbox = node.bounding_box()
|
||||
nodeX = bbox.left
|
||||
nodeY = bbox.top
|
||||
nodeWidth = bbox.right - bbox.left
|
||||
nodeHeight = bbox.bottom - bbox.top
|
||||
|
||||
return nodeX, nodeY, nodeWidth, nodeHeight
|
||||
|
||||
LabelColour().run()
|
Reference in New Issue
Block a user