Skip to content

Commit c78a494

Browse files
committed
R6 renamed path_group to interpreted_path. R6 paths are now complete. Note that there are minor API differences due to bugs in the R6 specification.
1 parent 84e22c1 commit c78a494

File tree

5 files changed

+143
-81
lines changed

5 files changed

+143
-81
lines changed

N3888_RefImpl/SampleApp/sample_draw.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -358,7 +358,7 @@ void test_path_functionality(display_surface& ds) {
358358
//pf.rel_line({ -200.0F, 0.0F });
359359
//pf.close_figure();
360360

361-
auto pg = path_group(pf);
361+
auto pg = interpreted_path(pf);
362362
ds.stroke(brush{ rgba_color::red }, pg, nullopt, nullopt, nullopt, nullopt, clip_props{ bounding_box(40.0F, 40.0F, 1240.0F, 680.0F) });
363363

364364
pf.clear();
@@ -399,7 +399,7 @@ void draw_radial_circles(display_surface& ds) {
399399
pf.matrix(matrix_2d());
400400
pf.new_figure({ 520.0F, 10.0F });
401401
pf.cubic_curve({ 480.0F, 60.0F }, { 560.0F, 60.0F }, { 520.0F, 10.0F });
402-
path_group p(pf);
402+
interpreted_path p(pf);
403403
//ds.path_group(p);
404404
//ds.brush(radialBrush);
405405

@@ -427,7 +427,7 @@ void draw_radial_circles(display_surface& ds) {
427427
//pf.arc_counterclockwise({ 900.0F, 200.0F }, 125.0F, 0.0F, two_pi<float>);
428428
//pf.new_figure({ 900.0F, 200.0F });
429429
//pf.arc_clockwise({ 900.0F, 200.0F }, 150.0F, 0.0F, two_pi<float>);
430-
p = path_group(pf);
430+
p = interpreted_path(pf);
431431
//ds.path_group(p);
432432
ds.stroke(radialBrush, p);
433433
//ds.matrix(matrix_2d::init_translate({ 0.0F, 310.0F }));

N3888_RefImpl/src/surface.cpp

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -135,7 +135,7 @@ namespace {
135135
const auto& props = c.value();
136136
cairo_set_fill_rule(context, _Fill_rule_to_cairo_fill_rule_t(props.fill_rule()));
137137
cairo_new_path(context);
138-
cairo_append_path(context, props.clip().native_handle());
138+
cairo_append_path(context, props.clip()._Native_handle());
139139
cairo_clip(context);
140140
// Restore saved state
141141
cairo_set_fill_rule(context, fr);
@@ -223,37 +223,37 @@ void surface::paint(const brush& b, const optional<brush_props>& bp, const optio
223223
cairo_paint(context);
224224
}
225225

226-
void surface::fill(const brush& b, const path_group& pg, const optional<brush_props>& bp, const optional<render_props>& rp, const optional<clip_props>& cl) {
226+
void surface::fill(const brush& b, const interpreted_path& pg, const optional<brush_props>& bp, const optional<render_props>& rp, const optional<clip_props>& cl) {
227227
auto context = _Context.get();
228228
_Set_render_props(context, rp);
229229
_Set_clip_props(context, cl);
230230
_Set_brush_props(context, bp, b);
231231
cairo_set_source(context, b.native_handle());
232232
cairo_new_path(context);
233-
cairo_append_path(context, pg.native_handle());
233+
cairo_append_path(context, pg._Native_handle());
234234
cairo_fill(context);
235235
}
236236

237-
void surface::stroke(const brush& b, const path_group& pg, const optional<brush_props>& bp, const optional<stroke_props>& sp, const optional<dashes>& d, const optional<render_props>& rp, const optional<clip_props>& cl) {
237+
void surface::stroke(const brush& b, const interpreted_path& pg, const optional<brush_props>& bp, const optional<stroke_props>& sp, const optional<dashes>& d, const optional<render_props>& rp, const optional<clip_props>& cl) {
238238
auto context = _Context.get();
239239
_Set_render_props(context, rp);
240240
_Set_clip_props(context, cl);
241241
_Set_brush_props(context, bp, b);
242242
_Set_stroke_props(context, sp, _Line_join_miter_miter_limit, d);
243243
cairo_set_source(context, b.native_handle());
244244
cairo_new_path(context);
245-
cairo_append_path(context, pg.native_handle());
245+
cairo_append_path(context, pg._Native_handle());
246246
cairo_stroke(context);
247247
}
248248

249-
void surface::mask(const brush& b, const brush& mb, const path_group& pg, const optional<brush_props>& bp, const optional<mask_props>& mp, const optional<render_props>& rp, const optional<clip_props>& cl) {
249+
void surface::mask(const brush& b, const brush& mb, const interpreted_path& pg, const optional<brush_props>& bp, const optional<mask_props>& mp, const optional<render_props>& rp, const optional<clip_props>& cl) {
250250
auto context = _Context.get();
251251
_Set_render_props(context, rp);
252252
_Set_clip_props(context, cl);
253253
_Set_brush_props(context, bp, b);
254254
_Set_mask_props(mp, mb);
255255
cairo_set_source(context, b.native_handle());
256256
cairo_new_path(context);
257-
cairo_append_path(context, pg.native_handle());
257+
cairo_append_path(context, pg._Native_handle());
258258
cairo_mask(context, mb.native_handle());
259259
}

N3888_RefImpl/src/xio2d_impl.h

Lines changed: 111 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -1038,18 +1038,17 @@ namespace std::experimental::io2d {
10381038
//template <class Allocator>
10391039
//::std::vector<figure_items::path_data_types> _Interpret_path_items(const path_builder<Allocator>&, ::std::error_code&) noexcept;
10401040

1041+
inline interpreted_path::_Native_handle_type interpreted_path::_Native_handle() const noexcept {
1042+
return _Cairo_path.get();
1043+
}
1044+
1045+
inline constexpr interpreted_path::interpreted_path() noexcept
1046+
: _Cairo_path() {}
1047+
10411048
template <class Allocator>
1042-
inline path_group::path_group(const path_builder<Allocator>& pf)
1043-
: _Cairo_path(new cairo_path_t, [](cairo_path_t* path) {
1044-
if (path != nullptr) {
1045-
if (path->data != nullptr) {
1046-
delete[] path->data;
1047-
path->data = nullptr;
1048-
path->status = CAIRO_STATUS_NULL_POINTER;
1049-
}
1050-
delete path;
1051-
path = nullptr;
1052-
}
1049+
inline interpreted_path::interpreted_path(const path_builder<Allocator>& pf)
1050+
: _Cairo_path(new cairo_path_t, [](cairo_path_t*) {
1051+
// This deleter intentionally left blank. The dtor will deal with this.
10531052
}) {
10541053
auto processedVec = _Interpret_path_items<Allocator>(pf);
10551054
::std::vector<cairo_path_data_t> vec;
@@ -1069,30 +1068,46 @@ namespace std::experimental::io2d {
10691068
_Cairo_path->status = CAIRO_STATUS_SUCCESS;
10701069
}
10711070

1072-
template<class Allocator>
1073-
inline path_group::path_group(const path_builder<Allocator>& pf, ::std::error_code& ec) noexcept
1074-
: _Cairo_path(new cairo_path_t, [](cairo_path_t* path) {
1075-
if (path != nullptr) {
1076-
if (path->data != nullptr) {
1077-
delete[] path->data;
1078-
path->data = nullptr;
1079-
path->status = CAIRO_STATUS_NULL_POINTER;
1080-
}
1081-
delete path;
1082-
path = nullptr;
1083-
}
1071+
//template<class Allocator>
1072+
//inline interpreted_path::interpreted_path(const path_builder<Allocator>& pf, ::std::error_code& ec) noexcept
1073+
// : _Cairo_path(new cairo_path_t, [](cairo_path_t*) {
1074+
// // This deleter intentionally left blank. The dtor will deal with this.
1075+
//}) {
1076+
// auto processedVec = _Interpret_path_items<Allocator>(pf, ec);
1077+
// if (static_cast<bool>(ec)) {
1078+
// return;
1079+
// }
1080+
1081+
// ::std::vector<cairo_path_data_t> vec;
1082+
1083+
// for (const auto& val : processedVec) {
1084+
// ::std::visit([&vec](auto&& item) {
1085+
// using T = ::std::remove_cv_t<::std::remove_reference_t<decltype(item)>>;
1086+
// _Path_group_perform_visit<T>::template _Perform<T>(vec, item);
1087+
// }, val);
1088+
// }
1089+
// _Cairo_path->num_data = static_cast<int>(vec.size());
1090+
// const auto numDataST = vec.size();
1091+
// _Cairo_path->data = new cairo_path_data_t[numDataST];
1092+
// for (size_t currItemIndex = 0; currItemIndex < numDataST; currItemIndex++) {
1093+
// _Cairo_path->data[currItemIndex] = vec[currItemIndex];
1094+
// }
1095+
// _Cairo_path->status = CAIRO_STATUS_SUCCESS;
1096+
// ec.clear();
1097+
//}
1098+
1099+
template <class ForwardIterator>
1100+
inline interpreted_path::interpreted_path(ForwardIterator first, ForwardIterator last)
1101+
: _Cairo_path(new cairo_path_t, [](cairo_path_t*) {
1102+
// This deleter intentionally left blank. The dtor will deal with this.
10841103
}) {
1085-
auto processedVec = _Interpret_path_items<Allocator>(pf, ec);
1086-
if (static_cast<bool>(ec)) {
1087-
return;
1088-
}
1089-
1104+
auto processedVec = _Interpret_path_items<ForwardIterator>(first, last);
10901105
::std::vector<cairo_path_data_t> vec;
1091-
1106+
point_2d lastMoveToPoint;
10921107
for (const auto& val : processedVec) {
1093-
::std::visit([&vec](auto&& item) {
1108+
::std::visit([&vec, &lastMoveToPoint](auto&& item) {
10941109
using T = ::std::remove_cv_t<::std::remove_reference_t<decltype(item)>>;
1095-
_Path_group_perform_visit<T>::template _Perform<T>(vec, item);
1110+
_Path_group_perform_visit<T>::template _Perform<T>(vec, item, lastMoveToPoint);
10961111
}, val);
10971112
}
10981113
_Cairo_path->num_data = static_cast<int>(vec.size());
@@ -1102,7 +1117,38 @@ namespace std::experimental::io2d {
11021117
_Cairo_path->data[currItemIndex] = vec[currItemIndex];
11031118
}
11041119
_Cairo_path->status = CAIRO_STATUS_SUCCESS;
1105-
ec.clear();
1120+
}
1121+
1122+
inline interpreted_path::interpreted_path(const interpreted_path& other) noexcept
1123+
: _Cairo_path(other._Cairo_path) {}
1124+
inline interpreted_path& interpreted_path::operator=(const interpreted_path& other) noexcept {
1125+
_Cairo_path = other._Cairo_path;
1126+
return *this;
1127+
}
1128+
inline interpreted_path::interpreted_path(interpreted_path&& other) noexcept
1129+
: _Cairo_path(move(other._Cairo_path)) {
1130+
other._Cairo_path = nullptr;
1131+
}
1132+
inline interpreted_path& interpreted_path::operator=(interpreted_path&& other) noexcept {
1133+
if (this != &other) {
1134+
_Cairo_path = move(other._Cairo_path);
1135+
other._Cairo_path = nullptr;
1136+
}
1137+
return *this;
1138+
}
1139+
1140+
inline interpreted_path::~interpreted_path() noexcept {
1141+
auto path = _Cairo_path.get();
1142+
if (path != nullptr) {
1143+
if (path->data != nullptr) {
1144+
delete[] path->data;
1145+
path->data = nullptr;
1146+
path->status = CAIRO_STATUS_NULL_POINTER;
1147+
}
1148+
delete path;
1149+
path = nullptr;
1150+
_Cairo_path = nullptr;
1151+
}
11061152
}
11071153

11081154
inline cairo_antialias_t _Antialias_to_cairo_antialias_t(::std::experimental::io2d::antialias aa) {
@@ -1717,24 +1763,45 @@ namespace std::experimental::io2d {
17171763
}
17181764
};
17191765

1766+
template <class ForwardIterator>
1767+
inline ::std::vector<figure_items::figure_item> _Interpret_path_items(ForwardIterator first, ForwardIterator last);
1768+
17201769
template <class Allocator>
17211770
inline ::std::vector<figure_items::figure_item> _Interpret_path_items(const path_builder<Allocator>& pf) {
1771+
//matrix_2d m;
1772+
//point_2d currentPoint; // Tracks the untransformed current point.
1773+
//point_2d closePoint; // Tracks the transformed close point.
1774+
//::std::stack<matrix_2d> matrices;
1775+
//::std::vector<figure_items::figure_item> v;
1776+
1777+
//for (const figure_items::figure_item& val : pf) {
1778+
// ::std::visit([&m, &currentPoint, &closePoint, &matrices, &v](auto&& item) {
1779+
// using T = ::std::remove_cv_t<::std::remove_reference_t<decltype(item)>>;
1780+
// _Path_item_interpret_visitor<T>::template _Interpret<T>(item, v, m, currentPoint, closePoint, matrices);
1781+
// }, val);
1782+
//}
1783+
//return v;
1784+
return _Interpret_path_items(begin(pf), end(pf));
1785+
}
1786+
1787+
template <class ForwardIterator>
1788+
inline ::std::vector<figure_items::figure_item> _Interpret_path_items(ForwardIterator first, ForwardIterator last) {
17221789
matrix_2d m;
17231790
point_2d currentPoint; // Tracks the untransformed current point.
17241791
point_2d closePoint; // Tracks the transformed close point.
17251792
::std::stack<matrix_2d> matrices;
17261793
::std::vector<figure_items::figure_item> v;
17271794

1728-
for (const figure_items::figure_item& val : pf) {
1795+
for (auto val = first; val != last; val++) {
17291796
::std::visit([&m, &currentPoint, &closePoint, &matrices, &v](auto&& item) {
17301797
using T = ::std::remove_cv_t<::std::remove_reference_t<decltype(item)>>;
17311798
_Path_item_interpret_visitor<T>::template _Interpret<T>(item, v, m, currentPoint, closePoint, matrices);
1732-
}, val);
1799+
}, *val);
17331800
}
17341801
return v;
17351802
}
17361803

1737-
template<class Allocator>
1804+
template<class Allocator>
17381805
inline path_builder<Allocator>::path_builder() noexcept(noexcept(Allocator())) :
17391806
path_builder(Allocator()) { }
17401807

@@ -2312,10 +2379,10 @@ namespace std::experimental::io2d {
23122379
template <class Allocator>
23132380
inline clip_props::clip_props(const path_builder<Allocator> &pf,
23142381
experimental::io2d::fill_rule fr)
2315-
: _Clip(path_group(pf))
2382+
: _Clip(interpreted_path(pf))
23162383
, _Fill_rule(fr) { }
23172384

2318-
inline clip_props::clip_props(const path_group& pg,
2385+
inline clip_props::clip_props(const interpreted_path& pg,
23192386
experimental::io2d::fill_rule fr) noexcept
23202387
: _Clip(pg)
23212388
, _Fill_rule(fr) { }
@@ -2330,23 +2397,23 @@ namespace std::experimental::io2d {
23302397
clip.rel_line({ 0.0F, r.height() });
23312398
clip.rel_line({ -r.width(), 0.0F });
23322399
clip.close_figure();
2333-
_Clip = path_group(clip);
2400+
_Clip = interpreted_path(clip);
23342401
}
23352402

23362403
template <class Allocator>
23372404
inline void clip_props::clip(const path_builder<Allocator>& pf) {
2338-
_Clip = path_group(pf);
2405+
_Clip = interpreted_path(pf);
23392406
}
23402407

2341-
inline void clip_props::clip(const path_group& pg) noexcept {
2408+
inline void clip_props::clip(const interpreted_path& pg) noexcept {
23422409
_Clip = pg;
23432410
}
23442411

23452412
inline void clip_props::fill_rule(experimental::io2d::fill_rule fr) {
23462413
_Fill_rule = fr;
23472414
}
23482415

2349-
inline path_group clip_props::clip() const noexcept {
2416+
inline interpreted_path clip_props::clip() const noexcept {
23502417
return _Clip;
23512418
}
23522419

@@ -2420,19 +2487,19 @@ namespace std::experimental::io2d {
24202487

24212488
template <class Allocator>
24222489
inline void surface::fill(const brush& b, const path_builder<Allocator>& pf, const optional<brush_props>& bp, const optional<render_props>& rp, const optional<clip_props>& cl) {
2423-
path_group pg(pf);
2490+
interpreted_path pg(pf);
24242491
fill(b, pg, bp, rp, cl);
24252492
}
24262493

24272494
template <class Allocator>
24282495
inline void surface::stroke(const brush& b, const path_builder<Allocator>& pf, const optional<brush_props>& bp, const optional<stroke_props>& sp, const optional<dashes>& d, const optional<render_props>& rp, const optional<clip_props>& cl) {
2429-
path_group pg(pf);
2496+
interpreted_path pg(pf);
24302497
stroke(b, pg, bp, sp, d, rp, cl);
24312498
}
24322499

24332500
template <class Allocator>
24342501
inline void surface::mask(const brush& b, const brush& mb, const path_builder<Allocator>& pf, const optional<brush_props>& bp, const optional<mask_props>& mp, const optional<render_props>&rp, const optional<clip_props>& cl) {
2435-
path_group pg(pf);
2502+
interpreted_path pg(pf);
24362503
mask(b, mb, pg, bp, mp, rp, cl);
24372504
}
24382505

N3888_RefImpl/src/xpath.h

Lines changed: 15 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -338,30 +338,25 @@ namespace std::experimental::io2d {
338338
}*/ // compiler error prevents forward declaration
339339

340340
class interpreted_path {
341+
shared_ptr<cairo_path_t> _Cairo_path;
341342
public:
343+
using _Native_handle_type = cairo_path*;
344+
_Native_handle_type _Native_handle() const noexcept;
345+
// Note: Can default construct. It will just be empty. To be useful it would need to be assigned to.
346+
constexpr interpreted_path() noexcept;
342347
template <class Allocator>
343-
explicit interpreted_path(const path_builder<Allocator>& pb);
348+
explicit interpreted_path(const path_builder<Allocator>& p);
349+
//template <class Allocator>
350+
//interpreted_path(const path_builder<Allocator>& p, std::error_code& ec) noexcept;
344351
template <class ForwardIterator>
345352
interpreted_path(ForwardIterator first, ForwardIterator last);
346-
};
347-
348-
class path_group {
349-
::std::shared_ptr<cairo_path_t> _Cairo_path;
350-
public:
351-
using native_handle_type = cairo_path*;
352-
// Note: Can default construct. It will just be empty. To be useful it would need to be assigned to.
353-
path_group() noexcept = default;
354-
template <class Allocator>
355-
explicit path_group(const path_builder<Allocator>& p);
356-
template <class Allocator>
357-
path_group(const path_builder<Allocator>& p, std::error_code& ec) noexcept;
358-
359-
native_handle_type native_handle() {
360-
return _Cairo_path.get();
361-
}
362-
const cairo_path* native_handle() const {
363-
return _Cairo_path.get();
364-
}
353+
//template <class ForwardIterator>
354+
//interpreted_path(ForwardIterator first, ForwardIterator last, error_code& ec) noexcept;
355+
interpreted_path(const interpreted_path& other) noexcept;
356+
interpreted_path& operator=(const interpreted_path& other) noexcept;
357+
interpreted_path(interpreted_path&& other) noexcept;
358+
interpreted_path& operator=(interpreted_path&& other) noexcept;
359+
~interpreted_path() noexcept;
365360
};
366361

367362
}

0 commit comments

Comments
 (0)