Skip to content

Commit b6e9887

Browse files
committed
[SVG] Added ENFORCE_TRACKING flag
1 parent 7b7b1e3 commit b6e9887

File tree

12 files changed

+41
-10
lines changed

12 files changed

+41
-10
lines changed

CMakeLists.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ else ()
5050
endif ()
5151
option (BUILD_TESTS "Build/enable tests" ON)
5252
option (BUILD_DEFS "Auto-generate C/C++ headers and documentation" OFF)
53-
option (DISABLE_SSL "Disable built-in SSL support even if available on this system" OFF)
53+
option (DISABLE_SSL "Disable built-in SSL support even if available on this system" ON)
5454
option (DISABLE_X11 "Disable X11 even if available on this system" OFF)
5555
option (DISABLE_AUDIO "Disable audio API" OFF)
5656
option (DISABLE_DISPLAY "Disable display API" OFF)

docs/xml/modules/classes/svg.xml

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,7 @@
9191

9292
<method>
9393
<name>Render</name>
94-
<comment>Render the scene to a target Bitamp.</comment>
94+
<comment>Render the scene to a target Bitmap.</comment>
9595
<prototype>ERR svg::Render(OBJECTPTR Object, objBitmap * Bitmap, LONG X, LONG Y, LONG Width, LONG Height)</prototype>
9696
<input>
9797
<param type="objBitmap *" name="Bitmap">The target <class name="Bitmap">Bitmap</class>.</param>
@@ -200,7 +200,7 @@
200200
<description>
201201
<p>During the normal initialisation process, a new <class name="VectorViewport">VectorViewport</class> is created to host the SVG scene graph. By default, the viewport and its content is strictly owned by the SVG object unless a Target is defined to redirect the scene graph elsewhere.</p>
202202
<p>The provided Target can be any object class, as long as it forms part of a scene graph owned by a <class name="VectorScene">VectorScene</class> object. It is recommended that the chosen target is a <class name="VectorViewport">VectorViewport</class>.</p>
203-
<p>The use of a Target will make the generated scene graph independent of the SVG object. Consequently, it is possible to terminate the SVG object without impacting the resources it created.</p>
203+
<p>The use of a Target will make the generated scene graph independent of the SVG object. Consequently, it is possible to terminate the SVG object without impacting the resources it created. If tracking back to the SVG object is still required, use the <code>ENFORCE_TRACKING</code> option in <fl>Flags</fl> to ensure that SVG definitions are still terminated on object destruction.</p>
204204
</description>
205205
</field>
206206

@@ -229,6 +229,7 @@
229229
<constants lookup="SVF" comment="SVG flags.">
230230
<const name="ALPHA">Generate an alpha channel in the rendered image.</const>
231231
<const name="AUTOSCALE">In auto-resize mode, vector dimensions are scaled to the width and height of the vector page. The <class name="VectorScene" field="PageWidth">VectorScene.PageWidth</class> and <class name="VectorScene" field="PageHeight">VectorScene.PageHeight</class> must be set for this.</const>
232+
<const name="ENFORCE_TRACKING">Enforce tracking of definition objects when a Target is used.</const>
232233
</constants>
233234

234235
</types>

include/parasol/modules/svg.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ enum class SVF : ULONG {
1616
NIL = 0,
1717
AUTOSCALE = 0x00000001,
1818
ALPHA = 0x00000002,
19+
ENFORCE_TRACKING = 0x00000004,
1920
};
2021

2122
DEFINE_ENUM_FLAG_OPERATORS(SVF)

