# HG changeset patch # User Edouard Tisserant # Date 1582902561 -3600 # Node ID eee5dcd9fc928a9cc3294a3c20793ab934fc76b3 # Parent 94696b3f69fb6554df7946279babf36fff9d7441 SVGHMI: detachable and discardable elements sets, Reworked geometric intersection, toward more accurate page content detection. Moved page's widget/element dependency crawling functions so that it is possible to compute a global detachable and discardable elements sets. Reworked geometric intersection detection logic to distinguish ovelapping and inclusion. Goal is to include englobing and overlapping graphical elements, but not groups (would then include everything around...). Intermediate commit, to be continued. diff -r 94696b3f69fb -r eee5dcd9fc92 svghmi/gen_index_xhtml.xslt --- a/svghmi/gen_index_xhtml.xslt Thu Feb 27 13:14:24 2020 +0100 +++ b/svghmi/gen_index_xhtml.xslt Fri Feb 28 16:09:21 2020 +0100 @@ -47,6 +47,90 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -139,6 +223,24 @@ + + Detachable : + + + + + + + + + Discardable : + + + + + + + @@ -200,39 +302,6 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - //(function(){ @@ -377,7 +446,7 @@ - ] + ], required_elements: [ @@ -846,11 +915,27 @@ + // function prepare_svg() { + + // /* set everybody hidden initially for better performance */ + + // for(let [elt,elt_parent] in detachable_elements){ + + // elt_parent.removeChild(elt) + + // } + + // }; + + + function prepare_svg() { /* set everybody hidden initially for better performance */ - for(let widget in hmi_widgets){ + for(let widget_id in hmi_widgets){ + + let widget = hmi_widgets[widget_id]; if(widget.element != undefined) @@ -858,16 +943,6 @@ } - /*for(let name in page_desc){ - - if(name != new_desc){ - - page_desc[name].widget.element.style.display = "none"; - - } - - }*/ - }; diff -r 94696b3f69fb -r eee5dcd9fc92 svghmi/gen_index_xhtml.ysl2 --- a/svghmi/gen_index_xhtml.ysl2 Thu Feb 27 13:14:24 2020 +0100 +++ b/svghmi/gen_index_xhtml.ysl2 Fri Feb 28 16:09:21 2020 +0100 @@ -73,8 +73,98 @@ const "indexed_hmitree", "exsl:node-set($_indexed_hmitree)"; - // TODO globally discardable elements, not (used by | ancestor of) any page - + // returns all directly or indirectly refered elements + def "func:refered_elements" { + param "elems"; + const "descend", "$elems/descendant-or-self::svg:*"; + const "clones", "$descend[self::svg:use]"; + const "originals", "//svg:*[concat('#',@id) = $clones/@xlink:href]"; + choose { + when "$originals" + result "$descend | func:refered_elements($originals)"; + otherwise + result "$descend"; + } + } + + def "func:intersect_1d" { + /* it is assumed that a1 > a0 and b1 > b0 */ + param "a0"; + param "a1"; + param "b0"; + param "b1"; + + const "d0", "$a0 >= $b0"; + const "d1", "$a1 >= $b1"; + choose { + when "not($d0) and $d1" + result "3"; /* a included in b */ + when "$d0 and not($d1)" + result "2"; /* b included in a */ + when "$d0 = $d1 and $b0 < $a1" + result "1"; /* a and b are overlapped */ + otherwise + result "0"; /* no intersection*/ + } + } + + def "func:intersect" { + param "a"; + param "b"; + + const "x_intersect", "func:intersect_1d($a/@x, $a/@x+$a/@w, $b/@x, $b/@x+$b/@w)"; + + choose{ + when "$x_intersect != 0"{ + const "y_intersect", "func:intersect_1d($a/@y, $a/@y+$a/@w, $b/@y, $b/@y+$b/@w)"; + result "$x_intersect * $y_intersect"; + } + otherwise result "0"; + } + } + + // return overlapping geometry a given element + def "func:overlapping_geometry" { + param "elt"; + /* only included groups are returned */ + /* all other elemenst are returne when overlapping*/ + const "g", "$geometry[@Id = $elt/@id]"; + result """$geometry[@Id != $elt/@id and func:intersect(., $g) = 4]"""; + } + + def "func:sumarized_elements" { + param "elements"; + const "short_list", "$elements[not(ancestor::*/@id = $elements/@id)]"; + /* TODO exclude globally discardable elements from group fulfillment check */ + const "filled_groups", "$short_list/parent::svg:*[not(descendant::*[not(self::svg:g)][not(@id = $short_list/descendant-or-self::*[not(self::svg:g)]/@id)])]"; + const "groups_to_add", "$filled_groups[not(ancestor::*/@id = $filled_groups/@id)]"; + result "$groups_to_add | $short_list[not(ancestor::svg:g/@id = $filled_groups/@id)]"; + } + + def "func:all_related_elements" { + param "page"; + const "page_overlapping_geometry", "func:overlapping_geometry($page)"; + const "page_overlapping_elements", "//svg:*[@id = $page_overlapping_geometry/@Id]"; + const "page_sub_elements", "func:refered_elements($page | $page_overlapping_elements)"; + result "$page_sub_elements"; + } + + def "func:detachable_elements" { + param "pages"; + choose{ + when "$pages"{ + result """func:sumarized_elements(func:all_related_elements($pages[1])) + | func:detachable_elements($pages[position()!=1])"""; + }otherwise{ + result "/.."; + } + } + } + + const "detachable_elements", "func:detachable_elements($hmi_pages)"; + const "essential_elements", "$detachable_elements | /svg:svg/svg:defs"; + const "required_elements", "$essential_elements//svg:* | $essential_elements/ancestor-or-self::svg:*"; + const "discardable_elements", "//svg:*[not(@id = $required_elements/@id)]"; template "*", mode="index" { param "index", "0"; @@ -193,6 +283,18 @@ comment { apply "$indexed_hmitree", mode="testtree"; } + comment { + | Detachable : + foreach "$detachable_elements"{ + | «@id» + } + } + comment { + | Discardable : + foreach "$discardable_elements"{ + | «@id» + } + } /**/ html xmlns="http://www.w3.org/1999/xhtml" xmlns:svg="http://www.w3.org/2000/svg" @@ -254,48 +356,6 @@ result "exsl:node-set($ast)"; } - // returns all directly or indirectly refered elements - def "func:refered_elements" { - param "elems"; - const "descend", "$elems/descendant-or-self::svg:*"; - const "clones", "$descend[self::svg:use]"; - const "originals", "//svg:*[concat('#',@id) = $clones/@xlink:href]"; - choose { - when "$originals" - result "$descend | func:refered_elements($originals)"; - otherwise - result "$descend"; - } - } - - // return included geometry a given element - def "func:included_geometry" { - param "elt"; - const "g", "$geometry[@Id = $elt/@id]"; - result """$geometry[@Id != $elt/@id and - @x >= $g/@x and @y >= $g/@y and - @x+@w <= $g/@x+$g/@w and @y+@h <= $g/@y+$g/@h]"""; - - } - - def "func:sumarized_elements" { - param "elements"; - const "short_list", "$elements[not(ancestor::*/@id = $elements/@id)]"; - /* TODO exclude globally discardable elements from group fulfillment check */ - const "filled_groups", "$short_list/parent::svg:*[not(descendant::*[not(self::svg:g)][not(@id = $short_list/descendant-or-self::*[not(self::svg:g)]/@id)])]"; - const "groups_to_add", "$filled_groups[not(ancestor::*/@id = $filled_groups/@id)]"; - result "$groups_to_add | $short_list[not(ancestor::svg:g/@id = $filled_groups/@id)]"; - } - - def "func:all_related_elements" { - param "page"; - const "page_included_geometry", "func:included_geometry($page)"; - const "page_sub_elements", "func:refered_elements($page)"; - - const "page_included_elements", "//svg:*[@id = $page_included_geometry/@Id]"; - result "$page_sub_elements | $page_included_elements"; - } - function "scripts" { | //(function(){ @@ -380,7 +440,7 @@ foreach "$all_page_ids" { | hmi_widgets["«.»"]`if "position()!=last()" > ,` } - | ] + | ], | required_elements: [ foreach "$shorter_list" { | "«@id»",