## 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 |
| ----------- | ---------------- | -------------------------------- |
| 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
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 + "/"
--- /dev/null
+# 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
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
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
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)
from helpers.key import Key
from helpers.mapping import Mapping
+helpers.register_fonts()
+
class KeyList(RelativeLayout):
keylist = ListProperty([])
first_key = StringProperty("")
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,
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