Skip to content

Commit

Permalink
Add typing
Browse files Browse the repository at this point in the history
  • Loading branch information
t20100 committed Oct 27, 2023
1 parent b74b48f commit fd1fb65
Show file tree
Hide file tree
Showing 5 changed files with 105 additions and 62 deletions.
47 changes: 31 additions & 16 deletions src/silx/gui/_glutils/font.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# /*##########################################################################
#
# Copyright (c) 2016-2022 European Synchrotron Radiation Facility
# Copyright (c) 2016-2023 European Synchrotron Radiation Facility
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
Expand All @@ -23,12 +23,15 @@
# ###########################################################################*/
"""Text rasterisation feature leveraging Qt font and text layout support."""

from __future__ import annotations

__authors__ = ["T. Vincent"]
__license__ = "MIT"
__date__ = "13/10/2016"


import logging
from typing import Union
import numpy

from .. import qt
Expand All @@ -42,7 +45,7 @@
_logger = logging.getLogger(__name__)


def getDefaultFontFamily():
def getDefaultFontFamily() -> str:
"""Returns the default font family of the application"""
return qt.QApplication.instance().font().family()

Expand Down Expand Up @@ -70,24 +73,30 @@ def getDefaultFontFamily():
"""Thickest characters: Maximum font weight"""


def rasterTextQt(text, font, size=-1, weight=-1, italic=False, devicePixelRatio=1.0):
def rasterTextQt(
text: str,
font: Union[str, qt.QFont],
size: int = -1,
weight: int = -1,
italic: bool = False,
devicePixelRatio: float = 1.0,
) -> tuple[numpy.ndarray, int]:
"""Raster text using Qt.
It supports multiple lines.
:param str text: The text to raster
:param text: The text to raster
:param font: Font name or QFont to use
:type font: str or :class:`QFont`
:param int size:
:param size:
Font size in points
Used only if font is given as name.
:param int weight:
:param weight:
Font weight in [0, 99], see QFont.Weight.
Used only if font is given as name.
:param bool italic:
:param italic:
True for italic font (default: False).
Used only if font is given as name.
:param float devicePixelRatio:
:param devicePixelRatio:
The current ratio between device and device-independent pixel
(default: 1.0)
:return: Corresponding image in gray scale and baseline offset from top
Expand Down Expand Up @@ -160,24 +169,30 @@ def rasterTextQt(text, font, size=-1, weight=-1, italic=False, devicePixelRatio=
return array, metrics.ascent() - min_row


def rasterText(text, font, size=-1, weight=-1, italic=False, devicePixelRatio=1.0):
def rasterText(
text: str,
font: Union[str, qt.QFont],
size: int = -1,
weight = -1,
italic: bool = False,
devicePixelRatio=1.0,
) -> tuple[numpy.ndarray, int]:
"""Raster text using Qt or matplotlib if there may be math syntax.
It supports multiple lines.
:param str text: The text to raster
:param text: The text to raster
:param font: Font name or QFont to use
:type font: str or :class:`QFont`
:param int size:
:param size:
Font size in points
Used only if font is given as name.
:param int weight:
:param weight:
Font weight in [0, 99], see QFont.Weight.
Used only if font is given as name.
:param bool italic:
:param italic:
True for italic font (default: False).
Used only if font is given as name.
:param float devicePixelRatio:
:param devicePixelRatio:
The current ratio between device and device-independent pixel
(default: 1.0)
:return: Corresponding image in gray scale and baseline offset from top
Expand Down
52 changes: 34 additions & 18 deletions src/silx/gui/plot/backends/BackendBase.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,12 +28,19 @@
This API is a simplified version of PyMca PlotBackend API.
"""

from __future__ import annotations


__authors__ = ["V.A. Sole", "T. Vincent"]
__license__ = "MIT"
__date__ = "21/12/2018"

from collections.abc import Callable
from typing import Optional
import weakref

from ... import qt


# Names for setCursor
CURSOR_DEFAULT = 'default'
Expand Down Expand Up @@ -188,17 +195,28 @@ def addShape(self, x, y, shape, color, fill, overlay,
"""
return object()

def addMarker(self, x, y, text, color,
symbol, linestyle, linewidth, constraint, yaxis, font):
def addMarker(
self,
x: Optional[float],
y: Optional[float],
text: Optional[str],
color: str,
symbol: Optional[str],
linestyle: str,
linewidth: float,
constraint: Optional[Callable[[float, float], tuple[float, float]]],
yaxis: str,
font: qt.QFont,
) -> object:
"""Add a point, vertical line or horizontal line marker to the plot.
:param float x: Horizontal position of the marker in graph coordinates.
If None, the marker is a horizontal line.
:param float y: Vertical position of the marker in graph coordinates.
If None, the marker is a vertical line.
:param str text: Text associated to the marker (or None for no text)
:param str color: Color to be used for instance 'blue', 'b', '#FF0000'
:param str symbol: Symbol representing the marker.
:param x: Horizontal position of the marker in graph coordinates.
If None, the marker is a horizontal line.
:param y: Vertical position of the marker in graph coordinates.
If None, the marker is a vertical line.
:param text: Text associated to the marker (or None for no text)
:param color: Color to be used for instance 'blue', 'b', '#FF0000'
:param symbol: Symbol representing the marker.
Only relevant for point markers where X and Y are not None.
Value in:
Expand All @@ -209,7 +227,7 @@ def addMarker(self, x, y, text, color,
- 'x' x-cross
- 'd' diamond
- 's' square
:param str linestyle: Style of the line.
:param linestyle: Style of the line.
Only relevant for line markers where X or Y is None.
Value in:
Expand All @@ -218,16 +236,14 @@ def addMarker(self, x, y, text, color,
- '--' dashed line
- '-.' dash-dot line
- ':' dotted line
:param float linewidth: Width of the line.
:param linewidth: Width of the line.
Only relevant for line markers where X or Y is None.
:param constraint: A function filtering marker displacement by
dragging operations or None for no filter.
This function is called each time a marker is
moved.
:type constraint: None or a callable that takes the coordinates of
the current cursor position in the plot as input
and that returns the filtered coordinates.
:param str yaxis: The Y axis this marker belongs to in: 'left', 'right'
dragging operations or None for no filter.
This function is called each time a marker is moved.
It takes the coordinates of the current cursor position in the plot
as input and that returns the filtered coordinates.
:param yaxis: The Y axis this marker belongs to in: 'left', 'right'
:param font: QFont to use to render text
:return: Handle used by the backend to univocally access the marker
"""
Expand Down
37 changes: 21 additions & 16 deletions src/silx/gui/plot/backends/glutils/GLText.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@


from collections import OrderedDict
from typing import Optional
import weakref

import numpy
Expand All @@ -43,10 +44,7 @@
from .GLSupport import mat4Translate


# TODO: Font should be configurable by the main program: using mpl.rcParams?


class _Cache(object):
class _Cache:
"""LRU (Least Recent Used) cache.
:param int maxsize: Maximum number of (key, value) pairs in the cache
Expand Down Expand Up @@ -92,7 +90,7 @@ def __setitem__(self, key, value):
ROTATE_90, ROTATE_180, ROTATE_270 = 90, 180, 270


class Text2D(object):
class Text2D:

_SHADERS = {
'vertex': """
Expand Down Expand Up @@ -138,12 +136,19 @@ class Text2D(object):
_sizes = _Cache()
"""Cache already computed sizes"""

def __init__(self, text, font, x=0, y=0,
color=(0., 0., 0., 1.),
bgColor=None,
align=LEFT, valign=BASELINE,
rotate=0,
devicePixelRatio= 1.):
def __init__(
self,
text: str,
font: qt.QFont,
x: float = 0.,
y: float = 0.,
color: tuple[float, float, float, float] = (0., 0., 0., 1.),
bgColor: Optional[tuple[float, float, float, float]] = None,
align: str = LEFT,
valign: str = BASELINE,
rotate: float = 0.,
devicePixelRatio: float = 1.,
):
self.devicePixelRatio = devicePixelRatio
self.font = font
self._vertices = None
Expand All @@ -169,7 +174,7 @@ def _textureKey(self) -> tuple[str, str, float]:
"""Returns the current texture key"""
return self.text, self.font.key(), self.devicePixelRatio

def _getTexture(self):
def _getTexture(self) -> tuple[Texture, int]:
# Retrieve/initialize texture cache for current context
textureKey = self._textureKey()

Expand Down Expand Up @@ -200,11 +205,11 @@ def _getTexture(self):
return textures[textureKey]

@property
def text(self):
def text(self) -> str:
return self._text

@property
def size(self):
def size(self) -> tuple[int, int]:
textureKey = self._textureKey()
if textureKey not in self._sizes:
image, offset = font.rasterText(
Expand All @@ -214,7 +219,7 @@ def size(self):
self._sizes[textureKey] = image.shape[1], image.shape[0]
return self._sizes[textureKey]

def getVertices(self, offset, shape):
def getVertices(self, offset: int, shape: tuple[int, int]) -> numpy.ndarray:
height, width = shape

if self._align == LEFT:
Expand Down Expand Up @@ -247,7 +252,7 @@ def getVertices(self, offset, shape):

return vertices

def render(self, matrix):
def render(self, matrix: numpy.ndarray):
if not self.text.strip():
return

Expand Down
8 changes: 3 additions & 5 deletions src/silx/gui/utils/image.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# /*##########################################################################
#
# Copyright (c) 2017-2022 European Synchrotron Radiation Facility
# Copyright (c) 2017-2023 European Synchrotron Radiation Facility
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
Expand Down Expand Up @@ -39,7 +39,7 @@
from .. import qt


def convertArrayToQImage(array):
def convertArrayToQImage(array: numpy.ndarray) -> qt.QImage:
"""Convert an array-like image to a QImage.
The created QImage is using a copy of the array data.
Expand All @@ -50,7 +50,6 @@ def convertArrayToQImage(array):
Channels are expected to be either RGB or RGBA.
:type array: numpy.ndarray of uint8
:return: Corresponding Qt image with RGB888 or ARGB32 format.
:rtype: QImage
"""
array = numpy.array(array, copy=False, order='C', dtype=numpy.uint8)

Expand Down Expand Up @@ -82,7 +81,7 @@ def convertArrayToQImage(array):
return qimage.copy() # Making a copy of the image and its data


def convertQImageToArray(image):
def convertQImageToArray(image: qt.QImage) -> numpy.ndarray:
"""Convert a QImage to a numpy array.
If QImage format is not Format_RGB888, Format_RGBA8888 or Format_ARGB32,
Expand All @@ -94,7 +93,6 @@ def convertQImageToArray(image):
:param QImage image: The QImage to convert.
:return: The image array of RGB or RGBA channels of shape
(height, width, channels (3 or 4))
:rtype: numpy.ndarray of uint8
"""
rgba8888 = getattr(qt.QImage, 'Format_RGBA8888', None) # Only in Qt5

Expand Down
23 changes: 16 additions & 7 deletions src/silx/gui/utils/matplotlib.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,13 +29,16 @@
It provides the matplotlib :class:`FigureCanvasQTAgg` class corresponding
to the used backend.
"""
from __future__ import annotations


__authors__ = ["T. Vincent"]
__license__ = "MIT"
__date__ = "02/05/2018"


import io
from typing import Union
import matplotlib
import numpy

Expand Down Expand Up @@ -72,24 +75,30 @@ def qFontToFontProperties(font: qt.QFont):
)


def rasterMathText(text, font, size=-1, weight=-1, italic=False, devicePixelRatio=1.0):
def rasterMathText(
text: str,
font: Union[str, qt.QFont],
size: int = -1,
weight: int = -1,
italic: bool = False,
devicePixelRatio: float = 1.0,
) -> tuple[numpy.ndarray, int]:
"""Raster text using matplotlib supporting latex-like math syntax.
It supports multiple lines.
:param str text: The text to raster
:param text: The text to raster
:param font: Font name or QFont to use
:type font: str or :class:`QFont`
:param int size:
:param size:
Font size in points
Used only if font is given as name.
:param int weight:
:param weight:
Font weight in [0, 99], see QFont.Weight.
Used only if font is given as name.
:param bool italic:
:param italic:
True for italic font (default: False).
Used only if font is given as name.
:param float devicePixelRatio:
:param devicePixelRatio:
The current ratio between device and device-independent pixel
(default: 1.0)
:return: Corresponding image in gray scale and baseline offset from top
Expand Down

0 comments on commit fd1fb65

Please sign in to comment.