@@ -242,18 +242,102 @@ StrokePathGeometry::CreateSolidStrokeVertices(
242
242
Point offset;
243
243
Point previous_offset; // Used for computing joins.
244
244
245
- auto compute_offset = [&polyline, &offset, &previous_offset,
246
- &stroke_width](size_t point_i) {
245
+ // Computes offset by calculating the direction from point_i - 1 to point_i if
246
+ // point_i is within `contour_start_point_i` and `contour_end_point_i`;
247
+ // Otherwise, it uses direction from contour.
248
+ auto compute_offset = [&polyline, &offset, &previous_offset, &stroke_width](
249
+ const size_t point_i,
250
+ const size_t contour_start_point_i,
251
+ const size_t contour_end_point_i,
252
+ const Path::PolylineContour& contour) {
253
+ Point direction;
254
+ if (point_i >= contour_end_point_i) {
255
+ direction = contour.end_direction ;
256
+ } else if (point_i <= contour_start_point_i) {
257
+ direction = -contour.start_direction ;
258
+ } else {
259
+ direction =
260
+ (polyline.points [point_i] - polyline.points [point_i - 1 ]).Normalize ();
261
+ }
247
262
previous_offset = offset;
248
- Point direction =
249
- (polyline.points [point_i] - polyline.points [point_i - 1 ]).Normalize ();
250
263
offset = Vector2{-direction.y , direction.x } * stroke_width * 0.5 ;
251
264
};
252
265
266
+ auto add_vertices_for_linear_compoent =
267
+ [&vtx_builder, &offset, &previous_offset, &vtx, &polyline,
268
+ &compute_offset, scaled_miter_limit, scale, &join_proc](
269
+ const size_t component_start_index, const size_t component_end_index,
270
+ const size_t contour_start_point_i, const size_t contour_end_point_i,
271
+ const Path::PolylineContour& contour) {
272
+ auto is_last_component =
273
+ component_start_index ==
274
+ contour.components .back ().component_start_index ;
275
+
276
+ for (size_t point_i = component_start_index;
277
+ point_i < component_end_index; point_i++) {
278
+ auto is_end_of_component = point_i == component_end_index - 1 ;
279
+ vtx.position = polyline.points [point_i] + offset;
280
+ vtx_builder.AppendVertex (vtx);
281
+ vtx.position = polyline.points [point_i] - offset;
282
+ vtx_builder.AppendVertex (vtx);
283
+
284
+ // For line components, two additional points need to be appended
285
+ // prior to appending a join connecting the next component.
286
+ vtx.position = polyline.points [point_i + 1 ] + offset;
287
+ vtx_builder.AppendVertex (vtx);
288
+ vtx.position = polyline.points [point_i + 1 ] - offset;
289
+ vtx_builder.AppendVertex (vtx);
290
+
291
+ compute_offset (point_i + 2 , contour_start_point_i,
292
+ contour_end_point_i, contour);
293
+ if (!is_last_component && is_end_of_component) {
294
+ // Generate join from the current line to the next line.
295
+ join_proc (vtx_builder, polyline.points [point_i + 1 ],
296
+ previous_offset, offset, scaled_miter_limit, scale);
297
+ }
298
+ }
299
+ };
300
+
301
+ auto add_vertices_for_curve_compoent =
302
+ [&vtx_builder, &offset, &previous_offset, &vtx, &polyline,
303
+ &compute_offset, scaled_miter_limit, scale, &join_proc](
304
+ const size_t component_start_index, const size_t component_end_index,
305
+ const size_t contour_start_point_i, const size_t contour_end_point_i,
306
+ const Path::PolylineContour& contour) {
307
+ auto is_last_component =
308
+ component_start_index ==
309
+ contour.components .back ().component_start_index ;
310
+
311
+ for (size_t point_i = component_start_index;
312
+ point_i < component_end_index; point_i++) {
313
+ auto is_end_of_component = point_i == component_end_index - 1 ;
314
+
315
+ vtx.position = polyline.points [point_i] + offset;
316
+ vtx_builder.AppendVertex (vtx);
317
+ vtx.position = polyline.points [point_i] - offset;
318
+ vtx_builder.AppendVertex (vtx);
319
+
320
+ compute_offset (point_i + 2 , contour_start_point_i,
321
+ contour_end_point_i, contour);
322
+ // For curve components, the polyline is detailed enough such that
323
+ // it can avoid worrying about joins altogether.
324
+ if (is_end_of_component) {
325
+ vtx.position = polyline.points [point_i + 1 ] + offset;
326
+ vtx_builder.AppendVertex (vtx);
327
+ vtx.position = polyline.points [point_i + 1 ] - offset;
328
+ vtx_builder.AppendVertex (vtx);
329
+ // Generate join from the current line to the next line.
330
+ if (!is_last_component) {
331
+ join_proc (vtx_builder, polyline.points [point_i + 1 ],
332
+ previous_offset, offset, scaled_miter_limit, scale);
333
+ }
334
+ }
335
+ }
336
+ };
337
+
253
338
for (size_t contour_i = 0 ; contour_i < polyline.contours .size ();
254
339
contour_i++) {
255
340
auto contour = polyline.contours [contour_i];
256
- size_t contour_component_i = 0 ;
257
341
size_t contour_start_point_i, contour_end_point_i;
258
342
std::tie (contour_start_point_i, contour_end_point_i) =
259
343
polyline.GetContourPointBounds (contour_i);
@@ -271,8 +355,8 @@ StrokePathGeometry::CreateSolidStrokeVertices(
271
355
break ;
272
356
}
273
357
274
- // The first point's offset is always the same as the second point.
275
- compute_offset (contour_start_point_i + 1 );
358
+ compute_offset (contour_start_point_i, contour_start_point_i,
359
+ contour_end_point_i, contour );
276
360
const Point contour_first_offset = offset;
277
361
278
362
if (contour_i > 0 ) {
@@ -306,53 +390,26 @@ StrokePathGeometry::CreateSolidStrokeVertices(
306
390
scale, true );
307
391
}
308
392
309
- // Generate contour geometry.
310
- for (size_t point_i = contour_start_point_i + 1 ;
311
- point_i < contour_end_point_i; point_i++) {
312
- if ((contour_component_i + 1 >= contour.components .size ()) &&
313
- contour.components [contour_component_i + 1 ].component_start_index <=
314
- point_i) {
315
- // The point_i has entered the next component in this contour.
316
- contour_component_i += 1 ;
317
- }
318
- // Generate line rect.
319
- vtx.position = polyline.points [point_i - 1 ] + offset;
320
- vtx_builder.AppendVertex (vtx);
321
- vtx.position = polyline.points [point_i - 1 ] - offset;
322
- vtx_builder.AppendVertex (vtx);
323
-
324
- auto is_end_of_contour = point_i == contour_end_point_i - 1 ;
325
-
326
- if (!contour.components [contour_component_i].is_curve ) {
327
- // For line components, two additional points need to be appended prior
328
- // to appending a join connecting the next component.
329
- vtx.position = polyline.points [point_i] + offset;
330
- vtx_builder.AppendVertex (vtx);
331
- vtx.position = polyline.points [point_i] - offset;
332
- vtx_builder.AppendVertex (vtx);
333
-
334
- if (!is_end_of_contour) {
335
- compute_offset (point_i + 1 );
336
- // Generate join from the current line to the next line.
337
- join_proc (vtx_builder, polyline.points [point_i], previous_offset,
338
- offset, scaled_miter_limit, scale);
339
- }
393
+ for (size_t contour_component_i = 0 ;
394
+ contour_component_i < contour.components .size ();
395
+ contour_component_i++) {
396
+ auto component = contour.components [contour_component_i];
397
+ auto is_last_component =
398
+ contour_component_i == contour.components .size () - 1 ;
399
+
400
+ auto component_start_index = component.component_start_index ;
401
+ auto component_end_index =
402
+ is_last_component ? contour_end_point_i - 1
403
+ : contour.components [contour_component_i + 1 ]
404
+ .component_start_index ;
405
+ if (component.is_curve ) {
406
+ add_vertices_for_curve_compoent (
407
+ component_start_index, component_end_index, contour_start_point_i,
408
+ contour_end_point_i, contour);
340
409
} else {
341
- // For curve components, the polyline is detailed enough such that
342
- // it can avoid worrying about joins altogether.
343
- if (!is_end_of_contour) {
344
- compute_offset (point_i + 1 );
345
- } else {
346
- // If this is a curve and is the end of the contour, two end points
347
- // need to be drawn with the contour end_direction.
348
- auto end_offset =
349
- Vector2 (-contour.end_direction .y , contour.end_direction .x ) *
350
- stroke_width * 0.5 ;
351
- vtx.position = polyline.points [contour_end_point_i - 1 ] + end_offset;
352
- vtx_builder.AppendVertex (vtx);
353
- vtx.position = polyline.points [contour_end_point_i - 1 ] - end_offset;
354
- vtx_builder.AppendVertex (vtx);
355
- }
410
+ add_vertices_for_linear_compoent (
411
+ component_start_index, component_end_index, contour_start_point_i,
412
+ contour_end_point_i, contour);
356
413
}
357
414
}
358
415
0 commit comments