184 lines
6.2 KiB
Python
184 lines
6.2 KiB
Python
import xml.etree.ElementTree as ET
|
|
import xml.dom.minidom as minidom
|
|
import random
|
|
import math
|
|
|
|
from . import uuid_gen
|
|
from . import datamatrix
|
|
|
|
|
|
class Label:
|
|
def __init__(self, name, category, others, url):
|
|
self.name = name
|
|
self.url = url
|
|
self.category = category
|
|
self.others = others
|
|
|
|
def get_svg_element(self):
|
|
e = ET.Element("g")
|
|
|
|
fr = ET.SubElement(e, "flowRoot")
|
|
fr.set("style", "font-family:Sans;text-anchor:middle;font-size:1")
|
|
rect = ET.SubElement(ET.SubElement(fr, "flowRegion"), "rect")
|
|
rect.set("height", "23")
|
|
rect.set("width", "30")
|
|
rect.set("x", "2.5")
|
|
rect.set("y", "2.5")
|
|
|
|
fp = ET.SubElement(fr, "flowPara")
|
|
fp.set("style", "text-align:left;font-size:2.5")
|
|
fp.text = self.category
|
|
fp = ET.SubElement(fr, "flowPara")
|
|
fp.set("style", "line-height:110%;text-align:center;font-size:4")
|
|
fp.text = self.name
|
|
fp = ET.SubElement(fr, "flowPara")
|
|
fp.set("style", "fill:none;line-height:50%;text-align:center;font-size:1.8")
|
|
fp.text = "a"
|
|
for par in self.others:
|
|
fp = ET.SubElement(fr, "flowPara")
|
|
fp.set("style", "text-align:left;font-size:1.8")
|
|
fp.text = par
|
|
|
|
dmc = datamatrix.encode(self.url, datamatrix.symbols["rect12x36"])
|
|
if len(dmc) > 1:
|
|
raise Error("identifier too long")
|
|
dmg = ET.SubElement(e, "g")
|
|
dmg.set(
|
|
"transform",
|
|
"translate({:f} {:f})".format(
|
|
35.0 / 2 - (1.0 * 32) / 2, 37.125 - (32 / 36 * 12) - 1.5
|
|
),
|
|
)
|
|
datamatrix.render_data_matrix(dmc, 32 / 36, 0, dmg)
|
|
e.append(dmg)
|
|
|
|
return e
|
|
|
|
@staticmethod
|
|
def from_dict(d):
|
|
labels = {
|
|
"description": "desc",
|
|
"package": "pkg",
|
|
"value": "val",
|
|
"manufacturer": "mfr",
|
|
}
|
|
others = []
|
|
for l in labels:
|
|
if l in d:
|
|
others.append("{:s}: {:s}".format(labels[l], d[l]))
|
|
return Label(d["name"], d["type"], others, d["url"])
|
|
|
|
@staticmethod
|
|
def empty():
|
|
_id = "HTTP://I/{:014d}".format(math.floor((random.random()) * 10 ** 14))
|
|
return Label("", "", "", _id)
|
|
|
|
|
|
class Labelgen:
|
|
def __init__(
|
|
self,
|
|
width=210,
|
|
height=297,
|
|
x_no=6,
|
|
y_no=8,
|
|
x_marg=1,
|
|
y_marg=1,
|
|
x_offset=0,
|
|
y_offset=0,
|
|
outline=False,
|
|
add_uuid=False,
|
|
):
|
|
self._width = width
|
|
self._height = height
|
|
self._x_no = x_no
|
|
self._y_no = y_no
|
|
self._x_marg = x_marg
|
|
self._y_marg = y_marg
|
|
self._x_offset = x_offset
|
|
self._y_offset = y_offset
|
|
self._outline = outline
|
|
self._fields = [None] * ((x_no - 2 * x_marg) * (y_no - 2 * y_marg))
|
|
self._add_uuid = add_uuid
|
|
|
|
def gen_svg(self, filename):
|
|
ET.register_namespace("", "http://www.w3.org/2000/svg")
|
|
montage = ET.ElementTree(element=ET.Element("svg"))
|
|
|
|
mr = montage.getroot()
|
|
mr.set("width", "{:d}mm".format(self._width))
|
|
mr.set("height", "{:d}mm".format(self._height))
|
|
xoffset = self._x_offset
|
|
yoffset = self._y_offset
|
|
mr.set(
|
|
"viewBox",
|
|
"{:f} {:f} {:f} {:f}".format(
|
|
0 + xoffset, 0 + yoffset, self._width + xoffset, self._height + yoffset
|
|
),
|
|
)
|
|
|
|
el_x = self._width / self._x_no
|
|
el_y = self._height / self._y_no
|
|
|
|
field_no = 0
|
|
for yn in range(self._y_no):
|
|
for xn in range(self._x_no):
|
|
if (
|
|
yn >= self._y_marg
|
|
and yn < self._y_no - self._y_marg
|
|
and xn >= self._x_marg
|
|
and xn < self._x_no - self._x_marg
|
|
):
|
|
field_no += 1
|
|
field = self._fields[field_no - 1]
|
|
if field is not None:
|
|
el = ET.Element("g")
|
|
el.set(
|
|
"transform",
|
|
"translate({:f} {:f})".format(xn * el_x, yn * el_y),
|
|
)
|
|
el.append(field.get_svg_element())
|
|
mr.append(el)
|
|
if self._outline:
|
|
fr = ET.Element("rect")
|
|
mg = 0.9
|
|
fr.set("style", "fill:none;stroke:#000000;stroke-width:0.2")
|
|
fr.set("x", "{:f}".format(mg))
|
|
fr.set("y", "{:f}".format(mg))
|
|
fr.set("width", "{:f}".format(35 - 2 * mg))
|
|
fr.set("height", "{:f}".format(37.125 - 2 * mg))
|
|
el.append(fr)
|
|
elif self._add_uuid:
|
|
for ux in range(3):
|
|
for uy in range(3):
|
|
if yn + 1 == self._y_no and uy + 1 == 3:
|
|
continue
|
|
if xn + 1 == self._x_no and ux + 1 == 3:
|
|
continue
|
|
if yn == 0 and uy == 0:
|
|
continue
|
|
if xn == 0 and ux == 0:
|
|
continue
|
|
el = ET.Element("g")
|
|
el.set(
|
|
"transform",
|
|
"translate({:f} {:f}) scale(8 8)".format(
|
|
xn * 35 + 10 * ux + 2.5,
|
|
yn * 37.125 + 10 * uy + (37.125 - 30) / 2,
|
|
),
|
|
)
|
|
el.append(uuid_gen.get_uuid())
|
|
mr.append(el)
|
|
|
|
xmlstr = minidom.parseString(ET.tostring(mr)).toprettyxml(indent=" ")
|
|
with open(filename, "w") as f:
|
|
f.write(xmlstr)
|
|
|
|
def set_label(self, field_no, label):
|
|
self._fields[field_no - 1] = label
|
|
|
|
|
|
if __name__ == "__main__":
|
|
l = Labelgen()
|
|
l.set_label(2, Label("name", "category", {"pkg": "carton box"}, "HTTP://I/100"))
|
|
l.gen_svg("test.svg")
|