def setupTextActions(self): tb = QToolBar(self) tb.setWindowTitle("Format Actions") self.addToolBar(tb) tb = QToolBar(self) tb.setAllowedAreas(Qt.TopToolBarArea | Qt.BottomToolBarArea) tb.setWindowTitle("Format Actions") self.addToolBarBreak(Qt.TopToolBarArea) self.addToolBar(tb) self.comboFont = QFontComboBox(tb) tb.addWidget(self.comboFont) self.comboFont.activated[str].connect(self.textFamily) self.comboSize = QComboBox(tb) self.comboSize.setObjectName("comboSize") tb.addWidget(self.comboSize) self.comboSize.setEditable(True) db = QFontDatabase() for size in db.standardSizes(): self.comboSize.addItem('{}'.format(size)) self.comboSize.activated[str].connect(self.textSize) self.comboSize.setCurrentIndex(self.comboSize.findText('{}'.format(QApplication.font().pointSize())))
def main(): app = QtWidgets.QApplication(sys.argv) fontDB = QFontDatabase() fontDB.applicationFontFamilies( fontDB.addApplicationFont(":/res/Harmattan.ttf")) application = AppWindowByHaies() application.show() app.exec_()
def load_fonts(self, lrf, load_substitutions=True): font_map = {} for font in lrf.font_map: fdata = QByteArray(lrf.font_map[font].data) id = QFontDatabase.addApplicationFontFromData(fdata) if id != -1: font_map[font] = [str(i) for i in QFontDatabase.applicationFontFamilies(id)][0] if load_substitutions: base = P('fonts/liberation/*.ttf') for f in glob.glob(base): QFontDatabase.addApplicationFont(f) self.font_loader = FontLoader(font_map, self.dpi)
def on_bridge_ready(self): f = QApplication.instance().font() fi = QFontInfo(f) family = f.family() if family in ('.AppleSystemUIFont', 'MS Shell Dlg 2'): family = 'system-ui' ui_data = { 'all_font_families': QFontDatabase().families(), 'ui_font_family': family, 'ui_font_sz': '{}px'.format(fi.pixelSize()), 'show_home_page_on_ready': self.show_home_page_on_ready, 'system_colors': system_colors(), 'QT_VERSION': QT_VERSION, 'short_time_fmt': QLocale.system().timeFormat(QLocale.FormatType.ShortFormat), } self.bridge.create_view(vprefs['session_data'], vprefs['local_storage'], field_metadata.all_metadata(), ui_data) for func, args in iteritems(self.pending_bridge_ready_actions): getattr(self.bridge, func)(*args)
def on_bridge_ready(self): f = QApplication.instance().font() self.bridge.create_view( vprefs['session_data'], QFontDatabase().families(), field_metadata.all_metadata(), f.family(), f.pointSize()) for func, args in iteritems(self.pending_bridge_ready_actions): getattr(self.bridge, func)(*args)
def do_paint(self, painter, option, index): text = str(index.data(Qt.DisplayRole) or '') font = QFont(option.font) font.setPointSize(QFontInfo(font).pointSize() * 1.5) font2 = QFont(font) font2.setFamily(text) system, has_latin = writing_system_for_font(font2) if has_latin: font = font2 r = option.rect if option.state & QStyle.State_Selected: painter.setPen(QPen(option.palette.highlightedText(), 0)) if (option.direction == Qt.RightToLeft): r.setRight(r.right() - 4) else: r.setLeft(r.left() + 4) painter.setFont(font) painter.drawText(r, Qt.AlignVCenter|Qt.AlignLeading|Qt.TextSingleLine, text) if (system != QFontDatabase.Any): w = painter.fontMetrics().width(text + " ") painter.setFont(font2) sample = QFontDatabase().writingSystemSample(system) if (option.direction == Qt.RightToLeft): r.setRight(r.right() - w) else: r.setLeft(r.left() + w) painter.drawText(r, Qt.AlignVCenter|Qt.AlignLeading|Qt.TextSingleLine, sample)
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 on_bridge_ready(self): f = QApplication.instance().font() fi = QFontInfo(f) self.bridge.create_view( vprefs['session_data'], vprefs['local_storage'], QFontDatabase().families(), field_metadata.all_metadata(), f.family(), '{}px'.format(fi.pixelSize()), self.show_home_page_on_ready) for func, args in iteritems(self.pending_bridge_ready_actions): getattr(self.bridge, func)(*args)
def apply_theme(app): app.setStyle('Fusion') # Font font_database = QFontDatabase() font_database.addApplicationFont('source/ui/noto.ttf') app.setFont(QFont('Noto Sans CJK TC Regular', weight=QFont.Normal)) # QSS with open('source/ui/style.qss') as stylesheet: app.setStyleSheet(stylesheet.read()) # palette new_palette = QPalette() # base new_palette.setColor(QPalette.WindowText, QColor('#ABAEB0')) new_palette.setColor(QPalette.Button, QColor('#262f36')) new_palette.setColor(QPalette.Light, QColor('#D5D6D7')) new_palette.setColor(QPalette.Midlight, QColor('#05796E')) new_palette.setColor(QPalette.Dark, QColor('#1E272E')) new_palette.setColor(QPalette.Text, QColor('#ABAEB0')) new_palette.setColor(QPalette.BrightText, QColor('#e6e6e6')) new_palette.setColor(QPalette.ButtonText, QColor('#ABAEB0')) new_palette.setColor(QPalette.Base, QColor('#384047')) new_palette.setColor(QPalette.Window, QColor('#2B343B')) new_palette.setColor(QPalette.Shadow, QColor('#181F24')) new_palette.setColor(QPalette.Highlight, QColor('#07A092')) new_palette.setColor(QPalette.HighlightedText, QColor('#e6e6e6')) new_palette.setColor(QPalette.Link, QColor('#07A092')) new_palette.setColor(QPalette.AlternateBase, QColor('#262f36')) new_palette.setColor(QPalette.ToolTipBase, QColor(53, 53, 53)) new_palette.setColor(QPalette.ToolTipText, QColor('#828588')) # disabled new_palette.setColor(QPalette.Disabled, QPalette.WindowText, QColor(127, 127, 127)) new_palette.setColor(QPalette.Disabled, QPalette.Text, QColor(127, 127, 127)) new_palette.setColor(QPalette.Disabled, QPalette.ButtonText, QColor(127, 127, 127)) new_palette.setColor(QPalette.Disabled, QPalette.Highlight, QColor(80, 80, 80)) new_palette.setColor(QPalette.Disabled, QPalette.HighlightedText, QColor(127, 127, 127)) app.setPalette(new_palette)
def __init__(self, parent=None): super(CodeEditor, self).__init__(parent) self.setFont(QFontDatabase.systemFont(QFontDatabase.FixedFont)) self.line_number_area = LineNumberArea(self) self.blockCountChanged.connect(self.update) self.updateRequest.connect(self.updateLineNumberArea) self.cursorPositionChanged.connect(self.highlightCurrentLine) self.updateLineNumberAreaWidth(0) self.highlightCurrentLine()
def __init__(self, parent): QAbstractItemModel.__init__(self, parent) self.rules = () self.sort_on_count = True self.num_size = 1 self.num_unused = 0 self.build_maps() self.main_font = f = QFontDatabase.systemFont(QFontDatabase.FixedFont) f.setBold(True), f.setPointSize(parent.font().pointSize() + 2) self.italic_font = f = QFont(parent.font()) f.setItalic(True)
def default_font_family(): global _dff if _dff is None: families = set(map(unicode, QFontDatabase().families())) for x in ('Ubuntu Mono', 'Consolas', 'Liberation Mono'): if x in families: _dff = x break if _dff is None: _dff = 'Courier New' return _dff
def test_qt(self): from PyQt5.Qt import QImageReader, QNetworkAccessManager, QFontDatabase from calibre.utils.img import image_from_data, image_to_data, test # Ensure that images can be read before QApplication is constructed. # Note that this requires QCoreApplication.libraryPaths() to return the # path to the Qt plugins which it always does in the frozen build, # because the QT_PLUGIN_PATH env var is set. On non-frozen builds, # it should just work because the hard-coded paths of the Qt # installation should work. If they do not, then it is a distro # problem. fmts = set( map(lambda x: x.data().decode('utf-8'), QImageReader.supportedImageFormats())) testf = {'jpg', 'png', 'svg', 'ico', 'gif'} self.assertEqual( testf.intersection(fmts), testf, "Qt doesn't seem to be able to load some of its image plugins. Available plugins: %s" % fmts) data = P('images/blank.png', allow_user_override=False, data=True) img = image_from_data(data) image_from_data( P('catalog/mastheadImage.gif', allow_user_override=False, data=True)) for fmt in 'png bmp jpeg'.split(): d = image_to_data(img, fmt=fmt) image_from_data(d) # Run the imaging tests test() from calibre.gui2 import Application os.environ.pop('DISPLAY', None) has_headless = isosx or islinux app = Application([], headless=has_headless) self.assertGreaterEqual( len(QFontDatabase().families()), 5, 'The QPA headless plugin is not able to locate enough system fonts via fontconfig' ) if has_headless: from calibre.ebooks.covers import create_cover create_cover('xxx', ['yyy']) na = QNetworkAccessManager() self.assertTrue(hasattr(na, 'sslErrors'), 'Qt not compiled with openssl') from PyQt5.QtWebKitWidgets import QWebView if iswindows: from PyQt5.Qt import QtWin QtWin QWebView() del QWebView del na del app
def __init__(self, str, owner: LabeledObject, owner_widget: GraphItem, parent=None, flags=Qt.WindowFlags()): super().__init__(str, parent=parent, flags=flags) self.__owner = owner self.__owner_widget = owner_widget font_database = QFontDatabase() # Build absolute path to prevent problems on macOS path = os.path.join(os.path.dirname(__file__), "../ressources/fonts/lmroman8-regular.otf") font_id = font_database.addApplicationFont(path) if (font_id == -1): raise IOError("Font could not be loaded") font_name = QFontDatabase.applicationFontFamilies(font_id)[0] font = QFont(font_name, 16) self.setFont(font) self.adjustSize() self.__reposition()
def writing_system_for_font(font): has_latin = True systems = QFontDatabase().writingSystems(font.family()) # this just confuses the algorithm below. Vietnamese is Latin with lots of # special chars try: systems.remove(QFontDatabase.Vietnamese) except ValueError: pass system = QFontDatabase.Any if (QFontDatabase.Latin not in systems): has_latin = False # we need to show something if systems: system = systems[-1] else: systems.remove(QFontDatabase.Latin) if not systems: return system, has_latin if (len(systems) == 1 and systems[0] > QFontDatabase.Cyrillic): return systems[0], has_latin if (len(systems) <= 2 and systems[-1] > QFontDatabase.Armenian and systems[-1] < QFontDatabase.Vietnamese): return systems[-1], has_latin if (len(systems) <= 5 and systems[-1] >= QFontDatabase.SimplifiedChinese and systems[-1] <= QFontDatabase.Korean): system = systems[-1] return system, has_latin
def on_bridge_ready(self): f = QApplication.instance().font() fi = QFontInfo(f) ui_data = { 'all_font_families': QFontDatabase().families(), 'ui_font_family': f.family(), 'ui_font_sz': '{}px'.format(fi.pixelSize()), 'show_home_page_on_ready': self.show_home_page_on_ready, 'system_colors': system_colors(), } self.bridge.create_view(vprefs['session_data'], vprefs['local_storage'], field_metadata.all_metadata(), ui_data) for func, args in iteritems(self.pending_bridge_ready_actions): getattr(self.bridge, func)(*args)
def load(): Storage.DATABASE = QFontDatabase() if not Storage.USER_PREFERENCES_DIR.exists(): Storage.USER_PREFERENCES_DIR.mkdir() Storage.load_page_data() Storage.SOUNDS = { "tap": QSound( Storage.resolve_audio( "navigation_forward-selection-minimal.wav")) } if Storage.USER_DATA_FILE.exists(): with open(Storage.USER_DATA_FILE, "r") as file: Storage.USER_DATA = msgpack.load(file)
def test_qt(): from calibre.gui2 import Application from PyQt5.Qt import (QImageReader, QNetworkAccessManager, QFontDatabase) from PyQt5.QtWebKitWidgets import QWebView os.environ.pop('DISPLAY', None) app = Application([], headless=islinux) if len(QFontDatabase().families()) < 5: raise RuntimeError('The QPA headless plugin is not able to locate enough system fonts via fontconfig') fmts = set(map(unicode, QImageReader.supportedImageFormats())) testf = set(['jpg', 'png', 'mng', 'svg', 'ico', 'gif']) if testf.intersection(fmts) != testf: raise RuntimeError( "Qt doesn't seem to be able to load its image plugins") QWebView() del QWebView na = QNetworkAccessManager() if not hasattr(na, 'sslErrors'): raise RuntimeError('Qt not compiled with openssl') del na del app print ('Qt OK!')
def writing_system_for_font(font): has_latin = True systems = QFontDatabase().writingSystems(font.family()) # this just confuses the algorithm below. Vietnamese is Latin with lots of # special chars try: systems.remove(QFontDatabase.WritingSystem.Vietnamese) except ValueError: pass system = QFontDatabase.WritingSystem.Any if (QFontDatabase.WritingSystem.Latin not in systems): has_latin = False # we need to show something if systems: system = systems[-1] else: systems.remove(QFontDatabase.WritingSystem.Latin) if not systems: return system, has_latin if (len(systems) == 1 and systems[0] > QFontDatabase.WritingSystem.Cyrillic): return systems[0], has_latin if (len(systems) <= 2 and systems[-1] > QFontDatabase.WritingSystem.Armenian and systems[-1] < QFontDatabase.WritingSystem.Vietnamese): return systems[-1], has_latin if (len(systems) <= 5 and systems[-1] >= QFontDatabase.WritingSystem.SimplifiedChinese and systems[-1] <= QFontDatabase.WritingSystem.Korean): system = systems[-1] return system, has_latin
def __init__(self, parent=None): QTextEdit.__init__(self, parent) self.setFont(QFontDatabase.systemFont(QFontDatabase.FixedFont)) self.setReadOnly(True)
def __init__(self, master_password=None, urls=(), new_instance=False, shutdown=False, restart_state=None, no_session=False, run_local_server=True): if not isosx: # OS X turns this on automatically for v in ('QT_AUTO_SCREEN_SCALE_FACTOR', 'QT_SCALE_FACTOR', 'QT_SCREEN_SCALE_FACTORS', 'QT_DEVICE_PIXEL_RATIO'): if os.environ.get(v): break else: QApplication.setAttribute(Qt.AA_EnableHighDpiScaling, True) QApplication.__init__(self, [appname, '-name', appname]) self.setAttribute(Qt.AA_UseHighDpiPixmaps) self.setOrganizationName('kovidgoyal') self.setApplicationName(appname) self.setApplicationVersion(str_version) self.no_session = no_session self.handle_unix_signals() if not QSslSocket.supportsSsl(): raise SystemExit('Qt has been compiled without SSL support!') from .config import font_families, font_sizes ff = font_families().get('sans-serif') or 'default' if ff == 'default': ff = font_families().get('default') or 'default' f = self.font() if ff != 'default': f.setFamily(ff) fs = font_sizes().get('default-size') try: f.setPixelSize(int(fs)) except Exception: pass self.setFont(f) self.password_loaded.connect(self.on_password_load, type=Qt.QueuedConnection) if master_password is not None: password_db.start_load(master_password, self.password_loaded.emit) elif restart_state and 'key' in restart_state: password_db.start_load(restart_state.pop('key'), self.password_loaded.emit, pw_is_key=True) self.lastWindowClosed.connect(self.shutdown) if run_local_server: self.run_local_server(urls, new_instance, shutdown) sys.excepthook = self.on_unhandled_error self.windows = [] f = self.font() if (f.family(), f.pointSize()) == ( 'Sans Serif', 9): # Hard coded Qt settings, no user preference detected f.setPointSize(10) if 'Ubuntu' in QFontDatabase().families(): f.setFamily('Ubuntu') self.setFont(f) self.downloads = Downloads(self) self.disk_cache = create_favicon_cache() self.key_filter = KeyFilter(self) self.installEventFilter(self.key_filter)
def __init__(self, argv): # noqa 901 super(MainApplication, self).__init__(argv) self._isPrivate = False self._isPortable = True self._isClosing = False self._isStartingAfterCrash = False self._history = None # History self._bookmarks = None # Bookmarks self._autoFill = None # AutoFill self._cookieJar = None # CookieJar self._plugins = None # PluginProxy self._browsingLibrary = None # BrowsingLibrary self._networkManager = None self._restoreManager = None self._sessionManager = None self._downloadManager = None self._userAgentManager = None self._searchEnginesManager = None self._closedWindowsManager = None self._protocolHandlerManager = None self._html5PermissionsManager = None self._desktopNotifications = None # DesktopNotificationsFactory self._webProfile = None # QWebEngineProfile self._autoSaver = None self._proxyStyle = None self._wmClass = QByteArray() self._windows = [] self._lastActiveWindow = None self._postLaunchActions = [] self.setAttribute(Qt.AA_UseHighDpiPixmaps) self.setAttribute(Qt.AA_DontCreateNativeWidgetSiblings) self.setApplicationName('demo') self.setOrganizationDomain('org.autowin') self.setWindowIcon(QIcon.fromTheme('demo', QIcon(':/icons/demo.svg'))) self.setDesktopFileName('orig.autowin.demo') self.setApplicationVersion('1.0') # Set fallback icon theme (eg. on Windows/Mac) if QIcon.fromTheme('view-refresh').isNull(): QIcon.setThemeName('breeze-fallback') # QSQLITE database plugin is required if not QSqlDatabase.isDriverAvailable('QSQLITE'): QMessageBox.Critical( None, 'Error', 'Qt SQLite database plugin is not available.' ' Please install it and restart the application.') self._isClosing = True return if const.OS_WIN: # Set default app font (needed for N'ko) fontId = QFontDatabase.addApplicationFont('font.ttf') if fontId != -1: families = QFontDatabase.applicationFontFamilies(fontId) if not families.empty(): self.setFont(QFont(families.at(0))) startUrl = QUrl() startProfile = '' messages = [] noAddons = False newInstance = False if len(argv) > 1: cmd = CommandLineOptions() for pair in cmd.getActions(): action = pair.action text = pair.text if action == const.CL_StartWithoutAddons: noAddons = True elif action == const.CL_StartWithProfile: startProfile = text elif action == const.CL_StartPortable: self._isPortable = True elif action == const.CL_NewTab: messages.append("ACTION:NewTab") self._postLaunchActions.append(self.OpenNewTab) elif action == const.CL_NewWindow: messages.append("ACTION:NewWindow") elif action == const.CL_ToggleFullScreen: messages.append("ACTION:ToggleFullScreen") self._postLaunchActions.append(self.ToggleFullScreen) elif action == const.CL_ShowDownloadManager: messages.append("ACTION:ShowDownloadManager") self._postLaunchActions.append(self.OpenDownloadManager) elif action == const.CL_StartPrivateBrowsing: self._isPrivate = True elif action == const.CL_StartNewInstance: newInstance = True elif action == const.CL_OpenUrlInCurrentTab: startUrl = QUrl.fromUserInput(text) messages.append("ACTION:OpenUrlInCurrentTab" + text) elif action == const.CL_OpenUrlInNewWindow: startUrl = QUrl.fromUserInput(text) messages.append("ACTION:OpenUrlInNewWindow" + text) elif action == const.CL_OpenUrl: startUrl = QUrl.fromUserInput(text) messages.append("URL:" + text) elif action == const.CL_ExitAction: self._isClosing = True return elif action == const.CL_WMClass: self._wmClass = text if not self.isPortable(): appConf = QSettings( pathjoin(self.applicationDirPath(), '%s.conf' % const.APPNAME), QSettings.IniFormat) appConf.value('Config/Portable') if self.isPortable(): print('%s: Running in Portable Mode.' % const.APPNAME) DataPaths.setPortableVersion() # Don't start single application in private browsing if not self.isPrivate(): appId = 'org.autowin.mc' if self.isPortable(): appId += '.Portable' if self.isTestModeEnabled(): appId += '.TestMode' if newInstance: if not startProfile or startProfile == 'default': print( 'New instance cannot be started with default profile!') else: # Generate unique appId so it is possible to start more # separate instances of the same profile. It is dangerous to # run more instance of the same profile, but if the user # wants it, we should allow it. appId += '.' + str(QDateTime.currentMSecsSinceEpoch()) self.setAppId(appId) # If there is nothing to tell other instance, we need to at least weak it if not messages: messages.append(' ') if self.isRunning(): self._isClosing = True for message in messages: self.sendMessage(message) return if const.OS_MACOS: self.setQuitOnLastWindowClosed(False) # TODO: # disable tabbing issue #2261 # extern void disableWindowTabbing(); # self.disableWindowTabbing() else: self.setQuitOnLastWindowClosed(True) QSettings.setDefaultFormat(QSettings.IniFormat) QDesktopServices.setUrlHandler('http', self.addNewTab) QDesktopServices.setUrlHandler('https', self.addNewTab) QDesktopServices.setUrlHandler('ftp', self.addNewTab) profileManager = ProfileManager() profileManager.initConfigDir() profileManager.initCurrentProfile(startProfile) Settings.createSettings( pathjoin(DataPaths.currentProfilePath(), 'settings.ini')) NetworkManager.registerSchemes() if self.isPrivate(): self._webProfile = QWebEngineProfile() else: self._webProfile = QWebEngineProfile.defaultProfile() self._webProfile.downloadRequested.connect(self.downloadRequested) self._networkManager = NetworkManager(self) self.setupUserScripts() if not self.isPrivate() and not self.isTestModeEnabled(): self._sessionManager = SessionManager(self) self._autoSaver = AutoSaver(self) self._autoSaver.save.connect( self._sessionManager.autoSaveLastSession) settings = Settings() settings.beginGroup('SessionRestore') wasRunning = settings.value('isRunning', False) wasRestoring = settings.value('isRestoring', False) settings.setValue('isRunning', True) settings.setValue('isRestoring', wasRunning) settings.endGroup() settings.sync() self._isStartingAfterCrash = bool(wasRunning and wasRestoring) if wasRunning: QTimer.singleShot( 60 * 1000, lambda: Settings().setValue( 'SessionRestore/isRestoring', False)) # we have to ask about startup session before creating main window if self._isStartingAfterCrash and self.afterLaunch( ) == self.SelectSession: self._restoreManager = RestoreManager( self.sessionManager().askSessionFromUser()) self.loadSettings() self._plugins = PluginProxy(self) self._autoFill = AutoFill(self) self.app.protocolHandlerManager() if not noAddons: self._plugins.loadPlugins() window = self.createWindow(const.BW_FirstAppWindow, startUrl) window.startingCompleted.connect(self.restoreOverrideCursor) self.focusChanged.connect(self.onFocusChanged) if not self.isPrivate() and not self.isTestModeEnabled(): # check updates settings = Settings() checkUpdates = settings.value('Web-Browser-Settings/CheckUpdates', True) if checkUpdates: Updater(window) self.sessionManager().backupSavedSessions() if self._isStartingAfterCrash or self.afterLaunch( ) == self.RestoreSession: self._restoreManager = RestoreManager( self.sessionManager().lastActiveSessionPath()) if not self._restoreManager.isValid(): self.destroyRestoreManager() if not self._isStartingAfterCrash and self._restoreManager: self.restoreSession(window, self._restoreManager.restoreData()) QSettings.setPath(QSettings.IniFormat, QSettings.UserScope, DataPaths.currentProfilePath()) self.messageReceived.connect(self.messageReceivedCb) self.aboutToQuit.connect(self.saveSettings) QTimer.singleShot(0, self.postLaunch)
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 PyQt5.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 resolve_font(path): new_path = Storage.__resolve__("data/fonts", path) id = Storage.DATABASE.addApplicationFont(new_path) return QFontDatabase.applicationFontFamilies(id)[0]
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 PyQt5.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 init_ui(self): fixed_font = QFontDatabase.systemFont(QFontDatabase.FixedFont) fixed_font.setPointSize(12) self.main_text_edit.setFont(fixed_font) self.action_exit.triggered.connect(self.exit_app)