src/core/lib_objects.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1397,7 +1397,7 @@ void NotifySubscribers(OBJECTPTR Object, AC ActionID, APTR Parameters, ERR Error
13971397
glSubReadOnly--;
13981398

13991399
if (!glSubReadOnly) {
1400-
if (!glDelayedSubscribe.empty()) {
1400+
if (!glDelayedSubscribe.empty()) { // Check if SubscribeAction() was called during the notification process
14011401
for (auto &entry : glDelayedSubscribe) {
14021402
glSubscriptions[entry.ObjectID][LONG(entry.ActionID)].emplace_back(entry.Callback.Context, entry.Callback.Routine, entry.Callback.Meta);
14031403
}

src/picture/picture.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -326,10 +326,10 @@ static ERR PICTURE_Activate(extPicture *Self)
326326

327327
static ERR PICTURE_Free(extPicture *Self)
328328
{
329-
Self->~extPicture();
330329
if (Self->prvFile) { FreeResource(Self->prvFile); Self->prvFile = NULL; }
331330
if (Self->Bitmap) { FreeResource(Self->Bitmap); Self->Bitmap = NULL; }
332331
if (Self->Mask) { FreeResource(Self->Mask); Self->Mask = NULL; }
332+
Self->~extPicture();
333333
return ERR::Okay;
334334
}
335335

src/svg/class_svg.cpp

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -86,8 +86,6 @@ static ERR SVG_DataFeed(extSVG *Self, struct acDataFeed *Args)
8686

8787
static ERR SVG_Free(extSVG *Self)
8888
{
89-
Self->~extSVG();
90-
9189
if (Self->AnimationTimer) {
9290
UpdateTimer(Self->AnimationTimer, 0);
9391
Self->AnimationTimer = 0;
@@ -108,6 +106,12 @@ static ERR SVG_Free(extSVG *Self)
108106
if (Self->Statement) { FreeResource(Self->Statement); Self->Statement = NULL; }
109107
if (Self->XML) { FreeResource(Self->XML); Self->XML = NULL; }
110108

109+
if (!Self->Resources.empty()) {
110+
for (auto id : Self->Resources) FreeResource(id);
111+
}
112+
113+
Self->~extSVG();
114+
111115
return ERR::Okay;
112116
}
113117

@@ -552,7 +556,9 @@ The provided Target can be any object class, as long as it forms part of a scene
552556
object. It is recommended that the chosen target is a @VectorViewport.
553557
554558
The use of a Target will make the generated scene graph independent of the SVG object. Consequently, it is possible
555-
to terminate the SVG object without impacting the resources it created.
559+
to terminate the SVG object without impacting the resources it created. If tracking back to the SVG object is
560+
still required, use the `ENFORCE_TRACKING` option in #Flags to ensure that SVG definitions are still terminated on
561+
object destruction.
556562
557563
*********************************************************************************************************************/
558564

src/svg/class_svg_def.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
static const struct FieldDef clSVGFlags[] = {
44
{ "Autoscale", 0x00000001 },
55
{ "Alpha", 0x00000002 },
6+
{ "EnforceTracking", 0x00000004 },
67
{ NULL, 0 }
78
};
89

src/svg/gradients.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -152,6 +152,7 @@ static ERR xtag_lineargradient(extSVG *Self, const XMLTag &Tag)
152152
if (!id.empty()) {
153153
SetName(gradient, id.c_str());
154154
add_id(Self, Tag, id);
155+
track_object(Self, gradient);
155156
return Self->Scene->addDef(id.c_str(), gradient);
156157
}
157158
else return ERR::Okay;
@@ -222,6 +223,7 @@ static ERR xtag_radialgradient(extSVG *Self, const XMLTag &Tag)
222223
if (!id.empty()) {
223224
SetName(gradient, id.c_str());
224225
add_id(Self, Tag, id);
226+
track_object(Self, gradient);
225227
return Self->Scene->addDef(id.c_str(), gradient);
226228
}
227229
else return ERR::Okay;
@@ -291,6 +293,7 @@ static ERR xtag_diamondgradient(extSVG *Self, const XMLTag &Tag)
291293
if (!id.empty()) {
292294
SetName(gradient, id.c_str());
293295
add_id(Self, Tag, id);
296+
track_object(Self, gradient);
294297
return Self->Scene->addDef(id.c_str(), gradient);
295298
}
296299
else return ERR::Okay;
@@ -358,6 +361,7 @@ static ERR xtag_contourgradient(extSVG *Self, const XMLTag &Tag)
358361
if (!id.empty()) {
359362
SetName(gradient, id.c_str());
360363
add_id(Self, Tag, id);
364+
track_object(Self, gradient);
361365
return Self->Scene->addDef(id.c_str(), gradient);
362366
}
363367
else return ERR::Okay;
@@ -431,6 +435,7 @@ static ERR xtag_conicgradient(extSVG *Self, const XMLTag &Tag)
431435
if (!id.empty()) {
432436
SetName(gradient, id.c_str());
433437
add_id(Self, Tag, id);
438+
track_object(Self, gradient);
434439
return Self->Scene->addDef(id.c_str(), gradient);
435440
}
436441
else return ERR::Okay;

src/svg/parser.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -199,6 +199,7 @@ static void xtag_pathtransition(extSVG *Self, XMLTag &Tag)
199199

200200
if (InitObject(trans) IS ERR::Okay) {
201201
if (!Self->Cloning) Self->Scene->addDef(id.c_str(), trans);
202+
track_object(Self, trans);
202203
return;
203204
}
204205
}
@@ -266,6 +267,7 @@ static void xtag_clippath(extSVG *Self, XMLTag &Tag)
266267
process_children(Self, state, Tag, vp);
267268

268269
Self->Scene->addDef(id.c_str(), clip);
270+
track_object(Self, clip);
269271
}
270272
else FreeResource(clip);
271273
}
@@ -339,6 +341,7 @@ static void xtag_mask(extSVG *Self, XMLTag &Tag)
339341
process_children(Self, state, Tag, vp);
340342

341343
Self->Scene->addDef(id.c_str(), clip);
344+
track_object(Self, clip);
342345
}
343346
else FreeResource(clip);
344347
}
@@ -1466,6 +1469,8 @@ static void xtag_filter(extSVG *Self, svgState &State, XMLTag &Tag)
14661469
Self->Effects.clear();
14671470

14681471
if (!Self->Cloning) Self->Scene->addDef(id.c_str(), filter);
1472+
1473+
track_object(Self, filter);
14691474
}
14701475
else FreeResource(filter);
14711476
}
@@ -1560,6 +1565,7 @@ static void process_pattern(extSVG *Self, XMLTag &Tag)
15601565
if (!Self->Cloning) {
15611566
add_id(Self, Tag, id);
15621567
Self->Scene->addDef(id.c_str(), pattern);
1568+
track_object(Self, pattern);
15631569
}
15641570
}
15651571
else {
@@ -1812,6 +1818,7 @@ static void def_image(extSVG *Self, XMLTag &Tag)
18121818
if (!Self->Cloning) {
18131819
add_id(Self, Tag, id);
18141820
Self->Scene->addDef(id.c_str(), image);
1821+
track_object(Self, image);
18151822
}
18161823
}
18171824
else {
@@ -1896,6 +1903,7 @@ static ERR xtag_image(extSVG *Self, svgState &State, XMLTag &Tag, OBJECTPTR Pare
18961903
SetOwner(pic, image); // It's best if the pic belongs to the image.
18971904

18981905
Self->Scene->addDef(id.c_str(), image);
1906+
track_object(Self, image);
18991907
}
19001908
else return ERR::CreateObject;
19011909
}

src/svg/svg.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,7 @@ class extSVG : public objSVG {
9494
std::map<OBJECTID, svgAnimState> Animatrix; // For animated transforms, a vector may have one matrix only.
9595
std::vector<std::unique_ptr<svgLink>> Links;
9696
std::vector<svgInherit> Inherit;
97+
std::vector<OBJECTID> Resources; // Resources to terminate if ENFORCE_TRACKING was enabled.
9798
std::map<ULONG, std::vector<anim_base *>> StartOnBegin; // When the animation indicated by ULONG begins, it must activate() the referenced anim_base
9899
std::map<ULONG, std::vector<anim_base *>> StartOnEnd; // When the animation indicated by ULONG ends, it must activate() the referenced anim_base
99100
TIMER AnimationTimer;
@@ -159,6 +160,13 @@ static void xtag_use(extSVG *, svgState &, XMLTag &, OBJECTPTR);
159160
static ERR xtag_style(extSVG *, XMLTag &);
160161
static void xtag_symbol(extSVG *, XMLTag &);
161162

163+
inline void track_object(extSVG *SVG, OBJECTPTR Object)
164+
{
165+
if ((SVG->Flags & SVF::ENFORCE_TRACKING) != SVF::NIL) {
166+
SVG->Resources.emplace_back(Object->UID);
167+
}
168+
}
169+
162170
//********************************************************************************************************************
163171

164172
#include "funit.cpp"

src/svg/svg.fdl

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,8 @@
33
module({ name="SVG", copyright="Paul Manias © 2010-2024", version=1.0, timestamp=20240611 }, function()
44
flags("SVF", { comment="SVG flags." },
55
"AUTOSCALE: In auto-resize mode, vector dimensions are scaled to the width and height of the vector page. The @VectorScene.PageWidth and @VectorScene.PageHeight must be set for this.",
6-
"ALPHA: Generate an alpha channel in the rendered image.")
6+
"ALPHA: Generate an alpha channel in the rendered image.",
7+
"ENFORCE_TRACKING: Enforce tracking of definition objects when a Target is used.")
78

89
methods("svg", "Svg", {
910
{ id=1, name="Render" },

src/svg/svg_def.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
11
#undef MOD_IDL
2-
#define MOD_IDL "c.SVF:ALPHA=0x2,AUTOSCALE=0x1\n"
2+
#define MOD_IDL "c.SVF:ALPHA=0x2,AUTOSCALE=0x1,ENFORCE_TRACKING=0x4\n"

0 commit comments

Comments
 (0)