From eda37d12e6d3ce0f4b3c4f30564ee19894b8aa60 Mon Sep 17 00:00:00 2001 From: Martin Trigaux Date: Tue, 3 Dec 2013 16:17:53 +0100 Subject: [PATCH 01/14] [FIX] font: add columns for family, path and mode bzr revid: mat@openerp.com-20131203151753-ycz8pyp1eg382qps --- openerp/addons/base/res/res_company.py | 7 +-- openerp/addons/base/res/res_company_view.xml | 2 +- openerp/addons/base/res/res_font.py | 53 +++++++++----------- openerp/report/render/rml2pdf/customfonts.py | 6 +-- 4 files changed, 32 insertions(+), 36 deletions(-) diff --git a/openerp/addons/base/res/res_company.py b/openerp/addons/base/res/res_company.py index 6e74dbf1547..0f6d4bed133 100644 --- a/openerp/addons/base/res/res_company.py +++ b/openerp/addons/base/res/res_company.py @@ -298,8 +298,9 @@ class res_company(osv.osv): if res: return res[0] - font_obj.init_no_scan(cr, uid) - return font_obj.search(cr, uid, [('name', '=', 'Helvetica')], limit=1)[0] + font_obj.init_scan(cr, uid) + res = font_obj.search(cr, uid, [('name', '=', 'Helvetica')], limit=1) + return res and res[0] or False _header = """
@@ -396,7 +397,7 @@ class res_company(osv.osv): return {'value': {'rml_header': self._header_a4}} def act_discover_fonts(self, cr, uid, ids, context=None): - return self.pool.get("res.font").discover_fonts(cr, uid, ids, context) + return self.pool.get("res.font").init_scan(cr, uid, context) _defaults = { 'currency_id': _get_euro, diff --git a/openerp/addons/base/res/res_company_view.xml b/openerp/addons/base/res/res_company_view.xml index 3fccba944f9..aeced970f0e 100644 --- a/openerp/addons/base/res/res_company_view.xml +++ b/openerp/addons/base/res/res_company_view.xml @@ -85,7 +85,7 @@
""" @@ -348,13 +348,13 @@ class res_company(osv.osv): - + - + [[ company.logo or removeParentNode('image') ]] diff --git a/openerp/report/render/rml2pdf/customfonts.py b/openerp/report/render/rml2pdf/customfonts.py index a7138b269ee..82d14e0803b 100644 --- a/openerp/report/render/rml2pdf/customfonts.py +++ b/openerp/report/render/rml2pdf/customfonts.py @@ -94,7 +94,7 @@ def SetCustomFonts(rmldoc): """ for family, font, filename, mode in CustomTTFonts: if os.path.isabs(filename) and os.path.exists(filename): - rmldoc.setTTFontMapping(font, family, filename, mode) + rmldoc.setTTFontMapping(family, font, filename, mode) return True # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: From aac5c9d6eb8eb240f9eab654bcc44ff0bc51f469 Mon Sep 17 00:00:00 2001 From: Martin Trigaux Date: Mon, 9 Dec 2013 16:14:54 +0100 Subject: [PATCH 11/14] [IMP] font: better handeling of multiworker environement bzr revid: mat@openerp.com-20131209151454-5rylu5alldd3ixmh --- openerp/addons/base/base_data.xml | 20 ++++++ openerp/addons/base/res/res_company.py | 7 +- openerp/addons/base/res/res_font.py | 72 +++++++++----------- openerp/report/render/rml2pdf/customfonts.py | 7 -- openerp/report/render/rml2pdf/trml2pdf.py | 7 +- 5 files changed, 60 insertions(+), 53 deletions(-) diff --git a/openerp/addons/base/base_data.xml b/openerp/addons/base/base_data.xml index 6a47325db39..093a72c6406 100644 --- a/openerp/addons/base/base_data.xml +++ b/openerp/addons/base/base_data.xml @@ -91,5 +91,25 @@ Administrator + + + Helvetica + Helvetica + /dev/null + all + + + Times + Times + /dev/null + all + + + Courier + Courier + /dev/null + all + + diff --git a/openerp/addons/base/res/res_company.py b/openerp/addons/base/res/res_company.py index 0678223f3d2..b46492d28d7 100644 --- a/openerp/addons/base/res/res_company.py +++ b/openerp/addons/base/res/res_company.py @@ -297,12 +297,7 @@ class res_company(osv.osv): def _get_font(self, cr, uid, ids): font_obj = self.pool.get('res.font') res = font_obj.search(cr, uid, [('family', '=', 'Helvetica'), ('mode', '=', 'all')], limit=1) - if res: - return res[0] - # not even the basic pdf fonts, initiate the db - font_obj._base_populate_font(cr, uid) - res = font_obj.search(cr, uid, [('family', '=', 'Helvetica'), ('mode', '=', 'all')], limit=1) - return res and res[0] or False + return res and res[0] or False _header = """
diff --git a/openerp/addons/base/res/res_font.py b/openerp/addons/base/res/res_font.py index a8ea2fe8cf8..cf437b5eae8 100644 --- a/openerp/addons/base/res/res_font.py +++ b/openerp/addons/base/res/res_font.py @@ -40,7 +40,7 @@ _logger = logging.getLogger(__name__) class res_font(osv.Model): _name = "res.font" _description = 'Fonts available' - _order = 'name,family,id' + _order = 'family,name,id' _rec_name = 'family' _columns = { @@ -54,65 +54,61 @@ class res_font(osv.Model): ('name_font_uniq', 'unique(family, name)', 'You can not register two fonts with the same name'), ] - def _base_populate_font(self, cr, uid, context=None): - if not self.search(cr, uid, [('path', '=', '/dev/null')], context=context): - # populate db with basic pdf fonts - for family, name, path, mode in customfonts.BasePDFFonts: - self.create(cr, uid, { - 'family': family, 'name': name, - 'path': path, 'mode': mode, - }, context=context) - return True - def font_scan(self, cr, uid, lazy=False, context=None): + """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 found_fonts_ids = self.search(cr, uid, [('path', '!=', '/dev/null')], context=context) if not found_fonts_ids: # no scan yet or no font found on the system, scan the filesystem - self._discover_fonts(cr, uid, context=context) - self._register_fonts(cr, uid, context=context) - else: - if len(customfonts.CustomTTFonts) == 0: - # CustomTTFonts list is empty - for font in self.browse(cr, uid, found_fonts_ids, context=context): - customfonts.CustomTTFonts.append((font.family, font.name, font.path, font.mode)) + self._scan_disk(cr, uid, context=context) + elif len(customfonts.CustomTTFonts) == 0: + # CustomTTFonts list is empty + self._sync(cr, uid, context=context) else: - self._discover_fonts(cr, uid, context=context) - self._register_fonts(cr, uid, context=context) + self._scan_disk(cr, uid, context=context) return True - def _discover_fonts(self, cr, uid, context=None): - """Scan fonts on the file system, add them to the list of known fonts - and create font object for the new ones""" - customfonts.CustomTTFonts = [] - - found_fonts = {} + def _scan_disk(self, cr, uid, context=None): + """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) - if not found_fonts.get(font.familyName): - found_fonts[font.familyName] = {'name': font.familyName} - - mode = font.styleName.lower().replace(" ", "") - - customfonts.CustomTTFonts.append((font.familyName, font.name, font_path, mode)) + found_fonts.append((font.familyName, font.name, font_path, font.styleName)) except ttfonts.TTFError: _logger.warning("Could not register Font %s", font_path) - def _register_fonts(self, cr, uid, context=None): - # add new custom fonts - for family, name, path, mode in customfonts.CustomTTFonts: + for family, name, path, mode in found_fonts: if not self.search(cr, uid, [('family', '=', family), ('name', '=', name)], context=context): self.create(cr, uid, { 'family': family, 'name': name, 'path': path, 'mode': mode, }, context=context) - # remove fonts not present on disk - existing_font_names = [name for (family, name, path, mode) in customfonts.CustomTTFonts] + # remove fonts not present on the disk anymore + existing_font_names = [name for (family, name, path, mode) in found_fonts] inexistant_fonts = self.search(cr, uid, [('name', 'not in', existing_font_names), ('path', '!=', '/dev/null')], context=context) if inexistant_fonts: - return self.unlink(cr, uid, inexistant_fonts, context=context) + self.unlink(cr, uid, inexistant_fonts, context=context) + + self.clear_caches() + self._sync(cr, uid, context=context) return True + + def _sync(self, cr, uid, context=None): + """Set the customfonts.CustomTTFonts list to the content of the database""" + customfonts.CustomTTFonts = [] + found_fonts_ids = self.search(cr, uid, [('path', '!=', '/dev/null')], context=context) + for font in self.browse(cr, uid, found_fonts_ids, context=None): + customfonts.CustomTTFonts.append((font.family, font.name, font.path, font.mode)) + return True + + def clear_caches(self): + """Force worker to resync at next report loading by setting an empty font list""" + customfonts.CustomTTFonts = [] + return super(res_font, self).clear_caches() \ No newline at end of file diff --git a/openerp/report/render/rml2pdf/customfonts.py b/openerp/report/render/rml2pdf/customfonts.py index 82d14e0803b..a54359b4f0b 100644 --- a/openerp/report/render/rml2pdf/customfonts.py +++ b/openerp/report/render/rml2pdf/customfonts.py @@ -38,13 +38,6 @@ and Ubuntu distros, we have to override the search path, too. """ _logger = logging.getLogger(__name__) -# Basic fonts family included in PDF standart, will always be in the font list -BasePDFFonts = [ - ('Helvetica', 'Helvetica', '/dev/null', 'all'), - ('Times', 'Times', '/dev/null', 'all'), - ('Courier', 'Courier', '/dev/null', 'all'), -] - CustomTTFonts = [] # Search path for TTF files, in addition of rl_config.TTFSearchPath diff --git a/openerp/report/render/rml2pdf/trml2pdf.py b/openerp/report/render/rml2pdf/trml2pdf.py index b075b0f53ea..20da1a48db6 100644 --- a/openerp/report/render/rml2pdf/trml2pdf.py +++ b/openerp/report/render/rml2pdf/trml2pdf.py @@ -56,8 +56,11 @@ def select_fontname(fontname, default_fontname): try: pdfmetrics.getFont(fontname) except Exception: - _logger.warning('Could not locate font %s, substituting default: %s', - fontname, default_fontname) + addition = "" + if " " in fontname: + addition = ". Your font contains spaces which is not valid in RML." + _logger.warning('Could not locate font %s, substituting default: %s%s', + fontname, default_fontname, addition) fontname = default_fontname return fontname From b37d3b79899c60f3e605952d2e8965bfb3e6d458 Mon Sep 17 00:00:00 2001 From: Martin Trigaux Date: Mon, 9 Dec 2013 16:38:42 +0100 Subject: [PATCH 12/14] [FIX] font: trigger signal for clear cache instead on self bzr revid: mat@openerp.com-20131209153842-l13zfc24at7cfisc --- openerp/addons/base/res/res_font.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/openerp/addons/base/res/res_font.py b/openerp/addons/base/res/res_font.py index cf437b5eae8..7fab654c6d6 100644 --- a/openerp/addons/base/res/res_font.py +++ b/openerp/addons/base/res/res_font.py @@ -20,6 +20,7 @@ ############################################################################## from reportlab.pdfbase import ttfonts +from openerp.modules.registry import RegistryManager from openerp.osv import fields, osv from openerp.report.render.rml2pdf import customfonts @@ -74,7 +75,7 @@ class res_font(osv.Model): def _scan_disk(self, cr, uid, context=None): """Scan the file system and register the result in database""" - found_fonts = [] + found_fonts = [] for font_path in customfonts.list_all_sysfonts(): try: font = ttfonts.TTFontFile(font_path) @@ -96,7 +97,7 @@ class res_font(osv.Model): if inexistant_fonts: self.unlink(cr, uid, inexistant_fonts, context=context) - self.clear_caches() + RegistryManager.signal_caches_change(cr.dbname) self._sync(cr, uid, context=context) return True From b48b746dd14e71f7cac6575fa908894fc5a258e3 Mon Sep 17 00:00:00 2001 From: Martin Trigaux Date: Mon, 9 Dec 2013 16:45:37 +0100 Subject: [PATCH 13/14] [IMP] fix licence bzr revid: mat@openerp.com-20131209154537-r5hpcveuxmvcdj10 --- openerp/addons/base/res/res_font.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openerp/addons/base/res/res_font.py b/openerp/addons/base/res/res_font.py index 7fab654c6d6..306a8944783 100644 --- a/openerp/addons/base/res/res_font.py +++ b/openerp/addons/base/res/res_font.py @@ -2,7 +2,7 @@ ############################################################################## # # OpenERP, Open Source Management Solution -# Copyright (C) 2004-2009 Tiny SPRL (). +# Copyright (C) 2013 OpenERP SA (). # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU Affero General Public License as From efdfcfc90e016fc1c912db4598428cc2eabea893 Mon Sep 17 00:00:00 2001 From: Martin Trigaux Date: Mon, 9 Dec 2013 16:57:02 +0100 Subject: [PATCH 14/14] [FIX] font: family with one l (Familly is a commune in the Calvados department in the Basse-Normandie region in northwestern France.) bzr revid: mat@openerp.com-20131209155702-negir6agbiugfctz --- openerp/addons/base/base_data.xml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/openerp/addons/base/base_data.xml b/openerp/addons/base/base_data.xml index 093a72c6406..bd38f3a3db5 100644 --- a/openerp/addons/base/base_data.xml +++ b/openerp/addons/base/base_data.xml @@ -94,19 +94,19 @@ Administrator Helvetica - Helvetica + Helvetica /dev/null all Times - Times + Times /dev/null all Courier - Courier + Courier /dev/null all