]> git.immae.eu Git - perso/Immae/Projets/Python/MusicSampler.git/commitdiff
Remove fonts from directory
authorIsmaël Bouya <ismael.bouya@normalesup.org>
Wed, 27 Jul 2016 17:32:38 +0000 (19:32 +0200)
committerIsmaël Bouya <ismael.bouya@normalesup.org>
Wed, 27 Jul 2016 17:44:09 +0000 (19:44 +0200)
documentation_fr.md
fonts/Symbola.ttf [deleted file]
fonts/Ubuntu-B.ttf [deleted file]
fonts/Ubuntu-Regular.ttf [deleted file]
helpers/__init__.py
helpers/sysfont.py [new file with mode: 0644]
music_sampler.kv
music_sampler.py
music_sampler.spec

index 622b05445eb10f32e381fca89ad05096af69e609..8ba058d6d2379bcd8107ef0ff6e0f8fb14737b38 100644 (file)
@@ -8,14 +8,15 @@ Music Sampler est un lecteur de musique qui permet de pré-programmer des transi
 
 ## Pré-requis et installation
 
-Il faut avoir ffmpeg d'installé. Pour cela, il faut installer le paquet `libav-tools` :
+Il faut avoir ffmpeg d'installé. Pour cela, il faut installer le paquet `libav-tools` :
 
-    :::bash
+    ```
     sudo apt-get install libav-tools
+    ```
 
 Si vous utilisez la version compilée de Music Sampler, il n'y a rien d'autre à installer.
 
-Pour utiliser les sources directement, les modules suivants sont requis:
+Pour utiliser les sources directement, les modules suivants sont requis:
 
 | module      | version minimale | commentaire                      |
 | ----------- | ---------------- | -------------------------------- |
@@ -28,6 +29,11 @@ Pour utiliser les sources directement, les modules suivants sont requis:
 | transitions | 0.4.1            |                                  |
 | PyYAML      | 3.11             |                                  |
 
+- Le programme utilise les polices "Symbola" et "Ubuntu" (Regular / Bold), qui doivent être disponibles.
+
+    ```
+    sudo apt-get install ttf-ancient-fonts ttf-ubuntu-font-family
+    ```
 
 ## Version compilée
 
diff --git a/fonts/Symbola.ttf b/fonts/Symbola.ttf
deleted file mode 100644 (file)
index 51d9a88..0000000
Binary files a/fonts/Symbola.ttf and /dev/null differ
diff --git a/fonts/Ubuntu-B.ttf b/fonts/Ubuntu-B.ttf
deleted file mode 100644 (file)
index b173da2..0000000
Binary files a/fonts/Ubuntu-B.ttf and /dev/null differ
diff --git a/fonts/Ubuntu-Regular.ttf b/fonts/Ubuntu-Regular.ttf
deleted file mode 100644 (file)
index 45a038b..0000000
Binary files a/fonts/Ubuntu-Regular.ttf and /dev/null differ
index f1a968b298065dddfebe5c52649507fffd891111..4827e6c1af392acf8614008c1e1d9749e54a0190 100644 (file)
@@ -6,9 +6,43 @@ import math
 import sounddevice as sd
 import logging
 
+from . import sysfont
+
 class Config:
     pass
 
+def find_font(name, style=sysfont.STYLE_NONE):
+    if getattr(sys, 'frozen', False):
+        font = sys._MEIPASS + "/fonts/{}_{}.ttf".format(name, style)
+    else:
+        font = sysfont.get_font(name, style=style)
+        if font is not None:
+            font = font[4]
+    return font
+
+def register_fonts():
+    from kivy.core.text import LabelBase
+
+    ubuntu_regular = find_font("Ubuntu", style=sysfont.STYLE_NORMAL)
+    ubuntu_bold = find_font("Ubuntu", style=sysfont.STYLE_BOLD)
+    symbola = find_font("Symbola")
+
+    if ubuntu_regular is None:
+        error_print("Font Ubuntu regular could not be found, please install it.")
+        sys.exit()
+    if symbola is None:
+        error_print("Font Symbola could not be found, please install it.")
+        sys.exit()
+    if ubuntu_bold is None:
+        warn_print("Font Ubuntu Bold could not be found.")
+
+    LabelBase.register(name="Ubuntu",
+            fn_regular=ubuntu_regular,
+            fn_bold=ubuntu_bold)
+    LabelBase.register(name="Symbola",
+            fn_regular=symbola)
+
+
 def path():
     if getattr(sys, 'frozen', False):
         return sys._MEIPASS + "/"
