Skip to content

Commit 23c7a30

Browse files
committed
Improvements to layout
1 parent cd0137f commit 23c7a30

File tree

7 files changed

+66
-19
lines changed

7 files changed

+66
-19
lines changed

docstrings/bbox.py

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,8 +54,13 @@
5454
x_min, y_min, x_max, y_max = bbox
5555
"""
5656

57+
BBox_ascent = """
58+
The height of the bounding box above the baseline. This is an alias
59+
for `y_max`.
60+
"""
61+
5762
BBox_depth = """
58-
The depth of the bounding box beneath the baseline. This is an alias
63+
The depth of the bounding box below the baseline. This is an alias
5964
for `y_min`.
6065
"""
6166

docstrings/layout.py

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -49,8 +49,15 @@
4949
The size of the text, in pixels.
5050
"""
5151

52-
Layout_bbox = """
53-
Get the bounding box of the layout.
52+
Layout_ink_bbox = """
53+
Get the tight bounding box (`BBox`) of the physical characters in the
54+
layout. The origin is at (0, 0). The result is in pixels.
55+
"""
56+
57+
Layout_layout_bbox = """
58+
Get the logical bounding box (`BBox`) of the layout. This should be
59+
used to manage the layout of the text against other text. The result
60+
is in pixels.
5461
"""
5562

5663
Layout_glyph_indices = """

lib/freetypy/tests/test_layout.py

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -41,11 +41,12 @@ def test_layout():
4141
layout = ft.Layout(
4242
face, "The quick brown fox jumped over the lazy dog")
4343

44-
assert layout.bbox.width == 553.984375
45-
assert layout.bbox.height == 23.0
46-
assert layout.bbox.y_min == -5.0
44+
assert layout.ink_bbox.width == 553.984375
45+
assert layout.ink_bbox.ascent == 18.0
46+
assert layout.ink_bbox.depth == -5.0
47+
48+
assert tuple(layout.layout_bbox) == (0.0, -6.0, 555.984375, 22.0)
4749

48-
print(layout.glyph_indices.to_list())
4950
assert layout.glyph_indices.to_list() == [
5051
55, 75, 72, 3, 84, 88, 76, 70, 78, 3, 69, 85, 82, 90, 81, 3,
5152
73, 82, 91, 3, 77, 88, 80, 83, 72, 71, 3, 82, 89, 72, 85, 3,

src/bbox.c

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,12 @@ Py_BBox_init(Py_BBox *self, PyObject *args, PyObject *kwds)
101101
*/
102102

103103

104+
static PyObject *ascent_get(Py_BBox *self, PyObject *closure)
105+
{
106+
return PyFloat_FromDouble(self->yMax);
107+
}
108+
109+
104110
static PyObject *depth_get(Py_BBox *self, PyObject *closure)
105111
{
106112
return PyFloat_FromDouble(self->yMin);
@@ -109,7 +115,7 @@ static PyObject *depth_get(Py_BBox *self, PyObject *closure)
109115

110116
static PyObject *height_get(Py_BBox *self, PyObject *closure)
111117
{
112-
return PyFloat_FromDouble(self->yMax);
118+
return PyFloat_FromDouble(self->yMax - self->yMin);
113119
}
114120

115121

@@ -120,9 +126,11 @@ static PyObject *width_get(Py_BBox *self, PyObject *closure)
120126

121127

122128
static PyGetSetDef Py_BBox_getset[] = {
129+
DEF_BBOX_GETTER(ascent),
123130
DEF_BBOX_GETTER(depth),
124131
DEF_BBOX_GETTER(height),
125132
DEF_BBOX_GETTER(width),
133+
{NULL}
126134
};
127135

128136

src/layout.c

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -139,9 +139,14 @@ Py_Layout_init(Py_Layout *self, PyObject *args, PyObject *kwds)
139139
*/
140140

141141

142-
static PyObject *bbox_get(Py_Layout *self, PyObject *closure)
142+
static PyObject *ink_bbox_get(Py_Layout *self, PyObject *closure)
143143
{
144-
return Py_BBox_cnew(&self->x.bbox, 1.0 / (double)(1 << 6));
144+
return Py_BBox_cnew(&self->x.ink_bbox, 1.0 / (double)(1 << 6));
145+
}
146+
147+
static PyObject *layout_bbox_get(Py_Layout *self, PyObject *closure)
148+
{
149+
return Py_BBox_cnew(&self->x.layout_bbox, 1.0 / (double)(1 << 6));
145150
}
146151

147152

@@ -158,9 +163,11 @@ static PyObject *points_get(Py_Layout *self, PyObject *closure)
158163

159164

160165
static PyGetSetDef Py_Layout_getset[] = {
161-
DEF_LAYOUT_GETTER(bbox),
166+
DEF_LAYOUT_GETTER(ink_bbox),
167+
DEF_LAYOUT_GETTER(layout_bbox),
162168
DEF_LAYOUT_GETTER(glyph_indices),
163169
DEF_LAYOUT_GETTER(points),
170+
{NULL}
164171
};
165172

166173

src/simple_layout.c

Lines changed: 25 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,8 @@ of the authors and should not be interpreted as representing official policies,
2727
either expressed or implied, of the FreeBSD Project.
2828
*/
2929

30+
#include <limits.h>
31+
3032
#include "simple_layout.h"
3133

3234
#define FROM_FT_FIXED(v) (((double)(v) / (double)(1 << 16)))
@@ -61,8 +63,13 @@ FT_Error ftpy_calculate_simple_layout(
6163

6264
layout->size = text_length;
6365

64-
layout->bbox.xMin = layout->bbox.yMin = 0;
65-
layout->bbox.xMax = layout->bbox.yMax = 0;
66+
layout->layout_bbox.xMin = 0;
67+
layout->layout_bbox.xMax = 0;
68+
layout->layout_bbox.yMax = face->size->metrics.ascender;
69+
layout->layout_bbox.yMin = face->size->metrics.descender;
70+
71+
layout->ink_bbox.xMin = layout->ink_bbox.yMin = LONG_MAX;
72+
layout->ink_bbox.xMax = layout->ink_bbox.yMax = LONG_MIN;
6673

6774
use_kerning = FT_HAS_KERNING(face);
6875
pen.x = 0;
@@ -98,22 +105,33 @@ FT_Error ftpy_calculate_simple_layout(
98105
layout->xys[i].x = FROM_FT_FIXED(pen.x);
99106
layout->xys[i].y = FROM_FT_FIXED(pen.y);
100107

101-
/* TODO: Bounding box should be calculated from advance width */
102108
FT_Outline_Get_BBox(&((FT_OutlineGlyph)glyph)->outline, &glyph_bbox);
103109
glyph_bbox.xMin += pen.x >> 10;
104110
glyph_bbox.yMin += pen.y >> 10;
105111
glyph_bbox.xMax += pen.x >> 10;
106112
glyph_bbox.yMax += pen.y >> 10;
107-
if (glyph_bbox.xMin < layout->bbox.xMin) layout->bbox.xMin = glyph_bbox.xMin;
108-
if (glyph_bbox.yMin < layout->bbox.yMin) layout->bbox.yMin = glyph_bbox.yMin;
109-
if (glyph_bbox.xMax > layout->bbox.xMax) layout->bbox.xMax = glyph_bbox.xMax;
110-
if (glyph_bbox.yMax > layout->bbox.yMax) layout->bbox.yMax = glyph_bbox.yMax;
113+
if (glyph_bbox.xMin < layout->ink_bbox.xMin)
114+
layout->ink_bbox.xMin = glyph_bbox.xMin;
115+
if (glyph_bbox.yMin < layout->ink_bbox.yMin)
116+
layout->ink_bbox.yMin = glyph_bbox.yMin;
117+
if (glyph_bbox.xMax > layout->ink_bbox.xMax)
118+
layout->ink_bbox.xMax = glyph_bbox.xMax;
119+
if (glyph_bbox.yMax > layout->ink_bbox.yMax)
120+
layout->ink_bbox.yMax = glyph_bbox.yMax;
111121

112122
pen.x += glyph->advance.x;
123+
layout->layout_bbox.xMax = pen.x >> 10;
113124

114125
previous_glyph_index = glyph_index;
115126
}
116127

128+
/* layout->ink_bbox.xMin &= 0xffffffc0; */
129+
/* layout->ink_bbox.yMin &= 0xffffffc0; */
130+
/* layout->ink_bbox.xMax += 1 << 6; */
131+
/* layout->ink_bbox.xMax &= 0xffffffc0; */
132+
/* layout->ink_bbox.yMax += 1 << 6; */
133+
/* layout->ink_bbox.yMax &= 0xffffffc0; */
134+
117135
status = 0;
118136

119137
exit:

src/simple_layout.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,8 @@ typedef struct {
4949
size_t size;
5050
FT_ULong *glyph_indices;
5151
ftpy_Layout_Vector *xys;
52-
FT_BBox bbox;
52+
FT_BBox layout_bbox;
53+
FT_BBox ink_bbox;
5354
} ftpy_Layout;
5455

5556

0 commit comments

Comments
 (0)