Skip to content

Commit f240057

Browse files
committed
Add language parameter to Text objects
1 parent f017a0e commit f240057

File tree

11 files changed

+84
-15
lines changed

11 files changed

+84
-15
lines changed

lib/matplotlib/_text_helpers.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ def warn_on_missing_glyph(codepoint, fontnames):
4343
f"Matplotlib currently does not support {block} natively.")
4444

4545

46-
def layout(string, font, *, kern_mode=Kerning.DEFAULT):
46+
def layout(string, font, language, *, kern_mode=Kerning.DEFAULT):
4747
"""
4848
Render *string* with *font*.
4949
@@ -65,7 +65,7 @@ def layout(string, font, *, kern_mode=Kerning.DEFAULT):
6565
"""
6666
x = 0
6767
prev_glyph_idx = None
68-
char_to_font = font._get_fontmap(string)
68+
char_to_font = font._get_fontmap(string) # TODO: Pass in language.
6969
base_font = font
7070
for char in string:
7171
# This has done the fallback logic

lib/matplotlib/backends/backend_agg.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -189,7 +189,8 @@ def draw_text(self, gc, x, y, s, prop, angle, ismath=False, mtext=None):
189189
font = self._prepare_font(prop)
190190
# We pass '0' for angle here, since it will be rotated (in raster
191191
# space) in the following call to draw_text_image).
192-
font.set_text(s, 0, flags=get_hinting_flag())
192+
font.set_text(s, 0, flags=get_hinting_flag(),
193+
language=mtext.get_language() if mtext is not None else None)
193194
font.draw_glyphs_to_bitmap(
194195
antialiased=gc.get_antialiased())
195196
d = font.get_descent() / 64.0

lib/matplotlib/backends/backend_pdf.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2345,6 +2345,7 @@ def draw_text(self, gc, x, y, s, prop, angle, ismath=False, mtext=None):
23452345
return self.draw_mathtext(gc, x, y, s, prop, angle)
23462346

23472347
fontsize = prop.get_size_in_points()
2348+
language = mtext.get_language() if mtext is not None else None
23482349

23492350
if mpl.rcParams['pdf.use14corefonts']:
23502351
font = self._get_font_afm(prop)
@@ -2355,7 +2356,7 @@ def draw_text(self, gc, x, y, s, prop, angle, ismath=False, mtext=None):
23552356
fonttype = mpl.rcParams['pdf.fonttype']
23562357

23572358
if gc.get_url() is not None:
2358-
font.set_text(s)
2359+
font.set_text(s, language=language)
23592360
width, height = font.get_width_height()
23602361
self.file._annotations[-1][1].append(_get_link_annotation(
23612362
gc, x, y, width / 64, height / 64, angle))
@@ -2389,7 +2390,8 @@ def draw_text(self, gc, x, y, s, prop, angle, ismath=False, mtext=None):
23892390
multibyte_glyphs = []
23902391
prev_was_multibyte = True
23912392
prev_font = font
2392-
for item in _text_helpers.layout(s, font, kern_mode=Kerning.UNFITTED):
2393+
for item in _text_helpers.layout(s, font, language,
2394+
kern_mode=Kerning.UNFITTED):
23932395
if _font_supports_glyph(fonttype, ord(item.char)):
23942396
if prev_was_multibyte or item.ft_object != prev_font:
23952397
singlebyte_chunks.append((item.ft_object, item.x, []))

lib/matplotlib/backends/backend_ps.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -795,9 +795,10 @@ def draw_text(self, gc, x, y, s, prop, angle, ismath=False, mtext=None):
795795
thisx += width * scale
796796

797797
else:
798+
language = mtext.get_language() if mtext is not None else None
798799
font = self._get_font_ttf(prop)
799800
self._character_tracker.track(font, s)
800-
for item in _text_helpers.layout(s, font):
801+
for item in _text_helpers.layout(s, font, language):
801802
ps_name = (item.ft_object.postscript_name
802803
.encode("ascii", "replace").decode("ascii"))
803804
glyph_name = item.ft_object.get_glyph_name(item.glyph_idx)

lib/matplotlib/text.py

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -136,6 +136,7 @@ def __init__(self,
136136
super().__init__()
137137
self._x, self._y = x, y
138138
self._text = ''
139+
self._language = None
139140
self._reset_visual_defaults(
140141
text=text,
141142
color=color,
@@ -1422,6 +1423,36 @@ def _va_for_angle(self, angle):
14221423
return 'baseline' if anchor_at_left else 'top'
14231424
return 'top' if anchor_at_left else 'baseline'
14241425

1426+
def get_language(self):
1427+
"""Return the language this Text is in."""
1428+
return self._language
1429+
1430+
def set_language(self, language):
1431+
"""
1432+
Set the language of the text.
1433+
1434+
Parameters
1435+
----------
1436+
language : str or list[tuple[str, int, int]]
1437+
1438+
"""
1439+
_api.check_isinstance((list, str, None), language=language)
1440+
if isinstance(language, list):
1441+
for val in language:
1442+
if not isinstance(val, tuple) or len(val) != 3:
1443+
raise ValueError('language must be list of tuple, not {language!r}')
1444+
sublang, start, end = val
1445+
if not isinstance(sublang, str):
1446+
raise ValueError(
1447+
'sub-language specification must be str, not {sublang!r}')
1448+
if not isinstance(start, int):
1449+
raise ValueError('start location must be int, not {start!r}')
1450+
if not isinstance(end, int):
1451+
raise ValueError('end location must be int, not {end!r}')
1452+
1453+
self._language = language
1454+
self.stale = True
1455+
14251456

14261457
class OffsetFrom:
14271458
"""Callable helper class for working with `Annotation`."""

lib/matplotlib/text.pyi

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,8 @@ class Text(Artist):
108108
def set_antialiased(self, antialiased: bool) -> None: ...
109109
def _ha_for_angle(self, angle: Any) -> Literal['center', 'right', 'left'] | None: ...
110110
def _va_for_angle(self, angle: Any) -> Literal['center', 'top', 'baseline'] | None: ...
111+
def get_language(self) -> str | list[tuple[str, int, int]] | None: ...
112+
def set_language(self, language: str | list[tuple[str, int, int]] | None) -> None: ...
111113

112114
class OffsetFrom:
113115
def __init__(

lib/matplotlib/textpath.py

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ def get_text_width_height_descent(self, s, prop, ismath):
6969
d /= 64.0
7070
return w * scale, h * scale, d * scale
7171

72-
def get_text_path(self, prop, s, ismath=False):
72+
def get_text_path(self, prop, s, ismath=False, language=None):
7373
"""
7474
Convert text *s* to path (a tuple of vertices and codes for
7575
matplotlib.path.Path).
@@ -109,7 +109,8 @@ def get_text_path(self, prop, s, ismath=False):
109109
glyph_info, glyph_map, rects = self.get_glyphs_tex(prop, s)
110110
elif not ismath:
111111
font = self._get_font(prop)
112-
glyph_info, glyph_map, rects = self.get_glyphs_with_font(font, s)
112+
glyph_info, glyph_map, rects = self.get_glyphs_with_font(font, s,
113+
language=language)
113114
else:
114115
glyph_info, glyph_map, rects = self.get_glyphs_mathtext(prop, s)
115116

@@ -130,7 +131,7 @@ def get_text_path(self, prop, s, ismath=False):
130131
return verts, codes
131132

132133
def get_glyphs_with_font(self, font, s, glyph_map=None,
133-
return_new_glyphs_only=False):
134+
return_new_glyphs_only=False, language=None):
134135
"""
135136
Convert string *s* to vertices and codes using the provided ttf font.
136137
"""
@@ -145,7 +146,7 @@ def get_glyphs_with_font(self, font, s, glyph_map=None,
145146

146147
xpositions = []
147148
glyph_ids = []
148-
for item in _text_helpers.layout(s, font):
149+
for item in _text_helpers.layout(s, font, language):
149150
char_id = self._get_char_id(item.ft_object, ord(item.char))
150151
glyph_ids.append(char_id)
151152
xpositions.append(item.x)

lib/matplotlib/textpath.pyi

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,14 +16,16 @@ class TextToPath:
1616
self, s: str, prop: FontProperties, ismath: bool | Literal["TeX"]
1717
) -> tuple[float, float, float]: ...
1818
def get_text_path(
19-
self, prop: FontProperties, s: str, ismath: bool | Literal["TeX"] = ...
19+
self, prop: FontProperties, s: str, ismath: bool | Literal["TeX"] = ...,
20+
language: str | list[tuple[str, int, int]] | None = ...,
2021
) -> list[np.ndarray]: ...
2122
def get_glyphs_with_font(
2223
self,
2324
font: FT2Font,
2425
s: str,
2526
glyph_map: dict[str, tuple[np.ndarray, np.ndarray]] | None = ...,
2627
return_new_glyphs_only: bool = ...,
28+
language: str | list[tuple[str, int, int]] | None = ...,
2729
) -> tuple[
2830
list[tuple[str, float, float, float]],
2931
dict[str, tuple[np.ndarray, np.ndarray]],

src/ft2font.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -399,7 +399,8 @@ void FT2Font::set_kerning_factor(int factor)
399399
}
400400

401401
void FT2Font::set_text(
402-
std::u32string_view text, double angle, FT_Int32 flags, std::vector<double> &xys)
402+
std::u32string_view text, double angle, FT_Int32 flags, LanguageType languages,
403+
std::vector<double> &xys)
403404
{
404405
FT_Matrix matrix; /* transformation matrix */
405406

src/ft2font.h

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
#ifndef MPL_FT2FONT_H
77
#define MPL_FT2FONT_H
88

9+
#include <optional>
910
#include <set>
1011
#include <string>
1112
#include <string_view>
@@ -70,6 +71,9 @@ class FT2Font
7071
typedef void (*WarnFunc)(FT_ULong charcode, std::set<FT_String*> family_names);
7172

7273
public:
74+
using LanguageRange = std::tuple<std::string, int, int>;
75+
using LanguageType = std::optional<std::vector<LanguageRange>>;
76+
7377
FT2Font(FT_Open_Args &open_args, long hinting_factor,
7478
std::vector<FT2Font *> &fallback_list, WarnFunc warn);
7579
virtual ~FT2Font();
@@ -78,7 +82,7 @@ class FT2Font
7882
void set_charmap(int i);
7983
void select_charmap(unsigned long i);
8084
void set_text(std::u32string_view codepoints, double angle, FT_Int32 flags,
81-
std::vector<double> &xys);
85+
LanguageType languages, std::vector<double> &xys);
8286
int get_kerning(FT_UInt left, FT_UInt right, FT_Kerning_Mode mode, bool fallback);
8387
int get_kerning(FT_UInt left, FT_UInt right, FT_Kerning_Mode mode, FT_Vector &delta);
8488
void set_kerning_factor(int factor);

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy