Extension rotate text help needed

Discussion about writing code for Inkscape.
draftman
Posts: 39
Joined: Sun Jan 25, 2015 5:29 am

Extension rotate text help needed

Postby draftman » Sun Jan 25, 2015 6:51 am

I'm modifying the number nodes extension in inkscape .48.5 and, I need to rotate the text 90 deg.
Anyone know the code for this?
Here is the text part of the code.

Code: Select all

                       self.addText(
                          self.numGroup,
                          params[-2] + ( inkex.unittouu(self.options.dotsize) / 2 ),
                          params[-1] - ( inkex.unittouu(self.options.dotsize) / 2 ),
                          num )
                        num += 1
                node.getparent().remove (node)


    def addText(self,node,x,y,text):
                new = inkex.etree.SubElement(node,inkex.addNS('text','svg'))
                s = {'font-size': self.options.fontsize, 'fill-opacity': '1.0', 'stroke': 'none',
                     'font-weight': 'normal', 'font-style': 'normal', 'fill': '#999'}
                new.set('style', simplestyle.formatStyle(s))
                new.set('x', str(x))
                new.set('y', str(y))
                new.text = str(text)

User avatar
ragstian
Posts: 1181
Joined: Thu Oct 11, 2012 2:44 am
Location: Stavanger-Norway

Re: Extension rotate text help needed

Postby ragstian » Sun Jan 25, 2015 1:32 pm

Hi.
I'm modifying the number nodes extension in inkscape .48.5 and, I need to rotate the text 90 deg.
Anyone know the code for this?

90°- Which way?
Know -- not really!
The text rotation in SVG files is way over my head!

Anyway, here are some code that works:

Code: Select all

                inkex.etree.SubElement(
                  self.dotGroup,
                  inkex.addNS('circle','svg'),
                  dot_att )
               
                # Added rotation of text - Ragnar Stiansen 24-Jan-15
                cx = params[-2]
                cy = params[-1]
                r = self.unittouu(self.options.dotsize) / 2
                t='rotate(%f,%f,%f) matrix(1,0,0,1,0,-%f)' % (90,cx,cy,r+4)
               
                self.addText(
                  self.numGroup,
                  params[-2] + ( self.unittouu(self.options.dotsize) / 2 ),
                  params[-1] - ( self.unittouu(self.options.dotsize) / 2 ),
                  num, transform = t )
                num += self.options.step
        node.getparent().remove( node )

    def addText(self,node,x,y, text, transform=None):
                new = inkex.etree.SubElement(node,inkex.addNS('text','svg'))
                s = {'font-size': self.unittouu(self.options.fontsize),  'fill-opacity': '1.0', 'stroke': 'none',
                    'font-weight': 'normal', 'font-style': 'normal', 'fill': '#999'}
                   
                new.set('style', simplestyle.formatStyle(s))
                if not transform==None:
                   new.set('transform', str(transform))
                new.set('x', str(x))
                new.set('y', str(y))
                new.text = str(text)   
               
if __name__ == '__main__':


To vary the rotation change the "90" in the t='rotate(%f,%f,%f) matrix(1,0,0,1,0,-%f)' % (90,cx,cy,r+4) line.
(if needed replace the "90" by your variable name here.)
The "r" variable is the distance from the dot center to the text start, change to your liking.
Note the addition of transform = t in the self.addText parameter list.

If you cut and past from this code you might have to edit the indentation, for some reason the forum sometimes changes the indentation!
Another caveat - the python interpreter used in inkscape does not like a mix of tab and space characters as indentation in the code.

If any more help is needed please chime back. Chime back if you need the edited dot.py file.
Please submit your new extension!!

Example - using the "default" 90°degree (rotate right) rotation
- the "before" part was done with the original code - the "after" with the "new" code:
Image

RGDS
Ragnar
Good Luck!
( ͡° ͜ʖ ͡°)
RGDS
Ragnar

draftman
Posts: 39
Joined: Sun Jan 25, 2015 5:29 am

Re: Extension rotate text help needed

Postby draftman » Mon Jan 26, 2015 7:35 am

Thanks , Ragstian
That was exactly what I was looking for, and thank you for the detailed explanations (really helped).
I will post my extension as soon as I finish it.
Is there a category I should post it in, or just post it here?

User avatar
ragstian
Posts: 1181
Joined: Thu Oct 11, 2012 2:44 am
Location: Stavanger-Norway

Re: Extension rotate text help needed

Postby ragstian » Mon Jan 26, 2015 8:38 am

Hi.

Glad I could help! Took me some time to figure it out!

For your "new extension - just post it here.

RGDS
Ragnar
Good Luck!
( ͡° ͜ʖ ͡°)
RGDS
Ragnar

draftman
Posts: 39
Joined: Sun Jan 25, 2015 5:29 am

Re: Extension rotate text help needed

Postby draftman » Sun Feb 01, 2015 3:04 pm

Here's the modified code.
This extension creates dimension lines in feet & inches for architectural drawings.

This is my first attempt at programming, with the exception of a little bit of Html and Js.
So, if you see any mistakes please let me know.
I should also mention that I'm using Windows 7/ Inkscape .48.5 .

DimensionLines.py

Code: Select all

#!/usr/bin/env python
'''
Copyright (C) 2005 Aaron Spike, aaron@ekips.org
Modified by DR construction.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
'''
import inkex, simplestyle, simplepath, math

class DimLine(inkex.Effect):

    def __init__(self):
        inkex.Effect.__init__(self)
        self.OptionParser.add_option("--scale",
                        action="store", type="string",
                        dest="scale", default="pc",
                        help="i need it")
        self.OptionParser.add_option("-d", "--extrudeL",
                        action="store", type="string",
                        dest="extrudeL", default="50",
                        help="Size of the dots placed at path nodes")
        self.OptionParser.add_option("--type",
                        action="store", type="string",
                        dest="type", default="ortho",
                        help="i need it")
        self.OptionParser.add_option("-f", "--fontsize",
                        action="store", type="string",
                        dest="fontsize", default="12",
                        help="Size of node label numbers")
        self.OptionParser.add_option("--extrudeD",
                        action="store", type="string",
                        dest="extrudeD", default="down",
                        help="i need it")



    def effect(self):
        for id, node in self.selected.iteritems():
            if node.tag == inkex.addNS('path','svg'):
                self.group = inkex.etree.SubElement( node.getparent(), inkex.addNS('g','svg') )
                self.dotGroup = inkex.etree.SubElement( self.group, inkex.addNS('g','svg') )
                self.numGroup = inkex.etree.SubElement( self.group, inkex.addNS('g','svg') )
               
                try:
                    t = node.get('transform')
                    self.group.set('transform', t)
                except:
                    pass

                style = simplestyle.formatStyle({ 'stroke': '#000', 'stroke-width': '.6','fill': 'none' })
                a = []
                p = simplepath.parsePath(node.get('d'))
            
                num = 0
                for cmd,params in p:
                    if cmd != 'Z' and cmd != 'z':
                        font = int(self.options.fontsize)                  
                        exl = int(self.options.extrudeL)
                        #runing coordiances
                        x1 = p[num-1][1][-2]
                        y1 = p[num-1][1][-1]
                        x2 = p[num][1][-2]
                        y2 = p[num][1][-1]
                  #set coordiances
                        x1set= p[0][1][-2]
                        y1set= p[0][1][-1]
                        y2set = p[-1][1][-1]
                        x2set = p[-1][1][-2]
                  #type ortho, step
                        if self.options.type == "ortho":
                            y1flex = y1set
                            x1flex = x1set
                        if self.options.type == "step":
                            y1flex = y1
                            x1flex = x1

                        if self.options.extrudeD == "up":
                            if 0 > (x2 - x1): boo = 0
                            if 0 < (x2 - x1): boo = x2 - x1
                     #text x,y, degree
                            xtp = params[-2] - ( boo/2 )
                            ytp = y1set - exl - 5
                            deg = 0               

                            #extrude line                  
                            line_att = {
                              'style': style,
                              'd' : 'M '+str(x1)+','+str(y1flex - 3)+' L '+str(x1)+','+str((y1set - exl) - 10)
                            }
                     #measurement line
                            line2_att = {
                              'style': style,
                              'd' : 'M '+str(x1)+','+str((y1set - exl) )+' L '+str(x1 + boo)+','+str((y1set - exl) )
                            }
                     #tick
                            line3_att = {
                              'style': style,
                              'd' : 'M '+str(x1 - 5)+','+str((y1set - exl) + 5)+' L '+str(x1 + 5)+','+str((y1set - exl) - 5)
                            }
                        if self.options.extrudeD == "down":
                            if 0 > (x2 - x1): boo = 0
                            if 0 < (x2 - x1): boo = x2 - x1
                     #text x,y, degree
                            xtp = params[-2] - ( boo/2 )
                            ytp = y1set + exl + 5 + font
                            deg = 0   
                            #extrude line                  
                            line_att = {
                              'style': style,
                              'd' : 'M '+str(x1)+','+str(y1flex + 3)+' L '+str(x1)+','+str((y1set + exl) + 10)
                            }
                     #measurement line
                            line2_att = {
                              'style': style,
                              'd' : 'M '+str(x1)+','+str((y1set + exl) )+' L '+str(x1 + boo)+','+str((y1set + exl) )
                            }
                     #tick
                            line3_att = {
                              'style': style,
                              'd' : 'M '+str(x1 - 5)+','+str((y1set + exl) + 5)+' L '+str(x1 + 5)+','+str((y1set + exl) - 5)
                            }
                        if self.options.extrudeD == "left":
                            if 0 > (y1 - y2): boo = 0
                            if 0 < (y1 - y2): boo = y1 - y2
                     #text x,y, degree
                            xtp = x1set - exl - 5
                            ytp = y1 - ( boo/2 )
                            cx = x1 - exl - 5
                            cy = y1 - ( boo/2 )
                            deg = -90
                            #extrude line                  
                            line_att = {
                              'style': style,
                              'd' : 'M '+str(x1flex - 3)+','+str(y1)+' L '+str((x1set - exl)- 10)+','+str(y1)
                            }
                     #measurement line
                            line2_att = {
                              'style': style,
                              'd' : 'M '+str(x1set - exl)+','+str(y1)+' L '+str(x1set - exl)+','+str(y1 - boo)
                            }
                     #tick
                            line3_att = {
                              'style': style,
                              'd' : 'M '+str((x1set - exl) - 5)+','+str(y1 + 5)+' L '+str(x1set - exl + 5)+','+str(y1 - 5)
                            }
                        if self.options.extrudeD == "right":
                            if 0 > (y1 - y2): boo = 0
                            if 0 < (y1 - y2): boo = y1 - y2
                     #text x,y, degree
                            xtp = x1set + exl + 5 + font
                            ytp = y1 - ( boo/2 )
                            cx = x1 + exl + 5 + font
                            cy = y1 - ( boo/2 )
                            deg = -90
                            #extrude line                  
                            line_att = {
                              'style': style,
                              'd' : 'M '+str(x1flex + 3)+','+str(y1)+' L '+str((x1set + exl)+ 10)+','+str(y1)
                            }
                     #measurement line
                            line2_att = {
                              'style': style,
                              'd' : 'M '+str(x1set + exl)+','+str(y1)+' L '+str(x1set + exl)+','+str(y1 - boo)
                            }
                     #tick
                            line3_att = {
                              'style': style,
                              'd' : 'M '+str((x1set + exl) - 5)+','+str(y1 + 5)+' L '+str(x1set + exl + 5)+','+str(y1 - 5)
                            }
 
                        inkex.etree.SubElement(
                          self.dotGroup,
                          inkex.addNS('path','svg'),
                          line_att )                  
                        inkex.etree.SubElement(
                          self.dotGroup,
                          inkex.addNS('path','svg'),
                          line2_att )
                        inkex.etree.SubElement(
                          self.dotGroup,
                          inkex.addNS('path','svg'),
                          line3_att )
                  #Text
                        scale = float(self.options.scale)
                        feet = (boo / scale) + .0415
                        inch = ((boo / scale) + .0415)%1 * 12
                        if boo == 0: leng = " "                     
                        if boo != 0: leng = str(int(feet)) + " ' - " + str(int(inch)) + ' " '
                        # Added rotation of text - Ragnar Stiansen 24-Jan-15
                        t='rotate(%f,%f,%f) matrix(1,0,0,1,0,-%f)' % (deg,xtp,ytp,0)
                       
                        self.addText(
                          self.numGroup,
                          xtp,
                          ytp,
                          leng, transform = t )
                        num += 1
                node.getparent().remove (node)

    def addText(self,node,x,y,text, transform=None):
                new = inkex.etree.SubElement(node,inkex.addNS('text','svg'))
                s = {'text-align': 'center', 'vertical-align': 'top','text-anchor': 'middle',
                'font-size': self.options.fontsize, 'fill-opacity': '1.0', 'stroke': 'none',
                    'font-weight': 'normal', 'font-style': 'normal', 'fill': '#000'}
                new.set('style', simplestyle.formatStyle(s))
                if not transform==None:
                    new.set('transform', str(transform))
                new.set('x', str(x))
                new.set('y', str(y))
                new.text = str(text)

               
