Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commiteffb8e0

Browse files
committed
Use libraqm for text in vector outputs
1 parent73441fc commiteffb8e0

File tree

5 files changed

+117
-36
lines changed

5 files changed

+117
-36
lines changed

‎lib/matplotlib/_text_helpers.py

Lines changed: 4 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -4,19 +4,8 @@
44

55
from __future__importannotations
66

7-
importdataclasses
8-
97
from .import_api
10-
from .ft2fontimportFT2Font,Kerning,LoadFlags
11-
12-
13-
@dataclasses.dataclass(frozen=True)
14-
classLayoutItem:
15-
ft_object:FT2Font
16-
char:str
17-
glyph_idx:int
18-
x:float
19-
prev_kern:float
8+
from .ft2fontimportKerning,LoadFlags
209

2110

2211
defwarn_on_missing_glyph(codepoint,fontnames):
@@ -46,20 +35,6 @@ def layout(string, font, *, kern_mode=Kerning.DEFAULT):
4635
------
4736
LayoutItem
4837
"""
49-
x=0
50-
prev_glyph_idx=None
51-
char_to_font=font._get_fontmap(string)
52-
base_font=font
53-
forcharinstring:
54-
# This has done the fallback logic
55-
font=char_to_font.get(char,base_font)
56-
glyph_idx=font.get_char_index(ord(char))
57-
kern= (
58-
base_font.get_kerning(prev_glyph_idx,glyph_idx,kern_mode)/64
59-
ifprev_glyph_idxisnotNoneelse0.
60-
)
61-
x+=kern
62-
glyph=font.load_glyph(glyph_idx,flags=LoadFlags.NO_HINTING)
63-
yieldLayoutItem(font,char,glyph_idx,x,kern)
64-
x+=glyph.linearHoriAdvance/65536
65-
prev_glyph_idx=glyph_idx
38+
forraqm_iteminfont._layout(string,LoadFlags.NO_HINTING):
39+
raqm_item.ft_object.load_glyph(raqm_item.glyph_idx,flags=LoadFlags.NO_HINTING)
40+
yieldraqm_item

‎lib/matplotlib/backends/backend_ps.py

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -796,19 +796,18 @@ def draw_text(self, gc, x, y, s, prop, angle, ismath=False, mtext=None):
796796

797797
else:
798798
font=self._get_font_ttf(prop)
799-
self._character_tracker.track(font,s)
800799
foritemin_text_helpers.layout(s,font):
800+
self._character_tracker.track_glyph(item.font,item.glyph_idx)
801801
ps_name= (item.ft_object.postscript_name
802802
.encode("ascii","replace").decode("ascii"))
803803
glyph_name=item.ft_object.get_glyph_name(item.glyph_idx)
804-
stream.append((ps_name,item.x,glyph_name))
804+
stream.append((ps_name,item.x,item.y,glyph_name))
805805
self.set_color(*gc.get_rgb())
806806

807-
forps_name,groupinitertools. \
808-
groupby(stream,lambdaentry:entry[0]):
807+
forps_name,groupinitertools.groupby(stream,lambdaentry:entry[0]):
809808
self.set_font(ps_name,prop.get_size_in_points(),False)
810-
thetext="\n".join(f"{x:g}0 m /{name:s} glyphshow"
811-
for_,x,nameingroup)
809+
thetext="\n".join(f"{x:g}{y:g} m /{name:s} glyphshow"
810+
for_,x,y,nameingroup)
812811
self._pswriter.write(f"""\
813812
gsave
814813
{self._get_clip_cmd(gc)}

‎lib/matplotlib/textpath.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -144,15 +144,16 @@ def get_glyphs_with_font(self, font, s, glyph_map=None,
144144
glyph_map_new=glyph_map
145145

146146
xpositions= []
147+
ypositions= []
147148
glyph_ids= []
148149
foritemin_text_helpers.layout(s,font):
149150
char_id=self._get_char_id(item.ft_object,ord(item.char))
150151
glyph_ids.append(char_id)
151152
xpositions.append(item.x)
153+
ypositions.append(item.y)
152154
ifchar_idnotinglyph_map:
153155
glyph_map_new[char_id]=item.ft_object.get_path()
154156

155-
ypositions= [0]*len(xpositions)
156157
sizes= [1.]*len(xpositions)
157158

158159
rects= []

‎src/ft2font.h

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -143,6 +143,16 @@ class FT2Font
143143
returnFT_HAS_KERNING(face);
144144
}
145145

146+
voidset_parent(void *parent)
147+
{
148+
_parent = parent;
149+
}
150+
151+
void *get_parent()const
152+
{
153+
return _parent;
154+
}
155+
146156
private:
147157
WarnFunc ft_glyph_warn;
148158
bool warn_if_used;
@@ -158,6 +168,9 @@ class FT2Font
158168
long hinting_factor;
159169
int kerning_factor;
160170

171+
// Holds the parent PyFT2Font object.
172+
void *_parent;
173+
161174
// prevent copying
162175
FT2Font(const FT2Font &);
163176
FT2Font &operator=(const FT2Font &);

