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

Appearance settings

Commit 9765ea1

Browse filesBrowse files
committed
Use std::vector directly with FT_Outline_Decompose
This means we only need to do one pass through.
1 parent 5f2a89a commit 9765ea1
Copy full SHA for 9765ea1

File tree

Expand file treeCollapse file tree

1 file changed

+45
-63
lines changed
Filter options
Expand file treeCollapse file tree

1 file changed

+45
-63
lines changed

‎src/ft2font.cpp

Copy file name to clipboardExpand all lines: src/ft2font.cpp
+45-63Lines changed: 45 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -183,64 +183,49 @@ FT2Image::draw_rect_filled(unsigned long x0, unsigned long y0, unsigned long x1,
183183
m_dirty = true;
184184
}
185185

186-
// ft_outline_decomposer should be passed to FT_Outline_Decompose. On the
187-
// first pass, vertices and codes are set to NULL, and index is simply
188-
// incremented for each vertex that should be inserted, so that it is set, at
189-
// the end, to the total number of vertices. On a second pass, vertices and
190-
// codes should point to correctly sized arrays, and index set again to zero,
191-
// to get fill vertices and codes with the outline decomposition.
186+
// ft_outline_decomposer should be passed to FT_Outline_Decompose.
192187
struct ft_outline_decomposer
193188
{
194-
int index;
195-
double* vertices;
196-
unsigned char* codes;
189+
std::vector<double> &vertices;
190+
std::vector<unsigned char> &codes;
197191
};
198192

199193
static int
200194
ft_outline_move_to(FT_Vector const* to, void* user)
201195
{
202196
ft_outline_decomposer* d = reinterpret_cast<ft_outline_decomposer*>(user);
203-
if (d->codes) {
204-
if (d->index) {
205-
// Appending CLOSEPOLY is important to make patheffects work.
206-
*(d->vertices++) = 0;
207-
*(d->vertices++) = 0;
208-
*(d->codes++) = CLOSEPOLY;
209-
}
210-
*(d->vertices++) = to->x * (1. / 64.);
211-
*(d->vertices++) = to->y * (1. / 64.);
212-
*(d->codes++) = MOVETO;
213-
}
214-
d->index += d->index ? 2 : 1;
197+
if (!d->vertices.empty()) {
198+
// Appending CLOSEPOLY is important to make patheffects work.
199+
d->vertices.push_back(0);
200+
d->vertices.push_back(0);
201+
d->codes.push_back(CLOSEPOLY);
202+
}
203+
d->vertices.push_back(to->x * (1. / 64.));
204+
d->vertices.push_back(to->y * (1. / 64.));
205+
d->codes.push_back(MOVETO);
215206
return 0;
216207
}
217208

218209
static int
219210
ft_outline_line_to(FT_Vector const* to, void* user)
220211
{
221212
ft_outline_decomposer* d = reinterpret_cast<ft_outline_decomposer*>(user);
222-
if (d->codes) {
223-
*(d->vertices++) = to->x * (1. / 64.);
224-
*(d->vertices++) = to->y * (1. / 64.);
225-
*(d->codes++) = LINETO;
226-
}
227-
d->index++;
213+
d->vertices.push_back(to->x * (1. / 64.));
214+
d->vertices.push_back(to->y * (1. / 64.));
215+
d->codes.push_back(LINETO);
228216
return 0;
229217
}
230218

231219
static int
232220
ft_outline_conic_to(FT_Vector const* control, FT_Vector const* to, void* user)
233221
{
234222
ft_outline_decomposer* d = reinterpret_cast<ft_outline_decomposer*>(user);
235-
if (d->codes) {
236-
*(d->vertices++) = control->x * (1. / 64.);
237-
*(d->vertices++) = control->y * (1. / 64.);
238-
*(d->vertices++) = to->x * (1. / 64.);
239-
*(d->vertices++) = to->y * (1. / 64.);
240-
*(d->codes++) = CURVE3;
241-
*(d->codes++) = CURVE3;
242-
}
243-
d->index += 2;
223+
d->vertices.push_back(control->x * (1. / 64.));
224+
d->vertices.push_back(control->y * (1. / 64.));
225+
d->vertices.push_back(to->x * (1. / 64.));
226+
d->vertices.push_back(to->y * (1. / 64.));
227+
d->codes.push_back(CURVE3);
228+
d->codes.push_back(CURVE3);
244229
return 0;
245230
}
246231

@@ -249,18 +234,15 @@ ft_outline_cubic_to(
249234
FT_Vector const* c1, FT_Vector const* c2, FT_Vector const* to, void* user)
250235
{
251236
ft_outline_decomposer* d = reinterpret_cast<ft_outline_decomposer*>(user);
252-
if (d->codes) {
253-
*(d->vertices++) = c1->x * (1. / 64.);
254-
*(d->vertices++) = c1->y * (1. / 64.);
255-
*(d->vertices++) = c2->x * (1. / 64.);
256-
*(d->vertices++) = c2->y * (1. / 64.);
257-
*(d->vertices++) = to->x * (1. / 64.);
258-
*(d->vertices++) = to->y * (1. / 64.);
259-
*(d->codes++) = CURVE4;
260-
*(d->codes++) = CURVE4;
261-
*(d->codes++) = CURVE4;
262-
}
263-
d->index += 3;
237+
d->vertices.push_back(c1->x * (1. / 64.));
238+
d->vertices.push_back(c1->y * (1. / 64.));
239+
d->vertices.push_back(c2->x * (1. / 64.));
240+
d->vertices.push_back(c2->y * (1. / 64.));
241+
d->vertices.push_back(to->x * (1. / 64.));
242+
d->vertices.push_back(to->y * (1. / 64.));
243+
d->codes.push_back(CURVE4);
244+
d->codes.push_back(CURVE4);
245+
d->codes.push_back(CURVE4);
264246
return 0;
265247
}
266248

@@ -276,28 +258,28 @@ FT2Font::get_path(std::vector<double> &vertices, std::vector<unsigned char> &cod
276258
if (!face->glyph) {
277259
throw std::runtime_error("No glyph loaded");
278260
}
279-
ft_outline_decomposer decomposer = {};
261+
ft_outline_decomposer decomposer = {
262+
vertices,
263+
codes,
264+
};
265+
// We can make a close-enough estimate based on number of points and number of
266+
// contours (which produce a MOVETO each), though it's slightly underestimating due
267+
// to higher-order curves.
268+
size_t estimated_points = static_cast<size_t>(face->glyph->outline.n_contours) +
269+
static_cast<size_t>(face->glyph->outline.n_points);
270+
vertices.reserve(2 * estimated_points);
271+
codes.reserve(estimated_points);
280272
if (FT_Error error = FT_Outline_Decompose(
281273
&face->glyph->outline, &ft_outline_funcs, &decomposer)) {
282274
throw std::runtime_error("FT_Outline_Decompose failed with error " +
283275
std::to_string(error));
284276
}
285-
if (!decomposer.index) { // Don't append CLOSEPOLY to null glyphs.
277+
if (vertices.empty()) { // Don't append CLOSEPOLY to null glyphs.
286278
return;
287279
}
288-
vertices.resize((decomposer.index + 1) * 2);
289-
codes.resize(decomposer.index + 1);
290-
decomposer.index = 0;
291-
decomposer.vertices = vertices.data();
292-
decomposer.codes = codes.data();
293-
if (FT_Error error = FT_Outline_Decompose(
294-
&face->glyph->outline, &ft_outline_funcs, &decomposer)) {
295-
throw std::runtime_error("FT_Outline_Decompose failed with error " +
296-
std::to_string(error));
297-
}
298-
*(decomposer.vertices++) = 0;
299-
*(decomposer.vertices++) = 0;
300-
*(decomposer.codes++) = CLOSEPOLY;
280+
vertices.push_back(0);
281+
vertices.push_back(0);
282+
codes.push_back(CLOSEPOLY);
301283
}
302284

303285
FT2Font::FT2Font(FT_Open_Args &open_args,

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.