@@ -293,50 +293,120 @@ const Color& SolidStrokeContents::GetColor() const {
293
293
return color_;
294
294
}
295
295
296
+ static void CreateCap (
297
+ VertexBufferBuilder<SolidStrokeVertexShader::PerVertexData>& vtx_builder,
298
+ const Point & position,
299
+ const Point & normal ) {}
300
+
301
+ static void CreateJoin (
302
+ VertexBufferBuilder<SolidStrokeVertexShader::PerVertexData>& vtx_builder,
303
+ const Point & position,
304
+ const Point & start_normal,
305
+ const Point & end_normal) {
306
+ SolidStrokeVertexShader::PerVertexData vtx;
307
+ vtx.vertex_position = position;
308
+ vtx.pen_down = 1.0 ;
309
+ vtx.vertex_normal = {};
310
+ vtx_builder.AppendVertex (vtx);
311
+
312
+ // A simple bevel join to start with.
313
+ Scalar dir = start_normal.Cross (end_normal) > 0 ? -1 : 1 ;
314
+ vtx.vertex_normal = start_normal * dir;
315
+ vtx_builder.AppendVertex (vtx);
316
+ vtx.vertex_normal = end_normal * dir;
317
+ vtx_builder.AppendVertex (vtx);
318
+ }
319
+
296
320
static VertexBuffer CreateSolidStrokeVertices (const Path& path,
297
321
HostBuffer& buffer) {
298
322
using VS = SolidStrokeVertexShader;
299
323
300
324
VertexBufferBuilder<VS::PerVertexData> vtx_builder;
301
325
auto polyline = path.CreatePolyline ();
302
326
303
- for (size_t i = 0 , polyline_size = polyline.points .size (); i < polyline_size;
304
- i++) {
305
- const auto is_last_point = i == polyline_size - 1 ;
306
-
307
- const auto & p1 = polyline.points [i];
308
- const auto & p2 =
309
- is_last_point ? polyline.points [i - 1 ] : polyline.points [i + 1 ];
310
-
311
- const auto diff = p2 - p1;
312
-
313
- const Scalar direction = is_last_point ? -1.0 : 1.0 ;
327
+ size_t point_i = 0 ;
328
+ if (polyline.points .size () < 2 ) {
329
+ return {}; // Nothing to render.
330
+ }
314
331
315
- const auto normal =
316
- Point {-diff.y * direction, diff.x * direction}.Normalize ();
332
+ VS::PerVertexData vtx;
333
+
334
+ // Cursor state.
335
+ Point direction;
336
+ Point normal ;
337
+ Point previous_normal; // Used for computing joins.
338
+ auto compute_normals = [&](size_t point_i) {
339
+ previous_normal = normal ;
340
+ direction =
341
+ (polyline.points [point_i] - polyline.points [point_i - 1 ]).Normalize ();
342
+ normal = {-direction.y , direction.x };
343
+ };
344
+ compute_normals (1 );
345
+
346
+ // Break state.
347
+ auto breaks_it = polyline.breaks .begin ();
348
+ size_t break_end =
349
+ breaks_it != polyline.breaks .end () ? *breaks_it : polyline.points .size ();
350
+
351
+ while (point_i < polyline.points .size ()) {
352
+ if (point_i > 0 ) {
353
+ compute_normals (point_i);
354
+
355
+ // This branch only executes when we've just finished drawing a contour
356
+ // and are switching to a new one.
357
+ // We're drawing a triangle strip, so we need to "pick up the pen" by
358
+ // appending transparent vertices between the end of the previous contour
359
+ // and the beginning of the new contour.
360
+ vtx.vertex_position = polyline.points [point_i - 1 ];
361
+ vtx.vertex_normal = {};
362
+ vtx.pen_down = 0.0 ;
363
+ vtx_builder.AppendVertex (vtx);
364
+ vtx.vertex_position = polyline.points [point_i];
365
+ vtx_builder.AppendVertex (vtx);
366
+ }
317
367
318
- VS::PerVertexData vtx;
319
- vtx.vertex_position = p1;
320
- auto pen_down =
321
- polyline.breaks .find (i) == polyline.breaks .end () ? 1.0 : 0.0 ;
368
+ // Generate start cap.
369
+ CreateCap (vtx_builder, polyline.points [point_i], -direction);
370
+
371
+ // Generate contour geometry.
372
+ size_t contour_point_i = 0 ;
373
+ while (point_i < break_end) {
374
+ if (contour_point_i > 0 ) {
375
+ if (contour_point_i > 1 ) {
376
+ // Generate join from the previous line to the current line.
377
+ CreateJoin (vtx_builder, polyline.points [point_i - 1 ], previous_normal,
378
+ normal );
379
+ } else {
380
+ compute_normals (point_i);
381
+ }
382
+
383
+ // Generate line rect.
384
+ vtx.vertex_position = polyline.points [point_i - 1 ];
385
+ vtx.pen_down = 1.0 ;
386
+ vtx.vertex_normal = normal ;
387
+ vtx_builder.AppendVertex (vtx);
388
+ vtx.vertex_normal = -normal ;
389
+ vtx_builder.AppendVertex (vtx);
390
+ vtx.vertex_position = polyline.points [point_i];
391
+ vtx.vertex_normal = normal ;
392
+ vtx_builder.AppendVertex (vtx);
393
+ vtx.vertex_normal = -normal ;
394
+ vtx_builder.AppendVertex (vtx);
322
395
323
- vtx.vertex_normal = normal ;
324
- vtx.pen_down = pen_down;
325
- vtx_builder.AppendVertex (vtx);
396
+ compute_normals (point_i + 1 );
397
+ }
326
398
327
- vtx. vertex_normal = - normal ;
328
- vtx. pen_down = pen_down ;
329
- vtx_builder. AppendVertex (vtx);
399
+ ++contour_point_i ;
400
+ ++point_i ;
401
+ }
330
402
331
- // Put the pen down again for the next contour.
332
- if (!pen_down) {
333
- vtx.vertex_normal = normal ;
334
- vtx.pen_down = 1.0 ;
335
- vtx_builder.AppendVertex (vtx);
403
+ // Generate end cap.
404
+ CreateCap (vtx_builder, polyline.points [point_i - 1 ], -direction);
336
405
337
- vtx.vertex_normal = -normal ;
338
- vtx.pen_down = 1.0 ;
339
- vtx_builder.AppendVertex (vtx);
406
+ if (break_end < polyline.points .size ()) {
407
+ ++breaks_it;
408
+ break_end = breaks_it != polyline.breaks .end () ? *breaks_it
409
+ : polyline.points .size ();
340
410
}
341
411
}
342
412
@@ -384,6 +454,30 @@ Scalar SolidStrokeContents::GetStrokeSize() const {
384
454
return stroke_size_;
385
455
}
386
456
457
+ void SolidStrokeContents::SetStrokeMiter (Scalar miter) {
458
+ miter_ = miter;
459
+ }
460
+
461
+ Scalar SolidStrokeContents::GetStrokeMiter (Scalar miter) {
462
+ return miter_;
463
+ }
464
+
465
+ void SolidStrokeContents::SetStrokeCap (Cap cap) {
466
+ cap_ = cap;
467
+ }
468
+
469
+ SolidStrokeContents::Cap SolidStrokeContents::GetStrokeCap () {
470
+ return cap_;
471
+ }
472
+
473
+ void SolidStrokeContents::SetStrokeJoin (Join join) {
474
+ join_ = join;
475
+ }
476
+
477
+ SolidStrokeContents::Join SolidStrokeContents::GetStrokeJoin () {
478
+ return join_;
479
+ }
480
+
387
481
/* ******************************************************************************
388
482
******* ClipContents
389
483
******************************************************************************/
0 commit comments