Skip to content

Commit 7f11aa6

Browse files
committed
revert removal of raster text with Qt
1 parent 450134d commit 7f11aa6

File tree

1 file changed

+113
-3
lines changed

1 file changed

+113
-3
lines changed

src/silx/gui/_glutils/font.py

+113-3
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# /*##########################################################################
22
#
3-
# Copyright (c) 2016-2023 European Synchrotron Radiation Facility
3+
# Copyright (c) 2016-2024 European Synchrotron Radiation Facility
44
#
55
# Permission is hereby granted, free of charge, to any person obtaining a copy
66
# of this software and associated documentation files (the "Software"), to deal
@@ -21,19 +21,129 @@
2121
# THE SOFTWARE.
2222
#
2323
# ###########################################################################*/
24+
from __future__ import annotations
2425
"""Text rasterisation feature leveraging Qt font and text layout support."""
2526

2627
__authors__ = ["T. Vincent"]
2728
__license__ = "MIT"
2829
__date__ = "13/10/2016"
2930

3031

32+
import logging
33+
import numpy
34+
3135
from .. import qt
36+
from ..utils.image import convertQImageToArray
37+
from ..utils.matplotlib import rasterMathText
38+
3239

33-
# Expose rasterMathText as part of this module
34-
from ..utils.matplotlib import rasterMathText as rasterText # noqa
40+
_logger = logging.getLogger(__name__)
3541

3642

3743
def getDefaultFontFamily() -> str:
3844
"""Returns the default font family of the application"""
3945
return qt.QApplication.instance().font().family()
46+
47+
48+
def rasterTextQt(
49+
text: str,
50+
font: qt.QFont,
51+
dotsPerInch: float = 96.0,
52+
) -> tuple[numpy.ndarray, float]:
53+
"""Raster text using Qt.
54+
55+
It supports multiple lines.
56+
57+
:param text: The text to raster
58+
:param font: Font to use
59+
:param dotsPerInch: The DPI resolution of the created image
60+
:return: Corresponding image in gray scale and baseline offset from top
61+
"""
62+
if not text:
63+
_logger.info("Trying to raster empty text, replaced by white space")
64+
text = " " # Replace empty text by white space to produce an image
65+
66+
dotsPerMeter = int(dotsPerInch * 100 / 2.54)
67+
68+
# get text size
69+
image = qt.QImage(1, 1, qt.QImage.Format_Grayscale8)
70+
image.setDotsPerMeterX(dotsPerMeter)
71+
image.setDotsPerMeterY(dotsPerMeter)
72+
73+
painter = qt.QPainter()
74+
painter.begin(image)
75+
painter.setPen(qt.Qt.white)
76+
painter.setFont(font)
77+
bounds = painter.boundingRect(
78+
qt.QRect(0, 0, 4096, 4096), qt.Qt.TextExpandTabs, text
79+
)
80+
painter.end()
81+
82+
metrics = qt.QFontMetrics(font)
83+
offset = metrics.ascent() / 72.0 * dotsPerInch
84+
85+
# This does not provide the correct text bbox on macOS
86+
# size = metrics.size(qt.Qt.TextExpandTabs, text)
87+
# bounds = metrics.boundingRect(
88+
# qt.QRect(0, 0, size.width(), size.height()),
89+
# qt.Qt.TextExpandTabs,
90+
# text)
91+
92+
# Add extra border
93+
width = bounds.width() + 2
94+
# align line size to 32 bits to ease conversion to numpy array
95+
width = 4 * ((width + 3) // 4)
96+
image = qt.QImage(
97+
int(width),
98+
int(bounds.height() + 2),
99+
qt.QImage.Format_Grayscale8,
100+
)
101+
image.setDotsPerMeterX(dotsPerMeter)
102+
image.setDotsPerMeterY(dotsPerMeter)
103+
image.fill(0)
104+
105+
# Raster text
106+
painter = qt.QPainter()
107+
painter.begin(image)
108+
painter.setPen(qt.Qt.white)
109+
painter.setFont(font)
110+
painter.drawText(bounds, qt.Qt.TextExpandTabs, text)
111+
painter.end()
112+
113+
array = convertQImageToArray(image)
114+
115+
# Remove leading and trailing empty columns/rows but one on each side
116+
filled_rows = numpy.nonzero(numpy.sum(array, axis=1))[0]
117+
filled_columns = numpy.nonzero(numpy.sum(array, axis=0))[0]
118+
119+
if len(filled_rows) == 0 or len(filled_columns) == 0:
120+
return array, offset
121+
return (
122+
numpy.ascontiguousarray(
123+
array[
124+
0 : filled_rows[-1] + 2,
125+
max(0, filled_columns[0] - 1) : filled_columns[-1] + 2,
126+
]
127+
),
128+
offset,
129+
)
130+
131+
132+
def rasterText(
133+
text: str,
134+
font: qt.QFont,
135+
dotsPerInch: float = 96.0,
136+
) -> tuple[numpy.ndarray, float]:
137+
"""Raster text using Qt or matplotlib if there may be math syntax.
138+
139+
It supports multiple lines.
140+
141+
:param text: The text to raster
142+
:param font: Font name or QFont to use
143+
:param dotsPerInch: Created image resolution
144+
:return: Corresponding image in gray scale and baseline offset from top
145+
"""
146+
147+
if text.count("$") >= 2:
148+
return rasterMathText(text, font, dotsPerInch)
149+
return rasterTextQt(text, font, dotsPerInch)

0 commit comments

Comments
 (0)