def read_font_fule(self, basedir, css): from PyQt4.Qt import QFontDatabase import cssutils cssutils.log.setLevel(logging.ERROR) try: sheet = cssutils.parseString(css, validate=False) except: return for rule in sheet.cssRules: try: s = rule.style src = s.getProperty('src').propertyValue[0].uri font_family = s.getProperty('font-family').propertyValue[0].value except: continue if not src or not font_family: continue font_file = os.path.normcase(os.path.abspath(os.path.join(basedir, src))) if font_file not in self.added_fonts: self.added_fonts.add(font_file) if os.path.exists(font_file): with open(font_file, 'rb') as f: idx = QFontDatabase.addApplicationFontFromData(f.read()) if idx > -1: family = map(unicode, QFontDatabase.applicationFontFamilies(idx)).next() self.log('Extracted embedded font:', family, 'from', os.path.basename(font_file)) if (family and family != font_family and family not in self.replace_map): self.log('Replacing font family value:', font_family, 'with', family) self.replace_map[font_family.encode('utf-8')] = \ family.encode('utf-8')
def add_font(self, data): existing = None for font_id, entry in self.cache.iteritems(): if entry.size == len(data) and entry.hash == hash(data): existing = entry break if existing is None: font_id = QFontDatabase.addApplicationFontFromData(data) if font_id > -1: families = frozenset(map(lambda x:icu_lower(unicode(x)), QFontDatabase.applicationFontFamilies(font_id))) self.cache[font_id] = self.entry(len(data), hash(data), families)
def add_font(self, data): existing = None for font_id, entry in self.cache.iteritems(): if entry.size == len(data) and entry.hash == hash(data): existing = entry break if existing is None: font_id = QFontDatabase.addApplicationFontFromData(data) if font_id > -1: families = frozenset(map(lambda x:icu_lower(unicode(x)), QFontDatabase.applicationFontFamilies(font_id))) self.cache[font_id] = self.entry(len(data), hash(data), families)
def rating_font(): global _rating_font if _rating_font is None: from PyQt4.Qt import QFontDatabase _rating_font = 'Arial Unicode MS' if iswindows else 'sans-serif' fontid = QFontDatabase.addApplicationFont( #P('fonts/liberation/LiberationSerif-Regular.ttf') P('fonts/calibreSymbols.otf')) if fontid > -1: try: _rating_font = unicode( list(QFontDatabase.applicationFontFamilies(fontid))[0]) except: pass return _rating_font
def rating_font(): global _rating_font if _rating_font is None: from PyQt4.Qt import QFontDatabase _rating_font = 'Arial Unicode MS' if iswindows else 'sans-serif' fontid = QFontDatabase.addApplicationFont( #P('fonts/liberation/LiberationSerif-Regular.ttf') P('fonts/calibreSymbols.otf') ) if fontid > -1: try: _rating_font = unicode(list( QFontDatabase.applicationFontFamilies(fontid))[0]) except: pass return _rating_font
def load_builtin_fonts(): global _rating_font # Load the builtin fonts and any fonts added to calibre by the user to # Qt for ff in glob.glob(P('fonts/liberation/*.?tf')) + \ [P('fonts/calibreSymbols.otf')] + \ glob.glob(os.path.join(config_dir, 'fonts', '*.?tf')): if ff.rpartition('.')[-1].lower() in {'ttf', 'otf'}: with open(ff, 'rb') as s: # Windows requires font files to be executable for them to be # loaded successfully, so we use the in memory loader fid = QFontDatabase.addApplicationFontFromData(s.read()) if fid > -1: fam = QFontDatabase.applicationFontFamilies(fid) fam = set(map(unicode, fam)) if u'calibre Symbols' in fam: _rating_font = u'calibre Symbols'
def load_builtin_fonts(): global _rating_font # Load the builtin fonts and any fonts added to calibre by the user to # Qt for ff in glob.glob(P('fonts/liberation/*.?tf')) + \ [P('fonts/calibreSymbols.otf')] + \ glob.glob(os.path.join(config_dir, 'fonts', '*.?tf')): if ff.rpartition('.')[-1].lower() in {'ttf', 'otf'}: with open(ff, 'rb') as s: # Windows requires font files to be executable for them to be # loaded successfully, so we use the in memory loader fid = QFontDatabase.addApplicationFontFromData(s.read()) if fid > -1: fam = QFontDatabase.applicationFontFamilies(fid) fam = set(map(unicode, fam)) if u'calibre Symbols' in fam: _rating_font = u'calibre Symbols'
def load_builtin_fonts(): global _rating_font # Load the builtin fonts and any fonts added to calibre by the user to # Qt for ff in ( glob.glob(P("fonts/liberation/*.?tf")) + [P("fonts/calibreSymbols.otf")] + glob.glob(os.path.join(config_dir, "fonts", "*.?tf")) ): if ff.rpartition(".")[-1].lower() in {"ttf", "otf"}: with open(ff, "rb") as s: # Windows requires font files to be executable for them to be # loaded successfully, so we use the in memory loader fid = QFontDatabase.addApplicationFontFromData(s.read()) if fid > -1: fam = QFontDatabase.applicationFontFamilies(fid) fam = set(map(unicode, fam)) if u"calibre Symbols" in fam: _rating_font = u"calibre Symbols"
def read_font_fule(self, basedir, css): from PyQt4.Qt import QFontDatabase import cssutils cssutils.log.setLevel(logging.ERROR) try: sheet = cssutils.parseString(css, validate=False) except: return for rule in sheet.cssRules: try: s = rule.style src = s.getProperty('src').propertyValue[0].uri font_family = s.getProperty( 'font-family').propertyValue[0].value except: continue if not src or not font_family: continue font_file = os.path.normcase( os.path.abspath(os.path.join(basedir, src))) if font_file not in self.added_fonts: self.added_fonts.add(font_file) if os.path.exists(font_file): with open(font_file, 'rb') as f: idx = QFontDatabase.addApplicationFontFromData( f.read()) if idx > -1: family = map( unicode, QFontDatabase.applicationFontFamilies(idx)).next() self.log('Extracted embedded font:', family, 'from', os.path.basename(font_file)) if (family and family != font_family and family not in self.replace_map): self.log('Replacing font family value:', font_family, 'with', family) self.replace_map[font_family.encode('utf-8')] = \ family.encode('utf-8')
def handle_embedded_fonts(self): ''' Because of QtWebKit's inability to handle embedded fonts correctly, we remove the embedded fonts and make them available system wide instead. If you ever move to Qt WebKit 2.3+ then this will be unnecessary. ''' from calibre.ebooks.oeb.base import urlnormalize from calibre.utils.fonts.utils import remove_embed_restriction from PyQt4.Qt import QFontDatabase, QByteArray, QRawFont, QFont # First find all @font-face rules and remove them, adding the embedded # fonts to Qt family_map = {} for item in list(self.oeb.manifest): if not hasattr(item.data, 'cssRules'): continue remove = set() for i, rule in enumerate(item.data.cssRules): if rule.type == rule.FONT_FACE_RULE: remove.add(i) try: s = rule.style src = s.getProperty('src').propertyValue[0].uri font_family = s.getProperty( 'font-family').propertyValue[0].value except: continue path = item.abshref(src) ff = self.oeb.manifest.hrefs.get(urlnormalize(path), None) if ff is None: continue raw = ff.data self.oeb.manifest.remove(ff) try: raw = remove_embed_restriction(raw) except: continue fid = QFontDatabase.addApplicationFontFromData( QByteArray(raw)) family_name = None if fid > -1: try: family_name = unicode( QFontDatabase.applicationFontFamilies(fid)[0]) except (IndexError, KeyError): pass if family_name: family_map[icu_lower(font_family)] = family_name for i in sorted(remove, reverse=True): item.data.cssRules.pop(i) # Now map the font family name specified in the css to the actual # family name of the embedded font (they may be different in general). font_warnings = set() for item in self.oeb.manifest: if not hasattr(item.data, 'cssRules'): continue for i, rule in enumerate(item.data.cssRules): if rule.type != rule.STYLE_RULE: continue ff = rule.style.getProperty('font-family') if ff is None: continue val = ff.propertyValue for i in xrange(val.length): try: k = icu_lower(val[i].value) except (AttributeError, TypeError): val[i].value = k = 'times' if k in family_map: val[i].value = family_map[k] if iswindows: # On windows, Qt uses GDI which does not support OpenType # (CFF) fonts, so we need to nuke references to OpenType # fonts. Note that you could compile QT with configure # -directwrite, but that requires atleast Vista SP2 for i in xrange(val.length): family = val[i].value if family: f = QRawFont.fromFont(QFont(family)) if len(f.fontTable('head')) == 0: if family not in font_warnings: self.log.warn( 'Ignoring unsupported font: %s' % family) font_warnings.add(family) # Either a bitmap or (more likely) a CFF font val[i].value = 'times'
def handle_embedded_fonts(self): ''' Because of QtWebKit's inability to handle embedded fonts correctly, we remove the embedded fonts and make them available system wide instead. If you ever move to Qt WebKit 2.3+ then this will be unnecessary. ''' from calibre.ebooks.oeb.base import urlnormalize from calibre.utils.fonts.utils import remove_embed_restriction from PyQt4.Qt import QFontDatabase, QByteArray, QRawFont, QFont # First find all @font-face rules and remove them, adding the embedded # fonts to Qt family_map = {} for item in list(self.oeb.manifest): if not hasattr(item.data, 'cssRules'): continue remove = set() for i, rule in enumerate(item.data.cssRules): if rule.type == rule.FONT_FACE_RULE: remove.add(i) try: s = rule.style src = s.getProperty('src').propertyValue[0].uri font_family = s.getProperty('font-family').propertyValue[0].value except: continue path = item.abshref(src) ff = self.oeb.manifest.hrefs.get(urlnormalize(path), None) if ff is None: continue raw = ff.data self.oeb.manifest.remove(ff) try: raw = remove_embed_restriction(raw) except: continue fid = QFontDatabase.addApplicationFontFromData(QByteArray(raw)) family_name = None if fid > -1: try: family_name = unicode(QFontDatabase.applicationFontFamilies(fid)[0]) except (IndexError, KeyError): pass if family_name: family_map[icu_lower(font_family)] = family_name for i in sorted(remove, reverse=True): item.data.cssRules.pop(i) # Now map the font family name specified in the css to the actual # family name of the embedded font (they may be different in general). font_warnings = set() for item in self.oeb.manifest: if not hasattr(item.data, 'cssRules'): continue for i, rule in enumerate(item.data.cssRules): if rule.type != rule.STYLE_RULE: continue ff = rule.style.getProperty('font-family') if ff is None: continue val = ff.propertyValue for i in xrange(val.length): try: k = icu_lower(val[i].value) except (AttributeError, TypeError): val[i].value = k = 'times' if k in family_map: val[i].value = family_map[k] if iswindows: # On windows, Qt uses GDI which does not support OpenType # (CFF) fonts, so we need to nuke references to OpenType # fonts. Note that you could compile QT with configure # -directwrite, but that requires atleast Vista SP2 for i in xrange(val.length): family = val[i].value if family: f = QRawFont.fromFont(QFont(family)) if len(f.fontTable('head')) == 0: if family not in font_warnings: self.log.warn('Ignoring unsupported font: %s' %family) font_warnings.add(family) # Either a bitmap or (more likely) a CFF font val[i].value = 'times'