Server IP : 127.0.0.2 / Your IP : 3.140.250.173 Web Server : Apache/2.4.18 (Ubuntu) System : User : www-data ( ) PHP Version : 7.0.33-0ubuntu0.16.04.16 Disable Function : disk_free_space,disk_total_space,diskfreespace,dl,exec,fpaththru,getmyuid,getmypid,highlight_file,ignore_user_abord,leak,listen,link,opcache_get_configuration,opcache_get_status,passthru,pcntl_alarm,pcntl_fork,pcntl_waitpid,pcntl_wait,pcntl_wifexited,pcntl_wifstopped,pcntl_wifsignaled,pcntl_wexitstatus,pcntl_wtermsig,pcntl_wstopsig,pcntl_signal,pcntl_signal_dispatch,pcntl_get_last_error,pcntl_strerror,pcntl_sigprocmask,pcntl_sigwaitinfo,pcntl_sigtimedwait,pcntl_exec,pcntl_getpriority,pcntl_setpriority,php_uname,phpinfo,posix_ctermid,posix_getcwd,posix_getegid,posix_geteuid,posix_getgid,posix_getgrgid,posix_getgrnam,posix_getgroups,posix_getlogin,posix_getpgid,posix_getpgrp,posix_getpid,posix,_getppid,posix_getpwnam,posix_getpwuid,posix_getrlimit,posix_getsid,posix_getuid,posix_isatty,posix_kill,posix_mkfifo,posix_setegid,posix_seteuid,posix_setgid,posix_setpgid,posix_setsid,posix_setuid,posix_times,posix_ttyname,posix_uname,pclose,popen,proc_open,proc_close,proc_get_status,proc_nice,proc_terminate,shell_exec,source,show_source,system,virtual MySQL : OFF | cURL : ON | WGET : ON | Perl : ON | Python : ON | Sudo : ON | Pkexec : ON Directory : /opt/odoo/odoo/addons/base/res/ |
Upload File : |
# -*- coding: utf-8 -*- # Part of Odoo. See LICENSE file for full copyright and licensing details. import logging from reportlab.pdfbase import ttfonts from odoo import api, fields, models from odoo.report.render.rml2pdf import customfonts """This module allows the mapping of some system-available TTF fonts to the reportlab engine. This file could be customized per distro (although most Linux/Unix ones) should have the same filenames, only need the code below). Due to an awful configuration that ships with reportlab at many Linux and Ubuntu distros, we have to override the search path, too. """ _logger = logging.getLogger(__name__) # Alternatives for the [broken] builtin PDF fonts. Default order chosen to match # the pre-v8 mapping from odoo.report.render.rml2pdf.customfonts.CustomTTFonts. # Format: [ (BuiltinFontFamily, mode, [AlternativeFontName, ...]), ...] BUILTIN_ALTERNATIVES = [ ('Helvetica', "normal", ["DejaVuSans", "LiberationSans"]), ('Helvetica', "bold", ["DejaVuSans-Bold", "LiberationSans-Bold"]), ('Helvetica', 'italic', ["DejaVuSans-Oblique", "LiberationSans-Italic"]), ('Helvetica', 'bolditalic', ["DejaVuSans-BoldOblique", "LiberationSans-BoldItalic"]), ('Times', 'normal', ["LiberationSerif", "DejaVuSerif"]), ('Times', 'bold', ["LiberationSerif-Bold", "DejaVuSerif-Bold"]), ('Times', 'italic', ["LiberationSerif-Italic", "DejaVuSerif-Italic"]), ('Times', 'bolditalic', ["LiberationSerif-BoldItalic", "DejaVuSerif-BoldItalic"]), ('Courier', 'normal', ["FreeMono", "DejaVuSansMono"]), ('Courier', 'bold', ["FreeMonoBold", "DejaVuSansMono-Bold"]), ('Courier', 'italic', ["FreeMonoOblique", "DejaVuSansMono-Oblique"]), ('Courier', 'bolditalic', ["FreeMonoBoldOblique", "DejaVuSansMono-BoldOblique"]), ] class ResFont(models.Model): _name = "res.font" _description = 'Fonts available' _order = 'family,name,id' _rec_name = 'family' family = fields.Char(string="Font family", required=True) name = fields.Char(string="Font Name", required=True) path = fields.Char(required=True) mode = fields.Char(required=True) _sql_constraints = [ ('name_font_uniq', 'unique(family, name)', 'You can not register two fonts with the same name'), ] @api.model def font_scan(self, lazy=False): """Action of loading fonts In lazy mode will scan the filesystem only if there is no founts in the database and sync if no font in CustomTTFonts In not lazy mode will force scan filesystem and sync """ if lazy: # lazy loading, scan only if no fonts in db fonts = self.search([('path', '!=', '/dev/null')]) if not fonts: # no scan yet or no font found on the system, scan the filesystem self._scan_disk() elif len(customfonts.CustomTTFonts) == 0: # CustomTTFonts list is empty self._sync() else: self._scan_disk() return True def _scan_disk(self): """Scan the file system and register the result in database""" found_fonts = [] for font_path in customfonts.list_all_sysfonts(): try: font = ttfonts.TTFontFile(font_path) _logger.debug("Found font %s at %s", font.name, font_path) found_fonts.append((font.familyName, font.name, font_path, font.styleName)) except Exception, ex: _logger.warning("Could not register Font %s: %s", font_path, ex) for family, name, path, mode in found_fonts: if not self.search([('family', '=', family), ('name', '=', name)]): self.create({'family': family, 'name': name, 'path': path, 'mode': mode}) # remove fonts not present on the disk anymore existing_font_names = [name for (family, name, path, mode) in found_fonts] # Remove inexistent fonts self.search([('name', 'not in', existing_font_names), ('path', '!=', '/dev/null')]).unlink() self.pool.signal_caches_change() return self._sync() def _sync(self): """Set the customfonts.CustomTTFonts list to the content of the database""" customfonts.CustomTTFonts = [] local_family_modes = set() local_font_paths = {} for font in self.search([('path', '!=', '/dev/null')]): local_family_modes.add((font.family, font.mode)) local_font_paths[font.name] = font.path customfonts.CustomTTFonts.append((font.family, font.name, font.path, font.mode)) # Attempt to remap the builtin fonts (Helvetica, Times, Courier) to better alternatives # if available, because they only support a very small subset of unicode # (missing 'č' for example) for builtin_font_family, mode, alts in BUILTIN_ALTERNATIVES: if (builtin_font_family, mode) not in local_family_modes: # No local font exists with that name, try alternatives for altern_font in alts: if local_font_paths.get(altern_font): altern_def = (builtin_font_family, altern_font, local_font_paths[altern_font], mode) customfonts.CustomTTFonts.append(altern_def) _logger.debug("Builtin remapping %r", altern_def) break else: _logger.warning("No local alternative found for builtin font `%s` (%s mode)." "Consider installing the DejaVu fonts if you have problems " "with unicode characters in RML reports", builtin_font_family, mode) return True @classmethod def clear_caches(cls): """Force worker to resync at next report loading by setting an empty font list""" customfonts.CustomTTFonts = [] return super(ResFont, cls).clear_caches()