2021-07-23 02:36:56 +02:00
#!/usr/bin/env python3
import inkex
import math
from lxml import etree
class BoundingBox ( inkex . EffectExtension ) :
def add_arguments ( self , pars ) :
pars . add_argument ( ' --offset ' , type = float , default = 0.0 , help = ' Offset from object (all directions) ' )
2021-11-05 02:08:20 +01:00
pars . add_argument ( ' --unit ' , default = " mm " )
2021-07-23 02:36:56 +02:00
pars . add_argument ( ' --box ' , type = inkex . Boolean , default = 0.0 , help = ' Draw boxes ' )
2021-10-16 00:50:17 +02:00
pars . add_argument ( ' --corner_radius ' , type = float , default = 0.0 , help = ' Corner radius ' )
2021-07-23 02:36:56 +02:00
pars . add_argument ( ' --circle ' , type = inkex . Boolean , default = 0.0 , help = ' Draw circles ' )
pars . add_argument ( ' --split ' , type = inkex . Boolean , default = True , help = ' Handle selection as group ' )
def drawBBox ( self , bbox ) :
2021-11-05 02:08:20 +01:00
so = self . options
offset = self . svg . unittouu ( str ( so . offset ) + so . unit )
2021-07-23 02:36:56 +02:00
if self . options . box :
attribs = {
2021-11-05 02:08:20 +01:00
' style ' : str ( inkex . Style ( { ' stroke ' : ' #ff0000 ' , ' stroke-width ' : str ( self . svg . unittouu ( " 1px " ) ) , ' fill ' : ' none ' } ) ) ,
' x ' : str ( bbox . left - offset ) ,
' y ' : str ( bbox . top - offset ) ,
' width ' : str ( bbox . width + 2 * offset ) ,
' height ' : str ( bbox . height + 2 * offset ) ,
2021-10-16 00:50:17 +02:00
' ry ' : str ( self . options . corner_radius ) ,
' rx ' : str ( self . options . corner_radius )
2021-07-23 02:36:56 +02:00
}
etree . SubElement ( self . svg . get_current_layer ( ) , inkex . addNS ( ' rect ' , ' svg ' ) , attribs )
if self . options . circle :
attribs = {
2021-11-05 02:08:20 +01:00
' style ' : str ( inkex . Style ( { ' stroke ' : ' #ff0000 ' , ' stroke-width ' : str ( self . svg . unittouu ( " 1px " ) ) , ' fill ' : ' none ' } ) ) ,
2021-07-23 02:36:56 +02:00
' cx ' : str ( bbox . center_x ) ,
' cy ' : str ( bbox . center_y ) ,
2021-11-05 02:08:20 +01:00
#'r' : str(bbox.width / 2 + offset),
' r ' : str ( math . sqrt ( ( bbox . width + 2 * offset ) * ( bbox . width + 2 * offset ) + ( bbox . height + 2 * self . options . offset ) * ( bbox . height + 2 * self . options . offset ) ) / 2 ) ,
2021-07-23 02:36:56 +02:00
}
etree . SubElement ( self . svg . get_current_layer ( ) , inkex . addNS ( ' circle ' , ' svg ' ) , attribs )
2021-11-05 02:08:20 +01:00
2021-07-23 02:36:56 +02:00
def effect ( self ) :
2021-11-05 02:08:20 +01:00
scale_factor = self . svg . unittouu ( " 1px " )
2021-07-23 02:36:56 +02:00
if len ( self . svg . selected ) > 0 :
if self . options . split is False :
for element in self . svg . selected . values ( ) :
2021-11-05 02:08:20 +01:00
if isinstance ( element , inkex . ShapeElement ) and element . tag != inkex . addNS ( ' use ' , ' svg ' ) and element . get ( ' inkscape:groupmode ' ) != ' layer ' : #bbox fails for svg:use elements and layers:
if isinstance ( element , inkex . Rectangle ) or \
isinstance ( element , inkex . Circle ) or \
isinstance ( element , inkex . Ellipse ) :
self . drawBBox ( element . bounding_box ( ) * scale_factor )
else :
self . drawBBox ( element . bounding_box ( ) )
else : #combined bbox
2021-07-23 02:36:56 +02:00
#self.drawBBox(self.svg.get_selected_bbox()) #works for InkScape (1:1.0+devel+202008292235+eff2292935) @ Linux and for Windows (but with deprecation)
2021-11-05 02:08:20 +01:00
#self.drawBBox(self.svg.selection.bounding_box()) #works for InkScape 1.1dev (9b1fc87, 2020-08-27)) @ Windows
bbox = inkex . BoundingBox ( )
for element in self . svg . selected . values ( ) :
if isinstance ( element , inkex . ShapeElement ) and element . tag != inkex . addNS ( ' use ' , ' svg ' ) and element . get ( ' inkscape:groupmode ' ) != ' layer ' : #bbox fails for svg:use elements and layers:
if isinstance ( element , inkex . Rectangle ) or \
isinstance ( element , inkex . Circle ) or \
isinstance ( element , inkex . Ellipse ) :
bbox + = element . bounding_box ( ) * scale_factor
else :
bbox + = element . bounding_box ( )
self . drawBBox ( bbox )
2021-07-23 02:36:56 +02:00
else :
inkex . errormsg ( ' Please select some objects first. ' )
return
if __name__ == ' __main__ ' :
BoundingBox ( ) . run ( )