Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 535fdaa

Browse files
committed
Keep mathtext boxes in xywh representation throughout.
Previously, mathtext boxes would swap between xywh and x1y1x2y2 representation in the code: ship() uses xywh, calls Rule.render() which converts to x1y1x2y2 and stores in Output.rects in that format; then Output.to_vector() would convert back to xywh (while also swapping downwards y's to upwards y's). Instead, stick to xywh representation throughout (the rectangle always goes from x to x+w and y to y+h, regardless of whether y is upwards or downwards). No actual calculation is changed. Also remove an incorrect comment in RendererAgg.draw_mathtext: "dy" (i.e., y) isn't at the rect top side, but actually usually the bottom one; in any case, again it always goes from dy to dy+h.
1 parent d0df260 commit 535fdaa

2 files changed

Lines changed: 19 additions & 18 deletions

File tree

lib/matplotlib/_mathtext.py

Lines changed: 18 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -127,29 +127,30 @@ class Output:
127127
def __init__(self, box: Box):
128128
self.box = box
129129
self.glyphs: list[tuple[float, float, FontInfo]] = [] # (ox, oy, info)
130-
self.rects: list[tuple[float, float, float, float]] = [] # (x1, y1, x2, y2)
130+
self.rects: list[tuple[float, float, float, float]] = [] # (x, y, w, h)
131131

132132
def to_vector(self) -> VectorParse:
133133
w, h, d = map(
134134
np.ceil, [self.box.width, self.box.height, self.box.depth])
135135
gs = [(info.font, info.fontsize, info.num, info.glyph_index,
136136
ox, h - oy + info.offset)
137137
for ox, oy, info in self.glyphs]
138-
rs = [(x1, h - y2, x2 - x1, y2 - y1)
139-
for x1, y1, x2, y2 in self.rects]
138+
rs = [(bx, h - (by + bh), bw, bh)
139+
for bx, by, bw, bh in self.rects]
140+
# Output.rects has downwards ys, VectorParse.rects has upwards ys.
140141
return VectorParse(w, h + d, d, gs, rs)
141142

142143
def to_raster(self, *, antialiased: bool) -> RasterParse:
143144
# Metrics y's and mathtext y's are oriented in opposite directions,
144145
# hence the switch between ymin and ymax.
145146
xmin = min([*[ox + info.metrics.xmin for ox, oy, info in self.glyphs],
146-
*[x1 for x1, y1, x2, y2 in self.rects], 0]) - 1
147+
*[x for x, y, w, h in self.rects], 0]) - 1
147148
ymin = min([*[oy - info.metrics.ymax for ox, oy, info in self.glyphs],
148-
*[y1 for x1, y1, x2, y2 in self.rects], 0]) - 1
149+
*[y for x, y, w, h in self.rects], 0]) - 1
149150
xmax = max([*[ox + info.metrics.xmax for ox, oy, info in self.glyphs],
150-
*[x2 for x1, y1, x2, y2 in self.rects], 0]) + 1
151+
*[x + w for x, y, w, h in self.rects], 0]) + 1
151152
ymax = max([*[oy - info.metrics.ymin for ox, oy, info in self.glyphs],
152-
*[y2 for x1, y1, x2, y2 in self.rects], 0]) + 1
153+
*[y + h for x, y, w, h in self.rects], 0]) + 1
153154
w = xmax - xmin
154155
h = ymax - ymin - self.box.depth
155156
d = ymax - ymin - self.box.height
@@ -165,15 +166,15 @@ def to_raster(self, *, antialiased: bool) -> RasterParse:
165166
info.font.draw_glyph_to_bitmap(
166167
image, int(ox), int(oy - info.metrics.iceberg), info.glyph,
167168
antialiased=antialiased)
168-
for x1, y1, x2, y2 in shifted.rects:
169-
height = max(int(y2 - y1) - 1, 0)
169+
for x, y, bw, bh in shifted.rects:
170+
height = max(int(bh) - 1, 0)
170171
if height == 0:
171-
center = (y2 + y1) / 2
172+
center = y + bh / 2
172173
y = int(center - (height + 1) / 2)
173174
else:
174-
y = int(y1)
175-
x1 = math.floor(x1)
176-
x2 = math.ceil(x2)
175+
y = int(y)
176+
x1 = math.floor(x)
177+
x2 = math.ceil(x + bw)
177178
image[y:y+height+1, x1:x2+1] = 0xff
178179
return RasterParse(0, 0, w, h + d, d, image)
179180

@@ -299,11 +300,11 @@ def render_glyph(self, output: Output, ox: float, oy: float, font: str,
299300
output.glyphs.append((ox, oy, info))
300301

301302
def render_rect_filled(self, output: Output,
302-
x1: float, y1: float, x2: float, y2: float) -> None:
303+
x: float, y: float, w: float, h: float) -> None:
303304
"""
304-
Draw a filled rectangle from (*x1*, *y1*) to (*x2*, *y2*).
305+
Draw a filled rectangle at (*x*, *y*) with size (*w*, *h*).
305306
"""
306-
output.rects.append((x1, y1, x2, y2))
307+
output.rects.append((x, y, w, h))
307308

308309
def get_xheight(self, font: str, fontsize: float, dpi: float) -> float:
309310
"""
@@ -1385,7 +1386,7 @@ def __init__(self, width: float, height: float, depth: float, state: ParserState
13851386

13861387
def render(self, output: Output, # type: ignore[override]
13871388
x: float, y: float, w: float, h: float) -> None:
1388-
self.fontset.render_rect_filled(output, x, y, x + w, y + h)
1389+
self.fontset.render_rect_filled(output, x, y, w, h)
13891390

13901391

13911392
class Hrule(Rule):

lib/matplotlib/backends/backend_agg.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -205,7 +205,7 @@ def draw_mathtext(self, gc, x, y, s, prop, angle):
205205
gc1 = self.new_gc()
206206
gc1.set_linewidth(0)
207207
gc1.set_snap(gc.get_snap())
208-
for dx, dy, w, h in parse.rects: # dy is upwards & the rect top side.
208+
for dx, dy, w, h in parse.rects: # dy is upwards.
209209
if gc1.get_snap() in [None, True]:
210210
# Prevent thin bars from disappearing by growing symmetrically.
211211
if w < 1:

0 commit comments

Comments
 (0)