--- a/svghmi/fonts.py Tue Mar 30 10:05:55 2021 +0200
+++ b/svghmi/fonts.py Tue Mar 30 14:54:43 2021 +0200
@@ -17,14 +17,17 @@
font = ttLib.TTFont(filename)
# https://developer.apple.com/fonts/TrueType-Reference-Manual/RM06/Chap6name.html
for name in font["name"].names:
- if name.nameID==1 and name.platformID in [0,3]:
+ if name.nameID in [1,16] and name.platformID==3 and name.langID==1033: familyname = name.toUnicode()
+ if name.nameID==4 and name.platformID==3 and name.langID==1033: + uniquename = name.toUnicode() @@ -32,13 +35,13 @@
mimetype = "font/" + formatname
# conditions on sfntVersion was deduced from fontTools.ttLib.sfnt
elif font.sfntVersion in ("\x00\x01\x00\x00", "true"):
- formatname = "truetype"
+ formatname = "truetype" elif font.sfntVersion == "OTTO":
- return familyname,formatname,mimetype
+ return familyname,uniquename,formatname,mimetype def DataURIFromFile(filename, mimetype):
with open(filename, "rb") as fp:
@@ -50,7 +53,7 @@
b64encode(data).strip()])
def GetCSSFontFaceFromFontFile(filename):
- familyname, formatname, mimetype = GetFontTypeAndFamilyName(filename)
+ familyname, uniquename, formatname, mimetype = GetFontTypeAndFamilyName(filename) data_uri = DataURIFromFile(filename, mimetype)
--- a/svghmi/gen_index_xhtml.xslt Tue Mar 30 10:05:55 2021 +0200
+++ b/svghmi/gen_index_xhtml.xslt Tue Mar 30 14:54:43 2021 +0200
@@ -1,6 +1,6 @@
-<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:exsl="http://exslt.org/common" xmlns:regexp="http://exslt.org/regular-expressions" xmlns:str="http://exslt.org/strings" xmlns:func="http://exslt.org/functions" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:cc="http://creativecommons.org/ns#" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:svg="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" xmlns:xhtml="http://www.w3.org/1999/xhtml" xmlns:debug="debug" xmlns:preamble="preamble" xmlns:declarations="declarations" xmlns:definitions="definitions" xmlns:epilogue="epilogue" xmlns:ns="beremiz" version="1.0" extension-element-prefixes="ns func exsl regexp str dyn" exclude-result-prefixes="ns func exsl regexp str dyn debug preamble epilogue declarations definitions">
- <xsl:output cdata-section-elements="xhtml:script" method="xml"/>
+<xsl:stylesheet xmlns:ns="beremiz" xmlns:definitions="definitions" xmlns:xhtml="http://www.w3.org/1999/xhtml" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:func="http://exslt.org/functions" xmlns:epilogue="epilogue" xmlns:preamble="preamble" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" xmlns:svg="http://www.w3.org/2000/svg" xmlns:cc="http://creativecommons.org/ns#" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:str="http://exslt.org/strings" xmlns:regexp="http://exslt.org/regular-expressions" xmlns:exsl="http://exslt.org/common" xmlns:declarations="declarations" xmlns:debug="debug" exclude-result-prefixes="ns func exsl regexp str dyn debug preamble epilogue declarations definitions" extension-element-prefixes="ns func exsl regexp str dyn" version="1.0"> + <xsl:output method="xml" cdata-section-elements="xhtml:script"/> <xsl:variable name="svg" select="/svg:svg"/>
<xsl:variable name="hmi_elements" select="//svg:*[starts-with(@inkscape:label, 'HMI:')]"/>
<xsl:variable name="hmitree" select="ns:GetHMITree()"/>
@@ -1713,7 +1713,7 @@
<xsl:variable name="excluded_types" select="str:split('Page VarInit VarInitPersistent')"/>
- <xsl:key name="TypesKey" match="widget" use="@type"/>
+ <xsl:key use="@type" name="TypesKey" match="widget"/> <declarations:hmi-classes/>
<xsl:template match="declarations:hmi-classes">
--- a/svghmi/gen_index_xhtml.ysl2 Tue Mar 30 10:05:55 2021 +0200
+++ b/svghmi/gen_index_xhtml.ysl2 Tue Mar 30 14:54:43 2021 +0200
@@ -69,7 +69,11 @@
html xmlns="http://www.w3.org/1999/xhtml"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink" {
+ style type="text/css" media="screen" { // prevents user selection by mouse click / touch and drag
// prevents pinch zoom and other accidental panning panning with touch devices
body style="margin:0;overflow:hidden;user-select:none;touch-action:none;" {
--- a/svghmi/svghmi.py Tue Mar 30 10:05:55 2021 +0200
+++ b/svghmi/svghmi.py Tue Mar 30 14:54:43 2021 +0200
@@ -313,7 +313,7 @@
- "tooltip": _("Add TTF, OTH or WOFF font to be embedded in HMI"),
+ "tooltip": _("Add TTF, OTF or WOFF font to be embedded in HMI"), @@ -400,6 +400,18 @@
+ def GetFonts(self, _context): + project_path = self.CTNPath() + fontdir = os.path.join(project_path, "fonts") + for f in sorted(os.listdir(fontdir)): + fontfile = os.path.join(fontdir,f) + if os.path.isfile(fontfile): + css_parts.append(GetCSSFontFaceFromFontFile(fontfile)) + return "".join(css_parts) def ProgressStart(self, k, m):
@@ -455,6 +467,7 @@
[("GetSVGGeometry", lambda *_ignored:self.GetSVGGeometry()),
("GetHMITree", lambda *_ignored:self.GetHMITree()),
("GetTranslations", self.GetTranslations),
+ ("GetFonts", self.GetFonts), ("ProgressStart", lambda _ign,k,m:self.ProgressStart(str(k),str(m))),
("ProgressEnd", lambda _ign,k:self.ProgressEnd(str(k)))])
@@ -618,10 +631,62 @@
self.GetCTRoot().logger.write_error(_("POT file does not exist, add translatable text (label starting with '_') in Inkscape first\n"))
+ dialog = wx.FileDialog( + self.GetCTRoot().AppFrame, + os.path.expanduser("~"), + _("Font files (*.ttf;*.otf;*.woff;*.woff2)|*.ttf;*.otf;*.woff;*.woff2"), wx.OPEN) + if dialog.ShowModal() == wx.ID_OK: + fontfile = dialog.GetPath() + if os.path.isfile(fontfile): + familyname, uniquename, formatname, mimetype = GetFontTypeAndFamilyName(fontfile) + self.GetCTRoot().logger.write_error( + _('Selected font %s is not a readable file\n')%fontfile) + if familyname is None or uniquename is None or formatname is None or mimetype is None: + self.GetCTRoot().logger.write_error( + _('Selected font file %s is invalid or incompatible\n')%fontfile) + project_path = self.CTNPath() + fontfname = uniquename + "." + mimetype.split('/')[1] + fontdir = os.path.join(project_path, "fonts") + newfontfile = os.path.join(fontdir, fontfname) + if not os.path.exists(fontdir): + shutil.copyfile(fontfile, newfontfile) + self.GetCTRoot().logger.write( + _('Added font %s as %s\n')%(fontfile,newfontfile))
+ project_path = self.CTNPath() + fontdir = os.path.join(project_path, "fonts") + dialog = wx.FileDialog( + self.GetCTRoot().AppFrame, + _("Choose a font to remove"), + _("Font files (*.ttf;*.otf;*.woff;*.woff2)|*.ttf;*.otf;*.woff;*.woff2"), wx.OPEN) + if dialog.ShowModal() == wx.ID_OK: + fontfile = dialog.GetPath() + if os.path.isfile(fontfile): + if os.path.relpath(fontfile, fontdir) == os.path.basename(fontfile): + self.GetCTRoot().logger.write( + _('Removed font %s\n')%fontfile) + self.GetCTRoot().logger.write_error( + _("Font to remove %s is not in %s\n") % (fontfile,fontdir)) + self.GetCTRoot().logger.write_error( + _("Font file does not exist: %s\n") % fontfile) def CTNGlobalInstances(self):
# view_name = self.BaseParams.getName()