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

Commitb241ca4

Browse files
committed
Rasterize dvi files without dvipng.
This patch drops the reliance on dvipng to rasterize dvi files prior toinclusion by agg, instead performing the rasterization ourselves (as aconsequence, the rasterization output also becomes dependent of thefreetype version used). Note that this approach will be needed anywaysto support xetex and luatex, as dvipng doesn't support dvi filesgenerated by these engines.Baseline images change slightly, for the better or the worse. Thetop-left blue cross text in test_rotation.py ("Myrt0") seems to bebetter top-aligned against the blue line (the old version overshot abit); the bounding box of the formulas in test_usetex.py seems a bitworse.
1 parentde00c49 commitb241ca4

File tree

7 files changed

+125
-10
lines changed

7 files changed

+125
-10
lines changed

‎lib/matplotlib/backends/backend_agg.py

Lines changed: 40 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
"""
2323

2424
fromcontextlibimportnullcontext
25+
importmath
2526
frommathimportradians,cos,sin
2627

2728
importnumpyasnp
@@ -30,8 +31,9 @@
3031
frommatplotlibimport_api,cbook
3132
frommatplotlib.backend_basesimport (
3233
_Backend,FigureCanvasBase,FigureManagerBase,RendererBase)
34+
frommatplotlib.dvireadimportDvi
3335
frommatplotlib.font_managerimportfontManageras_fontManager,get_font
34-
frommatplotlib.ft2fontimportLoadFlags
36+
frommatplotlib.ft2fontimportFT2Image,LoadFlags
3537
frommatplotlib.mathtextimportMathTextParser
3638
frommatplotlib.pathimportPath
3739
frommatplotlib.transformsimportBbox,BboxBase
@@ -208,7 +210,8 @@ def get_text_width_height_descent(self, s, prop, ismath):
208210

209211
_api.check_in_list(["TeX",True,False],ismath=ismath)
210212
ifismath=="TeX":
211-
returnsuper().get_text_width_height_descent(s,prop,ismath)
213+
return [*map(
214+
math.ceil,super().get_text_width_height_descent(s,prop,ismath))]
212215

213216
ifismath:
214217
ox,oy,width,height,descent,font_image= \
@@ -227,19 +230,47 @@ def get_text_width_height_descent(self, s, prop, ismath):
227230
defdraw_tex(self,gc,x,y,s,prop,angle,*,mtext=None):
228231
# docstring inherited
229232
# todo, handle props, angle, origins
230-
size=prop.get_size_in_points()
231-
232-
texmanager=self.get_texmanager()
233233

234-
Z=texmanager.get_grey(s,size,self.dpi)
235-
Z=np.array(Z*255.0,np.uint8)
234+
size=prop.get_size_in_points()
235+
dvifile=self.get_texmanager().make_dvi(s,size)
236+
withDvi(dvifile,self.dpi)asdvi:
237+
page,=dvi
238+
w=math.ceil(page.width)
239+
h=math.ceil(page.height)
240+
d=math.ceil(page.descent)
241+
242+
image=FT2Image(w,h+d)
243+
244+
fortextinpage.text:
245+
hf=mpl.rcParams["text.hinting_factor"]
246+
font=get_font(text.font_path)
247+
font.set_size(text.font_size,self.dpi)
248+
slant=text.font_effects.get("slant",0)
249+
extend=text.font_effects.get("extend",1)
250+
matrix= [
251+
[round(65536*extend/hf),round(65536*extend*slant)],
252+
[0,65536],
253+
]
254+
font.set_transform(matrix, [0,0])
255+
glyph=font.load_glyph(text.index)
256+
# text.y is upwards from baseline, _draw_glyph_at wants upwards from bottom.
257+
font._draw_glyph_at(image,text.x,d+text.y,glyph,
258+
antialiased=gc.get_antialiased())
259+
260+
image=np.asarray(image)
261+
262+
forboxinpage.boxes:
263+
x0=round(box.x)
264+
x1=x0+max(round(box.width),1)
265+
y1=round(h-box.y)
266+
y0=y1-max(round(box.height),1)
267+
image[y0:y1,x0:x1]=0xff
236268

237-
w,h,d=self.get_text_width_height_descent(s,prop,ismath="TeX")
238269
xd=d*sin(radians(angle))
239270
yd=d*cos(radians(angle))
240271
x=round(x+xd)
241272
y=round(y+yd)
242-
self._renderer.draw_text_image(Z,x,y,angle,gc)
273+
self._renderer.draw_text_image(image,x,y,angle,gc)
243274

244275
defget_canvas_width_height(self):
245276
# docstring inherited
Loading

‎src/ft2font.cpp

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -334,6 +334,17 @@ void FT2Font::set_size(double ptsize, double dpi)
334334
}
335335
}
336336

337+
voidFT2Font::set_transform(
338+
std::array<std::array<FT_Fixed,2>,2> matrix, std::array<FT_Fixed,2> delta)
339+
{
340+
FT_Matrix m = {matrix[0][0], matrix[0][1], matrix[1][0], matrix[1][1]};
341+
FT_Vector d = {delta[0], delta[1]};
342+
FT_Set_Transform(face, &m, &d);
343+
for (auto & fallback : fallbacks) {
344+
fallback->set_transform(matrix, delta);
345+
}
346+
}
347+
337348
voidFT2Font::set_charmap(int i)
338349
{
339350
if (i >= face->num_charmaps) {
@@ -721,6 +732,25 @@ void FT2Font::draw_glyph_to_bitmap(FT2Image &im, int x, int y, size_t glyphInd,
721732
im.draw_bitmap(&bitmap->bitmap, x + bitmap->left, y);
722733
}
723734

735+
voidFT2Font::draw_glyph_at(FT2Image &im,double x,double y,size_t glyphInd,bool antialiased)
736+
{
737+
if (glyphInd >= glyphs.size()) {
738+
throwstd::runtime_error("glyph num is out of range");
739+
}
740+
FT_Vector sub_offset = {FT_Fixed(x *64 + .5),FT_Fixed(y *64 + .5)};
741+
FT_Error error =FT_Glyph_To_Bitmap(
742+
&glyphs[glyphInd],
743+
antialiased ? FT_RENDER_MODE_NORMAL : FT_RENDER_MODE_MONO,
744+
&sub_offset,// additional translation
745+
1// destroy image
746+
);
747+
if (error) {
748+
throw_ft_error("Could not convert glyph to bitmap", error);
749+
}
750+
FT_BitmapGlyph bitmap = (FT_BitmapGlyph)glyphs[glyphInd];
751+
im.draw_bitmap(&bitmap->bitmap, bitmap->left, im.get_height() - bitmap->top);
752+
}
753+
724754
voidFT2Font::get_glyph_name(unsignedint glyph_number, std::string &buffer,
725755
bool fallback =false)
726756
{

‎src/ft2font.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,8 @@ class FT2Font
7676
virtual~FT2Font();
7777
voidclear();
7878
voidset_size(double ptsize,double dpi);
79+
voidset_transform(
80+
std::array<std::array<FT_Fixed,2>,2> matrix, std::array<FT_Fixed,2> delta);
7981
voidset_charmap(int i);
8082
voidselect_charmap(unsignedlong i);
8183
voidset_text(std::u32string_view codepoints,double angle, FT_Int32 flags,
@@ -102,6 +104,7 @@ class FT2Font
102104
longget_descent();
103105
voiddraw_glyphs_to_bitmap(bool antialiased);
104106
voiddraw_glyph_to_bitmap(FT2Image &im,int x,int y,size_t glyphInd,bool antialiased);
107+
voiddraw_glyph_at(FT2Image &im,double x,double y,size_t glyphInd,bool antialiased);
105108
voidget_glyph_name(unsignedint glyph_number, std::string &buffer,bool fallback);
106109
longget_name_index(char *name);
107110
FT_UIntget_char_index(FT_ULong charcode,bool fallback);

‎src/ft2font_wrapper.cpp

Lines changed: 52 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -541,6 +541,25 @@ PyFT2Font_set_size(PyFT2Font *self, double ptsize, double dpi)
541541
self->x->set_size(ptsize, dpi);
542542
}
543543

544+
constchar *PyFT2Font_set_transform__doc__ =R"""(
545+
Set the transform of the text.
546+
547+
This is a low-level function directly taking inputs in 26.6 format. Refer
548+
to the FreeType docs of FT_Set_Transform for further description.
549+
550+
Parameters
551+
----------
552+
matrix : (2, 2) array of FT_Fixed
553+
delta : (2,) array of FT_Fixed
554+
)""";
555+
556+
staticvoid
557+
PyFT2Font_set_transform(
558+
PyFT2Font *self, std::array<std::array<FT_Fixed,2>,2> matrix, std::array<FT_Fixed,2> delta)
559+
{
560+
self->x->set_transform(matrix, delta);
561+
}
562+
544563
constchar *PyFT2Font_set_charmap__doc__ =R"""(
545564
Make the i-th charmap current.
546565
@@ -971,7 +990,7 @@ const char *PyFT2Font_draw_glyph_to_bitmap__doc__ = R"""(
971990
image : FT2Image
972991
The image buffer on which to draw the glyph.
973992
x, y : int
974-
Thepixel location at which to draw the glyph.
993+
Theposition of the glyph's top left corner.
975994
glyph : Glyph
976995
The glyph to draw.
977996
antialiased : bool, default: True
@@ -993,6 +1012,34 @@ PyFT2Font_draw_glyph_to_bitmap(PyFT2Font *self, FT2Image &image,
9931012
self->x->draw_glyph_to_bitmap(image, xd, yd, glyph->glyphInd, antialiased);
9941013
}
9951014

1015+
constchar *PyFT2Font__draw_glyph_at__doc__ =R"""(
1016+
Draw a single glyph to the bitmap at pixel locations x, y.
1017+
1018+
Parameters
1019+
----------
1020+
image : FT2Image
1021+
The image buffer on which to draw the glyph. If the buffer is too
1022+
small, the glyph will be cropped.
1023+
x, y : float
1024+
The position of the glyph's origin.
1025+
glyph : Glyph
1026+
The glyph to draw.
1027+
antialiased : bool, default: True
1028+
Whether to render glyphs 8-bit antialiased or in pure black-and-white.
1029+
1030+
See Also
1031+
--------
1032+
.draw_glyphs_to_bitmap
1033+
)""";
1034+
1035+
staticvoid
1036+
PyFT2Font__draw_glyph_at(PyFT2Font *self, FT2Image &image,
1037+
double x,double y,
1038+
PyGlyph *glyph,bool antialiased =true)
1039+
{
1040+
self->x->draw_glyph_at(image, x, y, glyph->glyphInd, antialiased);
1041+
}
1042+
9961043
constchar *PyFT2Font_get_glyph_name__doc__ =R"""(
9971044
Retrieve the ASCII name of a given glyph *index* in a face.
9981045
@@ -1614,6 +1661,7 @@ PYBIND11_MODULE(ft2font, m, py::mod_gil_not_used())
16141661
.def("clear", &PyFT2Font_clear, PyFT2Font_clear__doc__)
16151662
.def("set_size", &PyFT2Font_set_size,"ptsize"_a,"dpi"_a,
16161663
PyFT2Font_set_size__doc__)
1664+
.def("set_transform", &PyFT2Font_set_transform,"matrix"_a,"delta"_a)
16171665
.def("set_charmap", &PyFT2Font_set_charmap,"i"_a,
16181666
PyFT2Font_set_charmap__doc__)
16191667
.def("select_charmap", &PyFT2Font_select_charmap,"i"_a,
@@ -1643,6 +1691,9 @@ PYBIND11_MODULE(ft2font, m, py::mod_gil_not_used())
16431691
.def("draw_glyph_to_bitmap", &PyFT2Font_draw_glyph_to_bitmap,
16441692
"image"_a,"x"_a,"y"_a,"glyph"_a,py::kw_only(),"antialiased"_a=true,
16451693
PyFT2Font_draw_glyph_to_bitmap__doc__)
1694+
.def("_draw_glyph_at", &PyFT2Font__draw_glyph_at,
1695+
"image"_a,"x"_a,"y"_a,"glyph"_a,py::kw_only(),"antialiased"_a=true,
1696+
PyFT2Font__draw_glyph_at__doc__)
16461697
.def("get_glyph_name", &PyFT2Font_get_glyph_name,"index"_a,
16471698
PyFT2Font_get_glyph_name__doc__)
16481699
.def("get_charmap", &PyFT2Font_get_charmap, PyFT2Font_get_charmap__doc__)

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp