| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -43,7 +43,7 @@ def warn_on_missing_glyph(codepoint, fontnames): | |||
| 43 | 43 | f"Matplotlib currently does not support {block} natively.") | |
| 44 | 44 | ||
| 45 | 45 | ||
| 46 | - def layout(string, font, *, kern_mode=Kerning.DEFAULT): | ||
| 46 | + def layout(string, font, language, *, kern_mode=Kerning.DEFAULT): | ||
| 47 | 47 | """ | |
| 48 | 48 | Render *string* with *font*. | |
| 49 | 49 | ||
@@ -65,7 +65,7 @@ def layout(string, font, *, kern_mode=Kerning.DEFAULT): | |||
| 65 | 65 | """ | |
| 66 | 66 | x = 0 | |
| 67 | 67 | prev_glyph_idx = None | |
| 68 | - char_to_font = font._get_fontmap(string) | ||
| 68 | + char_to_font = font._get_fontmap(string) # TODO: Pass in language. | ||
| 69 | 69 | base_font = font | |
| 70 | 70 | for char in string: | |
| 71 | 71 | # This has done the fallback logic | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -189,7 +189,8 @@ def draw_text(self, gc, x, y, s, prop, angle, ismath=False, mtext=None): | |||
| 189 | 189 | font = self._prepare_font(prop) | |
| 190 | 190 | # We pass '0' for angle here, since it will be rotated (in raster | |
| 191 | 191 | # 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) | ||
| 193 | 194 | font.draw_glyphs_to_bitmap( | |
| 194 | 195 | antialiased=gc.get_antialiased()) | |
| 195 | 196 | d = font.get_descent() / 64.0 | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -2345,6 +2345,7 @@ def draw_text(self, gc, x, y, s, prop, angle, ismath=False, mtext=None): | |||
| 2345 | 2345 | return self.draw_mathtext(gc, x, y, s, prop, angle) | |
| 2346 | 2346 | ||
| 2347 | 2347 | fontsize = prop.get_size_in_points() | |
| 2348 | + language = mtext.get_language() if mtext is not None else None | ||
| 2348 | 2349 | ||
| 2349 | 2350 | if mpl.rcParams['pdf.use14corefonts']: | |
| 2350 | 2351 | font = self._get_font_afm(prop) | |
@@ -2355,7 +2356,7 @@ def draw_text(self, gc, x, y, s, prop, angle, ismath=False, mtext=None): | |||
| 2355 | 2356 | fonttype = mpl.rcParams['pdf.fonttype'] | |
| 2356 | 2357 | ||
| 2357 | 2358 | if gc.get_url() is not None: | |
| 2358 | - font.set_text(s) | ||
| 2359 | + font.set_text(s, language=language) | ||
| 2359 | 2360 | width, height = font.get_width_height() | |
| 2360 | 2361 | self.file._annotations[-1][1].append(_get_link_annotation( | |
| 2361 | 2362 | 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): | |||
| 2389 | 2390 | multibyte_glyphs = [] | |
| 2390 | 2391 | prev_was_multibyte = True | |
| 2391 | 2392 | 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): | ||
| 2393 | 2395 | if _font_supports_glyph(fonttype, ord(item.char)): | |
| 2394 | 2396 | if prev_was_multibyte or item.ft_object != prev_font: | |
| 2395 | 2397 | singlebyte_chunks.append((item.ft_object, item.x, [])) | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -795,9 +795,10 @@ def draw_text(self, gc, x, y, s, prop, angle, ismath=False, mtext=None): | |||
| 795 | 795 | thisx += width * scale | |
| 796 | 796 | ||
| 797 | 797 | else: | |
| 798 | + language = mtext.get_language() if mtext is not None else None | ||
| 798 | 799 | font = self._get_font_ttf(prop) | |
| 799 | 800 | 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): | ||
| 801 | 802 | ps_name = (item.ft_object.postscript_name | |
| 802 | 803 | .encode("ascii", "replace").decode("ascii")) | |
| 803 | 804 | glyph_name = item.ft_object.get_glyph_name(item.glyph_idx) | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -136,6 +136,7 @@ def __init__(self, | |||
| 136 | 136 | super().__init__() | |
| 137 | 137 | self._x, self._y = x, y | |
| 138 | 138 | self._text = '' | |
| 139 | + self._language = None | ||
| 139 | 140 | self._reset_visual_defaults( | |
| 140 | 141 | text=text, | |
| 141 | 142 | color=color, | |
@@ -1422,6 +1423,36 @@ def _va_for_angle(self, angle): | |||
| 1422 | 1423 | return 'baseline' if anchor_at_left else 'top' | |
| 1423 | 1424 | return 'top' if anchor_at_left else 'baseline' | |
| 1424 | 1425 | ||
| 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 | + | ||
| 1425 | 1456 | ||
| 1426 | 1457 | class OffsetFrom: | |
| 1427 | 1458 | """Callable helper class for working with `Annotation`.""" | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -108,6 +108,8 @@ class Text(Artist): | |||
| 108 | 108 | def set_antialiased(self, antialiased: bool) -> None: ... | |
| 109 | 109 | def _ha_for_angle(self, angle: Any) -> Literal['center', 'right', 'left'] | None: ... | |
| 110 | 110 | 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: ... | ||
| 111 | 113 | ||
| 112 | 114 | class OffsetFrom: | |
| 113 | 115 | def __init__( | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -69,7 +69,7 @@ def get_text_width_height_descent(self, s, prop, ismath): | |||
| 69 | 69 | d /= 64.0 | |
| 70 | 70 | return w * scale, h * scale, d * scale | |
| 71 | 71 | ||
| 72 | - def get_text_path(self, prop, s, ismath=False): | ||
| 72 | + def get_text_path(self, prop, s, ismath=False, language=None): | ||
| 73 | 73 | """ | |
| 74 | 74 | Convert text *s* to path (a tuple of vertices and codes for | |
| 75 | 75 | matplotlib.path.Path). | |
@@ -109,7 +109,8 @@ def get_text_path(self, prop, s, ismath=False): | |||
| 109 | 109 | glyph_info, glyph_map, rects = self.get_glyphs_tex(prop, s) | |
| 110 | 110 | elif not ismath: | |
| 111 | 111 | 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) | ||
| 113 | 114 | else: | |
| 114 | 115 | glyph_info, glyph_map, rects = self.get_glyphs_mathtext(prop, s) | |
| 115 | 116 | ||
@@ -130,7 +131,7 @@ def get_text_path(self, prop, s, ismath=False): | |||
| 130 | 131 | return verts, codes | |
| 131 | 132 | ||
| 132 | 133 | 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): | ||
| 134 | 135 | """ | |
| 135 | 136 | Convert string *s* to vertices and codes using the provided ttf font. | |
| 136 | 137 | """ | |
@@ -145,7 +146,7 @@ def get_glyphs_with_font(self, font, s, glyph_map=None, | |||
| 145 | 146 | ||
| 146 | 147 | xpositions = [] | |
| 147 | 148 | glyph_ids = [] | |
| 148 | - for item in _text_helpers.layout(s, font): | ||
| 149 | + for item in _text_helpers.layout(s, font, language): | ||
| 149 | 150 | char_id = self._get_char_id(item.ft_object, ord(item.char)) | |
| 150 | 151 | glyph_ids.append(char_id) | |
| 151 | 152 | xpositions.append(item.x) | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -16,14 +16,16 @@ class TextToPath: | |||
| 16 | 16 | self, s: str, prop: FontProperties, ismath: bool | Literal["TeX"] | |
| 17 | 17 | ) -> tuple[float, float, float]: ... | |
| 18 | 18 | 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 = ..., | ||
| 20 | 21 | ) -> list[np.ndarray]: ... | |
| 21 | 22 | def get_glyphs_with_font( | |
| 22 | 23 | self, | |
| 23 | 24 | font: FT2Font, | |
| 24 | 25 | s: str, | |
| 25 | 26 | glyph_map: dict[str, tuple[np.ndarray, np.ndarray]] | None = ..., | |
| 26 | 27 | return_new_glyphs_only: bool = ..., | |
| 28 | + language: str | list[tuple[str, int, int]] | None = ..., | ||
| 27 | 29 | ) -> tuple[ | |
| 28 | 30 | list[tuple[str, float, float, float]], | |
| 29 | 31 | dict[str, tuple[np.ndarray, np.ndarray]], | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -399,7 +399,8 @@ void FT2Font::set_kerning_factor(int factor) | |||
| 399 | 399 | } | |
| 400 | 400 | ||
| 401 | 401 | 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) | ||
| 403 | 404 | { | |
| 404 | 405 | FT_Matrix matrix; /* transformation matrix */ | |
| 405 | 406 | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -6,6 +6,7 @@ | |||
| 6 | 6 | #ifndef MPL_FT2FONT_H | |
| 7 | 7 | #define MPL_FT2FONT_H | |
| 8 | 8 | ||
| 9 | + #include <optional> | ||
| 9 | 10 | #include <set> | |
| 10 | 11 | #include <string> | |
| 11 | 12 | #include <string_view> | |
@@ -70,6 +71,9 @@ class FT2Font | |||
| 70 | 71 | typedef void (*WarnFunc)(FT_ULong charcode, std::set<FT_String*> family_names); | |
| 71 | 72 | ||
| 72 | 73 | public: | |
| 74 | + using LanguageRange = std::tuple<std::string, int, int>; | ||
| 75 | + using LanguageType = std::optional<std::vector<LanguageRange>>; | ||
| 76 | + | ||
| 73 | 77 | FT2Font(FT_Open_Args &open_args, long hinting_factor, | |
| 74 | 78 | std::vector<FT2Font *> &fallback_list, WarnFunc warn); | |
| 75 | 79 | virtual ~FT2Font(); | |
@@ -78,7 +82,7 @@ class FT2Font | |||
| 78 | 82 | void set_charmap(int i); | |
| 79 | 83 | void select_charmap(unsigned long i); | |
| 80 | 84 | void set_text(std::u32string_view codepoints, double angle, FT_Int32 flags, | |
| 81 | - std::vector<double> &xys); | ||
| 85 | + LanguageType languages, std::vector<double> &xys); | ||
| 82 | 86 | int get_kerning(FT_UInt left, FT_UInt right, FT_Kerning_Mode mode, bool fallback); | |
| 83 | 87 | int get_kerning(FT_UInt left, FT_UInt right, FT_Kerning_Mode mode, FT_Vector &delta); | |
| 84 | 88 | void set_kerning_factor(int factor); | |
| Back | FazBrowse Home | New Git URL |
0 commit comments