@@ -286,21 +286,31 @@ export struct InlineBox {
286
286
}
287
287
};
288
288
289
- struct SVGRoot {
290
- using Element = Union<SVG::Shape, SVGRoot, ::Box<Box>>;
291
- Vec<Element> elements;
289
+ struct SVGRoot ;
290
+
291
+ namespace SVG {
292
+
293
+ struct Group {
294
+ using Element = Union<Shape, SVGRoot, Karm::Box<Vaev::Layout::Box>, Group>;
295
+ Vec<Element> elements = {};
292
296
293
- Opt<ViewBox> viewBox;
294
297
Rc<Style::SpecifiedStyle> style;
295
298
296
- void add (Element&& element) {
297
- elements.pushBack (std::move (element));
298
- }
299
+ Group (Rc<Style::SpecifiedStyle> style)
300
+ : style(style) {}
299
301
300
- void add (Box&& box);
302
+ void add (Element&& element);
303
+ void add (Vaev::Layout::Box&& box);
304
+
305
+ void repr (Io::Emit& e) const ;
306
+ };
307
+ } // namespace SVG
308
+
309
+ struct SVGRoot : SVG::Group {
310
+ Opt<ViewBox> viewBox;
301
311
302
312
SVGRoot (Rc<Style::SpecifiedStyle> style)
303
- : viewBox(style->svg->viewBox), style(style ) {}
313
+ : SVG::Group(style), viewBox(style->svg->viewBox) {}
304
314
305
315
void repr (Io::Emit& e) const {
306
316
e (" (SVG {} viewBox:{}" , SVG::buildRectangle (*style), viewBox);
@@ -313,6 +323,16 @@ struct SVGRoot {
313
323
}
314
324
};
315
325
326
+ void SVG::Group::repr (Io::Emit& e) const {
327
+ e (" (Group {} " );
328
+ e.indentNewline ();
329
+ for (auto const & el : elements) {
330
+ e (" {}" , el);
331
+ e.newline ();
332
+ }
333
+ e (" )" );
334
+ }
335
+
316
336
export using Content = Union<
317
337
None,
318
338
Vec<Box>,
@@ -392,8 +412,12 @@ struct Box : Meta::NoCopy {
392
412
}
393
413
};
394
414
395
- void SVGRoot::add (Box&& box) {
396
- add (makeBox<Box>(std::move (box)));
415
+ void SVG::Group::add (Element&& element) {
416
+ elements.pushBack (std::move (element));
417
+ }
418
+
419
+ void SVG::Group::add (Vaev::Layout::Box&& box) {
420
+ add (Element{makeBox<Vaev::Layout::Box>(std::move (box))});
397
421
}
398
422
399
423
void InlineBox::add (Box&& b) {
@@ -452,28 +476,62 @@ export struct Metrics {
452
476
};
453
477
454
478
export struct Frag ;
479
+ struct SVGRootFrag ;
480
+
481
+ namespace SVG {
455
482
456
- struct SVGRootFrag {
457
- using Element = Union<SVG::ShapeFrag, SVGRootFrag, ::Box<Frag>>;
483
+ struct GroupFrag : SVG::Frag {
484
+ using Element = Union<SVG::ShapeFrag, SVGRootFrag, ::Box<Vaev::Layout:: Frag>, GroupFrag >;
458
485
Vec<Element> elements = {};
459
486
487
+ RectAu _objectBoundingBox{};
488
+ RectAu _strokeBoundingBox{};
489
+
490
+ Karm::Cursor<Group> box;
491
+
492
+ GroupFrag (Karm::Cursor<Group> group)
493
+ : box(group) {}
494
+
495
+ void _computeBoundingBoxes (SVG::GroupFrag* group);
496
+
497
+ RectAu objectBoundingBox () override {
498
+ return _objectBoundingBox;
499
+ }
500
+
501
+ RectAu strokeBoundingBox () override {
502
+ return _strokeBoundingBox;
503
+ }
504
+
505
+ Style::SpecifiedStyle const & style () override {
506
+ return *box->style ;
507
+ }
508
+
509
+ void add (Element&& element);
510
+
511
+ void repr (Io::Emit& e) const {
512
+ e (" (GroupFrag)" );
513
+ }
514
+ };
515
+ } // namespace SVG
516
+
517
+ struct SVGRootFrag : SVG::GroupFrag {
460
518
// NOTE: SVG viewports have these intrinsic transformations; choosing to store these transforms is more compliant
461
519
// and somewhat rendering-friendly but makes it harder to debug
462
520
Math::Trans2f transf;
463
521
SVG::Rectangle<Au> boundingBox;
464
522
523
+ SVGRootFrag (Karm::Cursor<SVG::Group> group, Math::Trans2f transf, SVG::Rectangle<Au> boundingBox)
524
+ : SVG::GroupFrag(group), transf(transf), boundingBox(boundingBox) {
525
+ }
526
+
465
527
static SVGRootFrag build (SVGRoot const & box, Vec2Au position, Vec2Au viewportSize) {
466
528
SVG::Rectangle<Karm::Au> rect{position.x , position.y , viewportSize.x , viewportSize.y };
467
529
468
530
Math::Trans2f transf =
469
531
box.viewBox ? SVG::computeEquivalentTransformOfSVGViewport (*box.viewBox , position, viewportSize)
470
532
: Math::Trans2f::translate (position.cast <f64 >());
471
533
472
- return {{}, transf, rect};
473
- }
474
-
475
- void add (Element&& el) {
476
- elements.pushBack (std::move (el));
534
+ return SVGRootFrag{&box, transf, rect};
477
535
}
478
536
479
537
void repr (Io::Emit& e) const {
@@ -532,9 +590,13 @@ export struct Frag {
532
590
}
533
591
};
534
592
593
+ void SVG::GroupFrag::add (Element&& el) {
594
+ elements.pushBack (std::move (el));
595
+ }
596
+
535
597
void SVGRootFrag::offsetBoxFrags (Vec2Au d) {
536
598
for (auto & element : elements) {
537
- if (auto frag = element.is <::Box<Frag>>()) {
599
+ if (auto frag = element.is <::Box<Vaev::Layout:: Frag>>()) {
538
600
(*frag)->offset (d);
539
601
} else if (auto nestedRoot = element.is <SVGRootFrag>()) {
540
602
nestedRoot->offsetBoxFrags (d);
0 commit comments