From 8472daba067d78e1038a16fd2bfdb7fede611143 Mon Sep 17 00:00:00 2001 From: Leif Gehrmann Date: Wed, 30 Dec 2020 00:25:07 +0000 Subject: [PATCH] Implement get/set_default() for PangoCairoFontMap + Documentation clarification (#26) --- Makefile | 2 +- docs/conf.py | 1 + docs/modules.rst | 8 +-- pangocairocffi/font_map.py | 93 ++++++++++++++++++++++++------ pangocairocffi/render_functions.py | 3 +- tests/test_font_map.py | 16 +++++ 6 files changed, 98 insertions(+), 25 deletions(-) create mode 100644 tests/test_font_map.py diff --git a/Makefile b/Makefile index 2671eb2..177a15e 100644 --- a/Makefile +++ b/Makefile @@ -63,7 +63,7 @@ test-all: clean ## run tests on all minor python versions tox coverage: ## check code coverage quickly with the default Python - coverage run --source pangocffi -m pytest + coverage run --source pangocairocffi -m pytest coverage report -m coverage html $(BROWSER) htmlcov/index.html diff --git a/docs/conf.py b/docs/conf.py index b7d78d0..5744e0c 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -16,6 +16,7 @@ version = '.'.join(release.split('.')[:2]) exclude_patterns = ['_build'] autodoc_member_order = 'bysource' +autoclass_content = 'both' autodoc_default_options = { 'members': None # Set to True when readthedocs.org updates sphinx to v2.0 } diff --git a/docs/modules.rst b/docs/modules.rst index 2fb9451..6921fc2 100644 --- a/docs/modules.rst +++ b/docs/modules.rst @@ -28,14 +28,14 @@ ____________________________ .. .. autofunction:: pangocairocffi.show_glyph_string -.. .. autofunction:: pangocairocffi.show_glyph_item - .. .. autofunction:: pangocairocffi.show_layout_line .. autofunction:: pangocairocffi.show_layout .. autofunction:: pangocairocffi.show_error_underline +.. autofunction:: pangocairocffi.show_glyph_item + Adding text to cairo's current path ___________________________________ @@ -50,7 +50,7 @@ ___________________________________ PangoCairo Fonts ================ -PangoCairo Fonts Functions +PangoCairo Font Functions __________________________ .. .. autofunction:: pangocairocffi.get_cairo_scaled_font_pointer @@ -63,7 +63,7 @@ __________________________ .. autofunction:: pangocairocffi.get_font_options -PangoCairo Fonts Map +PangoCairo Font Map ____________________ .. autoclass:: pangocairocffi.PangoCairoFontMap diff --git a/pangocairocffi/font_map.py b/pangocairocffi/font_map.py index cd8ab8a..bfa2fa7 100644 --- a/pangocairocffi/font_map.py +++ b/pangocairocffi/font_map.py @@ -1,33 +1,32 @@ +from typing import Optional + from . import pangocairo, ffi from pangocffi import Context from pangocffi import pango -# Todo: Implement FontMap in pango -# def get_default_font_map() -> pangocffi.FontMap: -# return FontMap.from_pointer( -# pangocairo.pango_cairo_font_map_get_default() -# ) -# def set_default_font_map(font_map: pangocffi.FontMap) -> None: -# return pangocairo.pango_cairo_font_map_set_default( -# font_map.get_pointer() -# ) - - -# Todo: extend FontMap from pangocffi class PangoCairoFontMap: """ - PangoCairoFontMap is an interface exported by font maps for use with Cairo. - The actual type of the font map will depend on the particular font + API not *fully* implemented yet. + + **Todo:** This class should extend FontMap from pangocffi once it is + implemented. This class in theory should be able to inherit the functions + listed here: + https://developer.gnome.org/pango/stable/pango-Fonts.html, with the prefix + ``pango_font_map_X``. For example: ``create_context``, ``load_font``, + ``load_fontset``, ``list_families``. + + ``PangoCairoFontMap`` is an interface exported by font maps for use with + Cairo. The actual type of the font map will depend on the particular font technology Cairo was compiled to use. """ def __init__(self): """ - Creates a new PangoCairoFontMap object; a ``fontmap`` is used to cache - information about available fonts, and holds certain global parameters - such as the resolution. In most cases, you can use - ``PangoCairoFontMap.get_default()`` instead. + ``__init__`` Creates a new PangoCairoFontMap object; a ``fontmap`` is + used to cache information about available fonts, and holds certain + global parameters such as the resolution. In most cases, you can use + :py:meth:`PangoCairoFontMap.get_default()` instead. Note that the type of the returned object will depend on the particular font backend Cairo was compiled to use; You generally should only use @@ -43,6 +42,7 @@ def __init__(self): self._init_pointer(pangocairo.pango_cairo_font_map_new()) def _init_pointer(self, pointer: ffi.CData): + pointer = ffi.cast('PangoCairoFontMap *', pointer) self._pointer = pointer def get_pointer(self) -> ffi.CData: @@ -68,6 +68,63 @@ def from_pointer(cls, pointer: ffi.CData) -> 'PangoCairoFontMap': cls._init_pointer(self, pointer) return self + @classmethod + def get_default( + cls, + ) -> 'PangoCairoFontMap': + """ + Gets a default ``PangoCairoFontMap`` to use with Cairo. + + Note that the type of the returned object will depend on the particular + font backend Cairo was compiled to use; You generally should only use + the PangoFontMap and PangoCairoFontMap interfaces on the returned + object. + + The default Cairo fontmap can be changed by using + :py:meth:`PangoCairoFontMap.set_default()`. This can be used to change + the Cairo font backend that the default fontmap uses for example. + + Note that since Pango 1.32.6, the default fontmap is per-thread. Each + thread gets its own default fontmap. In this way, PangoCairo can be + used safely from multiple threads. + + :return: + the default PangoCairo fontmap for the current thread. This object + is owned by Pango and must not be freed. + """ + font_map_pointer = pangocairo.pango_cairo_font_map_get_default() + return cls.from_pointer(font_map_pointer) + + @classmethod + def set_default( + cls, + fontmap: Optional['PangoCairoFontMap'] = None + ) -> None: + """ + Sets a default PangoCairoFontMap to use with Cairo. + + This can be used to change the Cairo font backend that the default + fontmap uses for example. The old default font map is unreffed and the + new font map referenced. + + Note that since Pango 1.32.6, the default fontmap is per-thread. This + function only changes the default fontmap for the current thread. + Default fontmaps of existing threads are not changed. Default fontmaps + of any new threads will still be created using + pango_cairo_font_map_new(). + + A value of ``None`` for fontmap will cause the current default font + map to be released and a new default font map to be created on demand, + using ``pango_cairo_font_map_new()``. + + :return: + the pango-cairo font map. + """ + fontmap_pointer = ffi.NULL + if fontmap is not None: + fontmap_pointer = fontmap.get_pointer() + pangocairo.pango_cairo_font_map_set_default(fontmap_pointer) + @classmethod def from_cairo_font_type( cls, diff --git a/pangocairocffi/render_functions.py b/pangocairocffi/render_functions.py index 217eeb6..3cc8c1f 100644 --- a/pangocairocffi/render_functions.py +++ b/pangocairocffi/render_functions.py @@ -51,10 +51,9 @@ def show_glyph_item( :param cairo_context: a Cairo context :param text: - the UTF-8 text that :param:`glyph_item` refers to + the UTF-8 text that ``glyph_item`` refers to :param glyph_item: a Pango glyph item - :return: """ cairo_context_pointer = _get_cairo_t_from_cairo_ctx(cairo_context) text_pointer = ffi.new('char[]', text.encode('utf8')) diff --git a/tests/test_font_map.py b/tests/test_font_map.py new file mode 100644 index 0000000..86e40fd --- /dev/null +++ b/tests/test_font_map.py @@ -0,0 +1,16 @@ +from pangocairocffi import PangoCairoFontMap + + +def test_font_map(): + font_map_default = PangoCairoFontMap.get_default() + font_map_new = PangoCairoFontMap() + assert font_map_new != font_map_default + + resolution = font_map_new.get_resolution() + assert resolution == 96 + font_map_new.set_resolution(123) + assert font_map_new.get_resolution() == 123 + + PangoCairoFontMap.set_default(font_map_new) + assert font_map_new == PangoCairoFontMap.get_default() + PangoCairoFontMap.set_default(None)