diff --git a/helpers/sysfont.py b/helpers/sysfont.py
new file mode 100644 (file)
index 0000000..f47693e
--- /dev/null
@@ -0,0 +1,224 @@
+# This file was imported from
+# https://bitbucket.org/marcusva/python-utils/overview
+# And slightly adapted
+
+"""OS-specific font detection."""
+import os
+import sys
+from subprocess import Popen, PIPE
+
+if sys.platform in ("win32", "cli"):
+    import winreg
+
+__all__ = ["STYLE_NORMAL", "STYLE_BOLD", "STYLE_ITALIC", "STYLE_LIGHT",
+           "init", "list_fonts", "get_fonts", "get_font"
+           ]
+
+# Font cache entries:
+# { family : [...,
+#             (name, styles, fonttype, filename)
+#             ...
+#            ]
+# }
+__FONTCACHE = None
+
+
+STYLE_NONE   = 0x00
+STYLE_NORMAL = 0x01
+STYLE_BOLD   = 0x02
+STYLE_ITALIC = 0x04
+STYLE_LIGHT  = 0x08
+STYLE_MEDIUM = 0x10
+
+def _add_font(family, name, styles, fonttype, filename):
+    """Adds a font to the internal font cache."""
+    global __FONTCACHE
+
+    if family not in __FONTCACHE:
+        __FONTCACHE[family] = []
+    __FONTCACHE[family].append((name, styles, fonttype, filename))
+
+
+def _cache_fonts_win32():
+    """Caches fonts on a Win32 platform."""
+    key = "SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Fonts"
+    regfonts = []
+    try:
+        with winreg.OpenKey(winreg.HKEY_LOCAL_MACHINE, key) as fontkey:
+            idx = 0
+            enumval = winreg.EnumValue
+            rappend = regfonts.append
+            while True:
+                rappend(enumval(fontkey, idx)[:2])
+                idx += 1
+    except WindowsError:
+        pass
+
+    # TODO: integrate alias handling for fonts within the registry.
+    # TODO: Scan and index fonts from %SystemRoot%\\Fonts that are not in the
+    # registry
+
+    # Received all fonts from the registry.
+    for name, filename in regfonts:
+        fonttype = os.path.splitext(filename)[1][1:].lower()
+        if name.endswith("(TrueType)"):
+            name = name[:-10].strip()
+        if name.endswith("(All Res)"):
+            name = name[:-9].strip()
+        style = STYLE_NORMAL
+        if name.find(" Bold") >= 0:
+            style |= STYLE_BOLD
+        if name.find(" Italic") >= 0 or name.find(" Oblique") >= 0:
+            style |= STYLE_ITALIC
+
+        family = name
+        for rm in ("Bold", "Italic", "Oblique"):
+            family = family.replace(rm, "")
+        family = family.lower().strip()
+
+        fontpath = os.environ.get("SystemRoot", "C:\\Windows")
+        fontpath = os.path.join(fontpath, "Fonts")
+        if filename.find("\\") == -1:
+            # No path delimiter is given; we assume it to be a font in
+            # %SystemRoot%\Fonts
+            filename = os.path.join(fontpath, filename)
+        _add_font(family, name, style, fonttype, filename)
+
+
+def _cache_fonts_darwin():
+    """Caches fonts on Mac OS."""
+    raise NotImplementedError("Mac OS X support is not given yet")
+
+
+def _cache_fonts_fontconfig():
+    """Caches font on POSIX-alike platforms."""
+    try:
+        command = "fc-list : file family style fullname fullnamelang"
+        proc = Popen(command, stdout=PIPE, shell=True, stderr=PIPE)
+        pout = proc.communicate()[0]
+        output = pout.decode("utf-8")
+    except OSError:
+        return
+
+    for entry in output.split(os.linesep):
+        if entry.strip() == "":
+            continue
+        values = entry.split(":")
+        filename = values[0]
+
+        # get the font type
+        fname, fonttype = os.path.splitext(filename)
+        if fonttype == ".gz":
+            fonttype = os.path.splitext(fname)[1][1:].lower()
+        else:
+            fonttype = fonttype.lstrip(".").lower()
+
+        # get the font name
+        name = None
+        if len(values) > 3:
+            fullnames, fullnamelangs = values[3:]
+            langs = fullnamelangs.split(",")
+            try:
+                offset = langs.index("fullnamelang=en")
+            except ValueError:
+                offset = -1
+            if offset == -1:
+                try:
+                    offset = langs.index("en")
+                except ValueError:
+                    offset = -1
+            if offset != -1:
+                # got an english name, use that one
+                name = fullnames.split(",")[offset]
+                if name.startswith("fullname="):
+                    name = name[9:]
+        if name is None:
+            if fname.endswith(".pcf") or fname.endswith(".bdf"):
+                name = os.path.basename(fname[:-4])
+            else:
+                name = os.path.basename(fname)
+        name = name.lower()
+
+        # family and styles
+        family = values[1].strip().lower()
+        stylevals = values[2].strip()
+        style = STYLE_NONE
+
+        if stylevals.find("Bold") >= 0:
+            style |= STYLE_BOLD
+        if stylevals.find("Light") >= 0:
+            style |= STYLE_LIGHT
+        if stylevals.find("Italic") >= 0 or stylevals.find("Oblique") >= 0:
+            style |= STYLE_ITALIC
+        if stylevals.find("Medium") >= 0:
+            style |= STYLE_MEDIUM
+        if style == STYLE_NONE:
+            style = STYLE_NORMAL
+        _add_font(family, name, style, fonttype, filename)
+
+
+def init():
+    """Initialises the internal font cache.
+
+    It does not need to be called explicitly.
+    """
+    global __FONTCACHE
+    if __FONTCACHE is not None:
+        return
+    __FONTCACHE = {}
+    if sys.platform in ("win32", "cli"):
+        _cache_fonts_win32()
+    elif sys.platform == "darwin":
+        _cache_fonts_darwin()
+    else:
+        _cache_fonts_fontconfig()
+
+
+def list_fonts():
+    """Returns an iterator over the cached fonts."""
+    if __FONTCACHE is None:
+        init()
+    if len(__FONTCACHE) == 0:
+        yield None
+    for family, entries in __FONTCACHE.items():
+        for fname, styles, fonttype, filename in entries:
+            yield (family, fname, styles, fonttype, filename)
+
+
+def get_fonts(name, style=STYLE_NONE, ftype=None):
+    """Retrieves all fonts matching the given family or font name."""
+    if __FONTCACHE is None:
+        init()
+    if len(__FONTCACHE) == 0:
+        return None
+
+    results = []
+    rappend = results.append
+
+    name = name.lower()
+    if ftype:
+        ftype = ftype.lower()
+
+    fonts = __FONTCACHE.get(name, [])
+    for fname, fstyles, fonttype, filename in fonts:
+        if ftype and fonttype != ftype:
+            # ignore font filetype mismatches
+            continue
+        if style == STYLE_NONE or fstyles == style:
+            rappend((name, fname, fstyles, fonttype, filename))
+
+    for family, fonts in __FONTCACHE.items():
+        for fname, fstyles, fonttype, filename in fonts:
+            if fname.lower() == name and filename not in results:
+                rappend((family, fname, fstyles, fonttype, filename))
+    return results
+
+
+def get_font(name, style=STYLE_NONE, ftype=None):
+    """Retrieves the best matching font file for the given name and
+    criteria.
+    """
+    retvals = get_fonts(name, style, ftype)
+    if len(retvals) > 0:
+        return retvals[0]
+    return None
index fa3862724bd73c6e7a642d32be0048cfa545d1a3..a18eb4e5395c77aa0f0093f009aa0c0cbeb09aa1 100644 (file)
@@ -40,7 +40,8 @@
       width: self.line_width
   Label:
     id: key_label
-    font_name: h.path() + "fonts/Ubuntu-B.ttf"
+    font_name: "Ubuntu"
+    bold: True
     font_size: math.ceil(2 * math.sqrt(self.parent.parent.key_size))
     color: 0, 0, 0, 1
     text: self.parent.key_sym
@@ -52,7 +53,7 @@
     center_y: self.parent.y + self.parent.height - self.texture_size[1] /2 - 5
   Label:
     id: key_description_title
-    font_name: h.path() + "fonts/Ubuntu-Regular.ttf"
+    font_name: "Ubuntu"
     font_size: math.ceil(2 * math.sqrt(self.parent.parent.key_size / 2))
     color: 0, 0, 0, 1
     text: self.parent.description_title
@@ -63,7 +64,7 @@
     center_y: self.parent.y + self.parent.height - self.texture_size[1] /2 - 5
   Label:
     id: key_description
-    font_name: h.path() + "fonts/Ubuntu-Regular.ttf"
+    font_name: "Ubuntu"
     font_size: math.ceil(2 * math.sqrt(self.parent.parent.key_size / 2))
     color: 0, 0, 0, 1
     text: "\n".join(self.parent.description)
   ubuntu_bold_line_height: self.min_height / max(mock_ubuntu_bold.height,1)
   Label:
     id: mock_symbola
-    font_name: h.path() + "fonts/Symbola.ttf"
+    font_name: "Symbola"
     font_size: math.ceil(2 * math.sqrt(self.parent.key_size or 10))
     color: 0, 0, 0, 0
     text: "A"
     size: self.texture_size
   Label:
     id: mock_ubuntu_regular
-    font_name: h.path() + "fonts/Ubuntu-Regular.ttf"
+    font_name: "Ubuntu"
     font_size: math.ceil(2 * math.sqrt(self.parent.key_size or 10))
     color: 0, 0, 0, 0
     text: "A"
     size: self.texture_size
   Label:
     id: mock_ubuntu_bold
-    font_name: h.path() + "fonts/Ubuntu-B.ttf"
+    font_name: "Ubuntu"
+    bold: True
     font_size: math.ceil(2 * math.sqrt(self.parent.key_size or 10))
     color: 0, 0, 0, 0
     text: "A"
       size: self.width, self.height
   Label:
     id: key_list_first
-    font_name: h.path() + "fonts/Ubuntu-B.ttf"
+    font_name: "Ubuntu"
+    bold: True
     font_size: math.ceil(2 * math.sqrt(self.parent.parent.key_size or 10))
     color: 0, 0, 0, 1
     text: self.parent.first_key
     pos: 0, self.parent.height - self.height
   Label:
     id: key_list_second
-    font_name: h.path() + "fonts/Ubuntu-Regular.ttf"
+    font_name: "Ubuntu"
     font_size: math.ceil(2 * math.sqrt(self.parent.parent.key_size or 10))
     color: 0, 0, 0, 1
     text: self.parent.second_key
     pos: 0, self.parent.height - key_list_first.height - self.height
   Label:
     id: key_list_third
-    font_name: h.path() + "fonts/Ubuntu-Regular.ttf"
+    font_name: "Ubuntu"
     font_size: math.ceil(2 * math.sqrt(self.parent.parent.key_size or 10))
     color: 0, 0, 0, 0.75
     text: self.parent.third_key
     pos: 0, self.parent.height - key_list_first.height - key_list_second.height - self.height
   Label:
     id: key_list_rest
-    font_name: h.path() + "fonts/Ubuntu-Regular.ttf"
+    font_name: "Ubuntu"
     font_size: math.ceil(2 * math.sqrt(self.parent.parent.key_size or 10))
     color: 0, 0, 0, 0.5
     text: "\n".join(self.parent.keylist[3:])
 
   Label:
     id: action_list_title
-    font_name: h.path() + "fonts/Ubuntu-B.ttf"
+    font_name: "Ubuntu"
+    bold: True
     font_size: math.ceil(2 * math.sqrt(self.parent.parent.key_size or 10))
     color: 0, 0, 0, 1
     text: self.parent.action_title
     size: self.texture_size[0], self.parent.height
   Label:
     id: action_list_icons
-    font_name: h.path() + "fonts/Symbola.ttf"
+    font_name: "Symbola"
     font_size: math.ceil(2 * math.sqrt(self.parent.parent.key_size or 10))
     line_height: self.parent.parent.symbola_line_height or 1
     color: 0, 0, 0, 1
     size: self.texture_size[0], self.parent.height - 3 * self.line_height * self.font_size
   Label:
     id: action_list_names
-    font_name: h.path() + "fonts/Ubuntu-Regular.ttf"
+    font_name: "Ubuntu"
     font_size: math.ceil(2 * math.sqrt(self.parent.parent.key_size or 10))
     line_height: self.parent.parent.ubuntu_regular_line_height or 1
     color: 0, 0, 0, 1
 
   Label:
     id: playlist_icons
-    font_name: h.path() + "fonts/Symbola.ttf"
+    font_name: "Symbola"
     font_size: math.ceil(2 * math.sqrt(self.parent.parent.key_size or 10))
     line_height: self.parent.parent.symbola_line_height or 1
     color: 0, 0, 0, 1
     size: self.texture_size[0], self.parent.height
   Label:
     id: playlist_names
-    font_name: h.path() + "fonts/Ubuntu-Regular.ttf" # FIXME: Mettre en gras quand c'est en cours
+    font_name: "Ubuntu" # FIXME: Mettre en gras quand c'est en cours
     line_height: self.parent.parent.ubuntu_regular_line_height or 1
     font_size: math.ceil(2 * math.sqrt(self.parent.parent.key_size or 10))
     color: 0, 0, 0, 1
         pos:  self.pos
         size: self.width, self.height
     id: playlist_times
-    font_name: h.path() + "fonts/Ubuntu-Regular.ttf"
+    font_name: "Ubuntu"
     line_height: self.parent.parent.ubuntu_regular_line_height or 1
     font_size: math.ceil(2 * math.sqrt(self.parent.parent.key_size or 10))
     color: 0, 0, 0, 1
       pos: self.width - self.key_size / 2, self.height - self.key_size /2
       size: self.key_size / 3, self.key_size / 3
   Label:
-    font_name: h.path() + "fonts/Ubuntu-Regular.ttf"
+    font_name: "Ubuntu"
     font_size: math.ceil(2 * math.sqrt(self.parent.key_size or 10))
     color: 0, 0, 0, 1
     text: "volume: {}%".format(self.parent.master_volume)
index c10b6349701210a2ce583bb88543559a6fb0dd4f..f5df2bf0dd3191ac3438d2352a10f6ce0ef61476 100644 (file)
@@ -14,6 +14,8 @@ from kivy.lang import Builder
 from helpers.key import Key
 from helpers.mapping import Mapping
 
+helpers.register_fonts()
+
 class KeyList(RelativeLayout):
     keylist = ListProperty([])
     first_key = StringProperty("")
index 591a6cf0cae30da1e4e9ce8780db5cd9263bd938..0d99dca2caefcc67238169feeb09ab7fdcf94b1a 100644 (file)
@@ -3,6 +3,11 @@ import os
 from kivy.tools.packaging.pyinstaller_hooks import get_deps_minimal,\
         hookspath, runtime_hooks
 
+import importlib.machinery
+sysfont = importlib.machinery\
+        .SourceFileLoader('sysfont', os.getcwd() + '/helpers/sysfont.py') \
+        .load_module()
+
 excluded_and_hidden_modules = get_deps_minimal(
         video=None,
         camera=None,
@@ -22,16 +27,26 @@ pyinstaller_file = open(".pyinstaller_commit", "w")
 pyinstaller_file.write(commit_message)
 pyinstaller_file.close()
 
+data = [
+  ('music_sampler.kv', '.'),
+  ('.pyinstaller_commit', '.')
+]
+
 a = Analysis(['music_sampler.py'],
              binaries=None,
-             datas=[
-              ('fonts/*', 'fonts'),
-              ('music_sampler.kv', '.'),
-              ('.pyinstaller_commit', '.')
-             ],
+             datas=data,
              hookspath=hookspath(),
              runtime_hooks=runtime_hooks(),
              **excluded_and_hidden_modules)
+
+for fontname, style in [("Ubuntu", sysfont.STYLE_NORMAL), ("Ubuntu", sysfont.STYLE_BOLD), ("Symbola", sysfont.STYLE_NONE)]:
+    font = sysfont.get_font(fontname, style=style)
+    a.datas.append((
+        'fonts/{}_{}.ttf'.format(fontname, style),
+        font[4],
+        'DATA'
+        ))
+
 pyz = PYZ(a.pure, a.zipped_data)
 
 # Single file