if __name__ == '__main__':
    e = DimLine()
    e.affect()


# vim: expandtab shiftwidth=4 tabstop=8 softtabstop=4 encoding=utf-8 textwidth=99


DimensionLine.inx

Code: Select all

<?xml version="1.0" encoding="UTF-8"?>
<inkscape-extension xmlns="http://www.inkscape.org/namespace/inkscape/extension">
    <_name>Dimension Lines</_name>
    <id>dr.const.filter.DimensionLines</id>
   <dependency type="executable" location="extensions">DimensionLines.py</dependency>
   <dependency type="executable" location="extensions">inkex.py</dependency>
   <param name="scale" type="enum" _gui-text="Scale 1'=">
               <_item value= "1" >px</_item>
            <_item value= "15" >pc</_item>
            <_item value= "135" >1 1/2"</_item>
            <_item value= "90" >1"</_item>
            <_item value= "67.5" >3/4"</_item>
            <_item value= "45" >1/2"</_item>
            <_item value= "33.75" >3/8"</_item>
            <_item value= "22.5" >1/4"</_item>
            <_item value= "16.875" >3/16"</_item>
            <_item value= "11.25" >1/8"</_item>
         </param>

   <param name="fontsize" type="string" _gui-text="Font size">12</param>
   <param name="type" type="enum" _gui-text=" Type ">
               <_item value="ortho">ortho</_item>
            <_item value="step">step</_item>
         </param>
   <param name="extrudeL" type="string" _gui-text="Extrude length (px)">50</param>
   <param name="extrudeD" type="enum" _gui-text="Extrude direction ">
               <_item value="up">up</_item>
            <_item value="down">down</_item>
            <_item value="left">left</_item>
            <_item value="right">right</_item>
         </param>
    <effect>
      <object-type>path</object-type>
                <effects-menu>
                    <submenu _name="Architectural"/>
                </effects-menu>
    </effect>
    <script>
        <command reldir="extensions" interpreter="python">DimensionLines.py</command>
    </script>
