From 777cfbf1bae1f24753d42d3ac86fb00d3b39ae3a Mon Sep 17 00:00:00 2001 From: Florian Bruhin Date: Tue, 31 Dec 2019 15:52:42 +0100 Subject: Improve QtFont parsing This uses QtFont.setFamilies, similar to what QCssParser does in the commit where it was introduced: https://codereview.qt-project.org/c/qt/qtbase/+/240070 It also fixes a "font family too long" warning on Windows - see #5013 --- doc/changelog.asciidoc | 2 ++ qutebrowser/config/configtypes.py | 23 ++++++++++++----- tests/unit/config/test_configtypes.py | 48 ++++++++++++++++++++++++++++++----- 3 files changed, 60 insertions(+), 13 deletions(-) diff --git a/doc/changelog.asciidoc b/doc/changelog.asciidoc index 131978215..d3f65d358 100644 --- a/doc/changelog.asciidoc +++ b/doc/changelog.asciidoc @@ -81,6 +81,8 @@ Changed doing so would be equal to `:tab-clone`. * The `:buffer` completion doesn't show any window sections anymore, only a flat list of tabs. +- Improved parsing in some corner cases for the `QtFont` type (used for + `fonts.tabs` and `fonts.debug_console`). - Performance improvements for the following areas: * Adding settings with URL patterns * Matching of settings using URL patterns diff --git a/qutebrowser/config/configtypes.py b/qutebrowser/config/configtypes.py index 475879de0..9628184b9 100644 --- a/qutebrowser/config/configtypes.py +++ b/qutebrowser/config/configtypes.py @@ -1267,12 +1267,23 @@ class QtFont(Font): if family == 'monospace' and self.monospace_fonts is not None: family = self.monospace_fonts - # The Qt CSS parser handles " and ' before passing the string to - # QFont.setFamily. We could do proper CSS-like parsing here, but since - # hopefully nobody will ever have a font with quotes in the family (if - # that's even possible), we take a much more naive approach. - family = family.replace('"', '').replace("'", '') - font.setFamily(family) + + families = [] + for part in family.split(','): + part = part.strip() + # The Qt CSS parser handles " and ' before passing the string to + # QFont.setFamily. + if ((part.startswith("'") and part.endswith("'")) or + (part.startswith('"') and part.endswith('"'))): + part = part[1:-1] + families.append(part) + + if hasattr(font, 'setFamilies'): + font.setFamily(families[0]) + font.setFamilies(families) + else: + # Added in Qt 5.13 + font.setFamily(', '.join(families)) return font diff --git a/tests/unit/config/test_configtypes.py b/tests/unit/config/test_configtypes.py index e766fca8a..034b79c25 100644 --- a/tests/unit/config/test_configtypes.py +++ b/tests/unit/config/test_configtypes.py @@ -48,21 +48,41 @@ class Font(QFont): def __repr__(self): weight = debug.qenum_key(QFont, self.weight(), add_base=True, klass=QFont.Weight) - return utils.get_repr(self, family=self.family(), pt=self.pointSize(), - px=self.pixelSize(), weight=weight, - style=self.style()) + kwargs = { + 'family': self.family(), + 'pt': self.pointSize(), + 'px': self.pixelSize(), + 'weight': weight, + 'style': self.style(), + } + try: + kwargs['families'] = self.families() + except AttributeError: + # Added in Qt 5.13 + pass + + return utils.get_repr(self, **kwargs) @classmethod def fromdesc(cls, desc): """Get a Font based on a font description.""" f = cls() + f.setStyle(desc.style) f.setWeight(desc.weight) + if desc.pt is not None and desc.pt != -1: f.setPointSize(desc.pt) if desc.px is not None and desc.pt != -1: f.setPixelSize(desc.px) + f.setFamily(desc.family) + try: + f.setFamilies([desc.family]) + except AttributeError: + # Added in Qt 5.13 + pass + return f @@ -1407,16 +1427,30 @@ class TestFont: expected = Font.fromdesc(desc) assert klass().to_py(val) == expected + def test_qtfont(self, qtfont_class): + """Test QtFont's to_py.""" + value = Font(qtfont_class().to_py('10pt "Foobar Neue", Fubar')) + + if hasattr(value, 'families'): + # Added in Qt 5.13 + assert value.family() == 'Foobar Neue' + assert value.families() == ['Foobar Neue', 'Fubar'] + else: + assert value.family() == 'Foobar Neue, Fubar' + + assert value.weight() == QFont.Normal + assert value.style() == QFont.StyleNormal + + assert value.pointSize() == 10 + def test_qtfont_float(self, qtfont_class): """Test QtFont's to_py with a float as point size. We can't test the point size for equality as Qt seems to do some rounding as appropriate. """ - value = Font(qtfont_class().to_py('10.5pt "Foobar Neue"')) - assert value.family() == 'Foobar Neue' - assert value.weight() == QFont.Normal - assert value.style() == QFont.StyleNormal + value = Font(qtfont_class().to_py('10.5pt Test')) + assert value.family() == 'Test' assert value.pointSize() >= 10 assert value.pointSize() <= 11 -- cgit v1.2.3-54-g00ecf