aboutsummaryrefslogtreecommitdiff
path: root/imagemap.py
diff options
context:
space:
mode:
authorViatrix2026-03-16 17:48:48 -0700
committerViatrix2026-03-16 17:53:39 -0700
commit90246c78b9b0a5c736c574d7d95159fbfe74c597 (patch)
treeca8696918acdf1913576cd5994989479cdce76a9 /imagemap.py
parentfbcbb4eff55d0703f9fee526e5caea4744e931f7 (diff)
Clip-paths now work!
Diffstat (limited to 'imagemap.py')
-rw-r--r--imagemap.py19
1 files changed, 17 insertions, 2 deletions
diff --git a/imagemap.py b/imagemap.py
index 3595323..9eb4132 100644
--- a/imagemap.py
+++ b/imagemap.py
@@ -62,8 +62,7 @@ class ImageMap(inkex.OutputExtension):
hscale=self.svg.viewport_height/viewBox[3] if viewBox[3]!=0 else 1
# preprocess shapes for our purposes.
- # after this, the shapes within the image must: look the same as before (barring colour/alpha), not be clones, have no stroke, not intersect, be visually unaffected by `fill-rule`, and not go out of bounds.
- # TODO pay attention to clip-path
+ # after this, the shapes within the image must: look the same as before (barring colour/alpha), not be clones, have no stroke, not intersect, be visually unaffected by `fill-rule`, not be clipped, and not go out of bounds.
links=[]
rects=[]
svgIDs=[i.get_id() for i in self.svg.iterdescendants('{http://www.w3.org/2000/svg}svg')]
@@ -92,13 +91,29 @@ class ImageMap(inkex.OutputExtension):
self.svg.append(rect)
rects+=[newid]
+ #clip-paths
+ clipped=[]
+ clippedpaths=set()
+ for clippedEl in self.svg.iterdescendants():
+ if not isinstance(clippedEl,inkex.BaseElement): continue
+ if clippedEl.cascaded_style().get('clip-path','none')=='none': continue
+ clipped.append([clippedEl.get_id(),0])
+ for el in clippedEl.descendants():
+ if not isinstance(el,inkex.ShapeElement) or isinstance(el,inkex.elements._groups.GroupBase):
+ clipped[-1][1]+=1 # can overshoot number of groups but works
+ continue
+ clippedpaths.add((el.get_id(),el.cascaded_style().get(CSS_LINK_INDEX)))
+
if len(links)==0:
raise inkex.AbortExtension(_("Image has no hyperlinks.\nAdd a hyperlink to an object with right-click → \"{}\".").format(_i("Create Anchor (Hyperlink)")))
command=\
''.join(f'select-clear;select-by-id:{i};selection-ungroup;' for i in reversed(svgIDs)) \
+ +''.join(f'select-clear;select-by-id:{i[0]};{"selection-ungroup;"*i[1]}' for i in reversed(clipped) if i[1]>0) \
+ +''.join(f'select-clear;select-by-id:{i[0]};object-release-clip;unselect-by-id:{i[0]};selection-set-backup;select-clear;select-by-id:{i[0]};object-stroke-to-path;selection-ungroup;path-union;object-set-attribute:id,{i[0]};selection-restore-backup;select-by-id:{i[0]};path-intersection;object-set-attribute:style,{CSS_LINK_INDEX}:{i[1]};' for i in clippedpaths) \
+''.join(f'select-clear;select-by-selector:[style~="{CSS_LINK_INDEX}-{i}"];object-stroke-to-path;selection-ungroup;path-union;select-by-id:{rects[i]};path-intersection;object-set-attribute:style,{CSS_LINK_INDEX}:" {CSS_LINK_INDEX}-{i} ";' for i in range(len(links))) \
+'select-all;path-flatten;path-split'
# (we re-set the existing style attribute in case it got unset on non-paths)
+ from lxml import etree
newbytes=inkscape_command(self.svg,actions=command)
self.svg=self.load(newbytes).getroot()
# preprocessing done, now for map generation