</inkscape-extension>


Directions to use Dimension Line extension.
- Open extension (Extensions/Architectural/Dimension Lines)
Set settings -
Scale 1'= (whatever you want)
Font size - 12
Type - ortho
Extrude length - 50
Extrude direction - up
- Draw a large square (to represent plans)
- Turn on snapping.
- Select the Bezier tool. Then select straight line segments mode (the squiggly looking icon).
- Snap the Bezier tool to the top left hand corner of square and click once.
- Then click anywhere within the square
- Then snap to right hand corner (top or bottom doesn't matter) and double click.
- Click the Apply button.

- Important ! If Extrude Direction = up or down, you must always start left and move right. If Extrude Direction = left or right, you must always start at the bottom and move up

User avatar
ragstian
Posts: 1181
Joined: Thu Oct 11, 2012 2:44 am
Location: Stavanger-Norway

Re: Extension rotate text help needed

Postby ragstian » Sun Feb 01, 2015 5:22 pm

Hi.

Very nice extension! :D

A few comments, a nice addition would be to have an input for decimal precision.
Your extension could then be applied to engineering, woodworking etc.

The live preview tick box can be removed from the dialog as it's not working.

Used on a vertical line the extension "crashes* with an "out of bounds" error message,
it would be nice if these errors was trapped by the program giving the user feedback to change parameters.
(use inkex.erormsg to output the message along these lines,

Code: Select all

out_msg = "\tIncorrect Voltage Reading\n\tCheck motor power."
inkex.errormsg(out_msg)

Looking forward to more architectural extensions for Inkscape in the future.
Keep up the good work!
RGDS
Ragnar
Good Luck!
( ͡° ͜ʖ ͡°)
RGDS
Ragnar

draftman
Posts: 39
Joined: Sun Jan 25, 2015 5:29 am

Re: Extension rotate text help needed

Postby draftman » Tue Feb 03, 2015 1:11 pm

Live preview works every time for me.
Tried everything I could think of to get it to crash, but it just kept on working.
Oh Boy! My first bug.
Unfortunately live preview is pretty useful in this extension.

User avatar
ragstian
Posts: 1181
Joined: Thu Oct 11, 2012 2:44 am
Location: Stavanger-Norway

Re: Extension rotate text help needed

Postby ragstian » Tue Feb 03, 2015 1:55 pm

Hi.

draftman wrote:Tried everything I could think of to get it to crash, but it just kept on working.

That's because you know how the extension is supposed to work and you feed it what it needs.
Me on the other hand being a "stupid user" - I made one vertical line (click on one point and press ctrl
to draw a true vertical line) with two nodes - started your extension with the "default" settings = "orthographic" and "up".

Ended up with:
Image

I am pretty sure the first error I saw from the extension was an out of bounds error, will see if I can get another one!

Nice programming for a "first-timer"!

RGDS
Ragnar
Good Luck!
( ͡° ͜ʖ ͡°)
RGDS
Ragnar


Return to “Programming”