Skip to content

Deprecate RendererCairo.font{weights,angles} #16285

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Mar 10, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions doc/api/next_api_changes/deprecations.rst
Original file line number Diff line number Diff line change
Expand Up @@ -278,3 +278,7 @@ property of `.Line2D` and `.LineCollection`. Previously, certain APIs would
accept ``offset = None`` as a synonym for ``offset = 0``, but this was never
universally implemented, e.g. for vector output. Support for ``offset = None``
is deprecated, set the offset to 0 instead.

``RendererCairo.fontweights``, ``RendererCairo.fontangles``
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
... are deprecated.
115 changes: 64 additions & 51 deletions lib/matplotlib/backends/backend_cairo.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
"cairo backend requires that pycairo>=1.11.0 or cairocffi"
"is installed") from err

from .. import cbook
from .. import cbook, font_manager
from matplotlib.backend_bases import (
_Backend, FigureCanvasBase, FigureManagerBase, GraphicsContextBase,
RendererBase)
Expand Down Expand Up @@ -70,33 +70,60 @@ def _append_path(ctx, path, transform, clip=None):
ctx.curve_to(*points)


def _cairo_font_args_from_font_prop(prop):
"""
Convert a `.FontProperties` or a `.FontEntry` to arguments that can be
passed to `.Context.select_font_face`.
"""
def attr(field):
try:
return getattr(prop, f"get_{field}")()
except AttributeError:
return getattr(prop, field)

name = attr("name")
slant = getattr(cairo, f"FONT_SLANT_{attr('style').upper()}")
weight = attr("weight")
weight = (cairo.FONT_WEIGHT_NORMAL
if font_manager.weight_dict.get(weight, weight) < 550
else cairo.FONT_WEIGHT_BOLD)
return name, slant, weight


class RendererCairo(RendererBase):
fontweights = {
100: cairo.FONT_WEIGHT_NORMAL,
200: cairo.FONT_WEIGHT_NORMAL,
300: cairo.FONT_WEIGHT_NORMAL,
400: cairo.FONT_WEIGHT_NORMAL,
500: cairo.FONT_WEIGHT_NORMAL,
600: cairo.FONT_WEIGHT_BOLD,
700: cairo.FONT_WEIGHT_BOLD,
800: cairo.FONT_WEIGHT_BOLD,
900: cairo.FONT_WEIGHT_BOLD,
'ultralight': cairo.FONT_WEIGHT_NORMAL,
'light': cairo.FONT_WEIGHT_NORMAL,
'normal': cairo.FONT_WEIGHT_NORMAL,
'medium': cairo.FONT_WEIGHT_NORMAL,
'regular': cairo.FONT_WEIGHT_NORMAL,
'semibold': cairo.FONT_WEIGHT_BOLD,
'bold': cairo.FONT_WEIGHT_BOLD,
'heavy': cairo.FONT_WEIGHT_BOLD,
'ultrabold': cairo.FONT_WEIGHT_BOLD,
'black': cairo.FONT_WEIGHT_BOLD,
}
fontangles = {
'italic': cairo.FONT_SLANT_ITALIC,
'normal': cairo.FONT_SLANT_NORMAL,
'oblique': cairo.FONT_SLANT_OBLIQUE,
}
@cbook.deprecated("3.3")
@property
def fontweights(self):
return {
100: cairo.FONT_WEIGHT_NORMAL,
200: cairo.FONT_WEIGHT_NORMAL,
300: cairo.FONT_WEIGHT_NORMAL,
400: cairo.FONT_WEIGHT_NORMAL,
500: cairo.FONT_WEIGHT_NORMAL,
600: cairo.FONT_WEIGHT_BOLD,
700: cairo.FONT_WEIGHT_BOLD,
800: cairo.FONT_WEIGHT_BOLD,
900: cairo.FONT_WEIGHT_BOLD,
'ultralight': cairo.FONT_WEIGHT_NORMAL,
'light': cairo.FONT_WEIGHT_NORMAL,
'normal': cairo.FONT_WEIGHT_NORMAL,
'medium': cairo.FONT_WEIGHT_NORMAL,
'regular': cairo.FONT_WEIGHT_NORMAL,
'semibold': cairo.FONT_WEIGHT_BOLD,
'bold': cairo.FONT_WEIGHT_BOLD,
'heavy': cairo.FONT_WEIGHT_BOLD,
'ultrabold': cairo.FONT_WEIGHT_BOLD,
'black': cairo.FONT_WEIGHT_BOLD,
}

@cbook.deprecated("3.3")
@property
def fontangles(self):
return {
'italic': cairo.FONT_SLANT_ITALIC,
'normal': cairo.FONT_SLANT_NORMAL,
'oblique': cairo.FONT_SLANT_OBLIQUE,
}

def __init__(self, dpi):
self.dpi = dpi
Expand Down Expand Up @@ -215,17 +242,12 @@ def draw_text(self, gc, x, y, s, prop, angle, ismath=False, mtext=None):
ctx = gc.ctx
ctx.new_path()
ctx.move_to(x, y)
ctx.select_font_face(prop.get_name(),
self.fontangles[prop.get_style()],
self.fontweights[prop.get_weight()])

size = prop.get_size_in_points() * self.dpi / 72.0

ctx.select_font_face(*_cairo_font_args_from_font_prop(prop))
ctx.save()
ctx.set_font_size(prop.get_size_in_points() * self.dpi / 72)
if angle:
ctx.rotate(np.deg2rad(-angle))
ctx.set_font_size(size)

ctx.show_text(s)
ctx.restore()

Expand All @@ -243,13 +265,9 @@ def _draw_mathtext(self, gc, x, y, s, prop, angle):
ctx.new_path()
ctx.move_to(ox, oy)

fontProp = ttfFontProperty(font)
ctx.select_font_face(fontProp.name,
self.fontangles[fontProp.style],
self.fontweights[fontProp.weight])

size = fontsize * self.dpi / 72.0
ctx.set_font_size(size)
ctx.select_font_face(
*_cairo_font_args_from_font_prop(ttfFontProperty(font)))
ctx.set_font_size(fontsize * self.dpi / 72)
ctx.show_text(s)

for ox, oy, w, h in rects:
Expand All @@ -273,19 +291,14 @@ def get_text_width_height_descent(self, s, prop, ismath):
return width, height, descent

ctx = self.text_ctx
ctx.save()
ctx.select_font_face(prop.get_name(),
self.fontangles[prop.get_style()],
self.fontweights[prop.get_weight()])

# Cairo (says it) uses 1/96 inch user space units, ref: cairo_gstate.c
# but if /96.0 is used the font is too small
size = prop.get_size_in_points() * self.dpi / 72

# problem - scale remembers last setting and font can become
# enormous causing program to crash
# save/restore prevents the problem
ctx.set_font_size(size)
ctx.save()
ctx.select_font_face(*_cairo_font_args_from_font_prop(prop))
# Cairo (says it) uses 1/96 inch user space units, ref: cairo_gstate.c
# but if /96.0 is used the font is too small
ctx.set_font_size(prop.get_size_in_points() * self.dpi / 72)

y_bearing, w, h = ctx.text_extents(s)[1:4]
ctx.restore()
Expand Down