‎src/ft2font_wrapper.cpp

Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -499,6 +499,7 @@ PyFT2Font_init(py::object filename, long hinting_factor = 8,
499499

500500
self->x =newFT2Font(open_args, hinting_factor, fallback_fonts, ft_glyph_warn,
501501
warn_if_used);
502+
self->x->set_parent(self);
502503

503504
self->x->set_kerning_factor(kerning_factor);
504505

@@ -1471,6 +1472,81 @@ PyFT2Font__get_type1_encoding_vector(PyFT2Font *self)
14711472
return indices;
14721473
}
14731474

1475+
/**********************************************************************
1476+
* Layout items
1477+
**/
1478+
1479+
structLayoutItem {
1480+
PyFT2Font *ft_object;
1481+
std::u32string character;
1482+
int glyph_idx;
1483+
double x;
1484+
double y;
1485+
double prev_kern;
1486+
1487+
LayoutItem(PyFT2Font *f, std::u32string c,int i,double x,double y,double k) :
1488+
ft_object(f), character(c), glyph_idx(i), x(x), y(y), prev_kern(k) {}
1489+
1490+
std::stringto_string()
1491+
{
1492+
std::ostringstream out;
1493+
out <<"LayoutItem(ft_object=" <<PyFT2Font_fname(ft_object);
1494+
out <<", char=" << character[0];
1495+
out <<", glyph_idx=" << glyph_idx;
1496+
out <<", x=" << x;
1497+
out <<", y=" << y;
1498+
out <<", prev_kern=" << prev_kern;
1499+
out <<")";
1500+
return out.str();
1501+
}
1502+
};
1503+
1504+
constchar *PyFT2Font_layout__doc__ =R"""(
1505+
Layout a string and yield information about each used glyph.
1506+
1507+
.. warning::
1508+
This API uses the fallback list and is both private and provisional: do not use
1509+
it directly.
1510+
1511+
Parameters
1512+
----------
1513+
text : str
1514+
The characters for which to find fonts.
1515+
1516+
Returns
1517+
-------
1518+
list[LayoutItem]
1519+
)""";
1520+
1521+
staticauto
1522+
PyFT2Font_layout(PyFT2Font *self, std::u32string text, LoadFlags flags)
1523+
{
1524+
auto load_flags =static_cast<FT_Int32>(flags);
1525+
1526+
std::set<FT_String*> glyph_seen_fonts;
1527+
std::vector<raqm_glyph_t> glyphs;
1528+
self->x->layout(text, load_flags, glyph_seen_fonts, glyphs);
1529+
1530+
std::vector<LayoutItem> items;
1531+
1532+
double x =0.0;
1533+
double y =0.0;
1534+
for (auto &glyph : glyphs) {
1535+
auto ft_object =static_cast<FT2Font *>(glyph.ftface->generic.data);
1536+
auto pyft_object =static_cast<PyFT2Font *>(ft_object->get_parent());
1537+
items.emplace_back(pyft_object, text.substr(glyph.cluster,1), glyph.index,
1538+
(x + glyph.x_offset) /64, (y + glyph.y_offset) /64,0);
1539+
x += glyph.x_advance;
1540+
y += glyph.y_advance;
1541+
}
1542+
1543+
return items;
1544+
}
1545+
1546+
/**********************************************************************
1547+
* Deprecations
1548+
**/
1549+
14741550
static py::object
14751551
ft2font__getattr__(std::string name) {
14761552
auto api =py::module_::import("matplotlib._api");
@@ -1601,6 +1677,21 @@ PYBIND11_MODULE(ft2font, m, py::mod_gil_not_used())
16011677
.def_property_readonly("bbox", &PyGlyph_get_bbox,
16021678
"The control box of the glyph.");
16031679

1680+
py::class_<LayoutItem>(m,"LayoutItem",py::is_final())
1681+
.def_readonly("ft_object", &LayoutItem::ft_object,
1682+
"The FT_Face of the item.")
1683+
.def_readonly("char", &LayoutItem::character,
1684+
"The character code for the item.")
1685+
.def_readonly("glyph_idx", &LayoutItem::glyph_idx,
1686+
"The glyph index for the item.")
1687+
.def_readonly("x", &LayoutItem::x,
1688+
"The x position of the item.")
1689+
.def_readonly("y", &LayoutItem::y,
1690+
"The y position of the item.")
1691+
.def_readonly("prev_kern", &LayoutItem::prev_kern,
1692+
"The kerning between this item and the previous one.")
1693+
.def("__str__", &LayoutItem::to_string);
1694+
16041695
py::class_<PyFT2Font>(m,"FT2Font",py::is_final(),py::buffer_protocol(),
16051696
PyFT2Font__doc__)
16061697
.def(py::init(&PyFT2Font_init),
@@ -1617,6 +1708,8 @@ PYBIND11_MODULE(ft2font, m, py::mod_gil_not_used())
16171708
PyFT2Font_select_charmap__doc__)
16181709
.def("get_kerning", &PyFT2Font_get_kerning,"left"_a,"right"_a,"mode"_a,
16191710
PyFT2Font_get_kerning__doc__)
1711+
.def("_layout", &PyFT2Font_layout,"string"_a,"flags"_a,
1712+
PyFT2Font_layout__doc__)
16201713
.def("set_text", &PyFT2Font_set_text,
16211714
"string"_a,"angle"_a=0.0,"flags"_a=LoadFlags::FORCE_AUTOHINT,
16221715
PyFT2Font_set_text__doc__)

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp