Visual LISP, AutoLISP and General Customization
cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

TextWidth before Text creation

15 REPLIES 15
Reply
Message 1 of 16
aqdam1978
689 Views, 15 Replies

TextWidth before Text creation

Hi, 

 

I want to know is there any formula/calculation for the width of text object before creation/insertion?

 

at now I used apploximated width size via a simple code:

 

(Defun GetStrWidth (str H W) (fix (*(* H W) (strlen str))))
;;usage: (GetStrWidth "This is a Text." 2.5 0.8)
;;H: TextHeight; W: width factor.

 

 

I know that for the existed text in drawing I can use textbox command, but for the texts that has not been created,

what can I do?

Is there any formula/calculation depands on font name, text height and width factor?

 

Thanks,

 

 

 

15 REPLIES 15
Message 2 of 16
Kent1Cooper
in reply to: aqdam1978

Wow....  It's hard to imagine.  It would require not only the font, height, and width factor, but whatever is doing the calculation would need to know the widths of every possible character, to add them up for the characters used in the text string.  If you were only talking about .SHP/.SHX fonts, maybe something could be made to read the font files and figure all of that out, but as for other font types [TrueType, for the main possibility], I wouldn't have a clue whether it would be possible at all.

Kent Cooper, AIA
Message 3 of 16
aqdam1978
in reply to: Kent1Cooper

Hi Kent,

 

YES, you are right.

That simple code works fine for MonoSpaced fonts, but for other types of font, NO!

 

In programming languages (like Delphi), there is a "Form" and "Canvas" for project.

we can assign a font to Canvas and it's possible to get width of texts before insertion.

 

I thought maybe there is a solution in AutoLisp like as other visual form-based proframming languages!

 

Thanks,

 

Abbas

 

 

Message 4 of 16
pbejse
in reply to: aqdam1978


@aqdam1978 wrote:

 

 

I know that for the existed text in drawing I can use textbox command, but for the texts that has not been created,

what can I do?

  


Curious what you want to achive here aqdam1978, perhaps there is another way thru textbox function. or is it a general question?

 

Message 5 of 16
hmsilva
in reply to: aqdam1978

aqdam1978 wrote:

Hi,

I want to know is there any formula/calculation for the width of text object before creation/insertion?

...

 

Abbas,

perhaps creating a temporary object, something like

 

(defun test (str TS H W / txt txtobj ll ur llpt urpt brpt Width)
;; usage:(test "This is a Text." "Standard" 2.5 0.8)
;; TS TextStyle; H: TextHeight; W: width factor.
;; returns the text string with or nil
;; if text style doesn't exist...
  (if (tblsearch "style" TS)
    (progn
      (entmake (list
		 '(0 . "TEXT")
		 '(100 . "AcDbEntity")
		 '(8 . "0")
		 '(100 . "AcDbText")
		 '(10 0.0 0.0 0.0)
		 (cons 40 H)
		 '(1 . "This Is A Test")
		 '(50 . 0.0)
		 (cons 41 W)
		 '(51 . 0.0)
		 (cons 7 TS)
		 '(71 . 0)
		 '(72 . 0)
		 '(11 0.0 0.0 0.0)
		 '(210 0.0 0.0 1.0)
		 '(100 . "AcDbText")
		 '(73 . 0)
	       );; list
      );; entmake
      (setq txt (entlast))
      (setq txtobj (vlax-ename->vla-object txt))
      (vla-getboundingbox txtobj 'll 'ur)
      (setq llpt  (vlax-safearray->list ll)
	    urpt  (vlax-safearray->list ur)
	    brpt  (list (car urpt) (cadr llpt) (caddr llpt))
	    Width (distance llpt brpt)
      )
      (entdel txt)
      Width
    );; progn
  );; if
);; test

 

Henrique

EESignature

Message 6 of 16
aqdam1978
in reply to: pbejse

Hi Pbejse, assume that I want to make columns of text like this:
Column1 Column2 ... ColumnN
---------- --------- ..... ---------
---------- --------- ..... ---------
---------- --------- ..... ---------
---------- --------- ..... ---------
---------- --------- ..... ---------
---------- --------- ..... ---------

(setq Column1 (list "str1" "str2" "str3"..... "strN"))
(setq Column2 (list "str1" "str2" "str3"..... "strN"))
.....
(setq ColumnN (list "str1" "str2" "str3"..... "strN"))

I put the fisrt column Texts in drawing via:

 

(setq X 0 Y 100)
(command "text" "s" "romans" "j" "ML" (list X (setq Y (- Y 5))) 0 (nth i Column1))

 

but for the second column:
(setq X (+ X dX) Y 100)
(command "text" "s" "romans" "j" "ML" (list X (setq Y (- Y 5))) 0 (nth i Column2))

 

So, I need dX value, dX is the widest text in Column1
in fact I need to calculate dX value for each column.

 

Thanks,

 

Abbas

Message 7 of 16
pbejse
in reply to: aqdam1978

I'll have a look-see tomorow Abbas 🙂

 

 

Message 8 of 16
devitg
in reply to: aqdam1978

What about using tables , check for the wide most text , and set column wide as need ?

Message 9 of 16
aqdam1978
in reply to: hmsilva

Hi Henrique,

 

Thanks for your code,

I also think there is no way except temporary creation!

 

I updated your code to:

(defun GetTextWidth (str TS H W / txt txtobj ll ur llpt urpt brpt Width fn)
;; usage:(GetTextWidth "This is a Text." "Standard" 2.5 0.8)
;; TS TextStyle; H: TextHeight; W: width factor.
(if (not (tblsearch "style" TS))(progn (setq fn "romans.shx")
	(if (=(setq txt (getstring (strcat "Give the FONT NAME <" fn ">: "))) "") ()(setq fn txt))
	(command "-style" TS fn  2 1 0 "N" "N" "N"))
)
      (entmake (list
		 '(0 . "TEXT")
		 '(100 . "AcDbEntity")
		 '(8 . "0")
		 '(100 . "AcDbText")
		 '(10 0.0 0.0 0.0)
		 (cons 40 H)
		 (cons 1 str)
		 '(50 . 0.0)
		 (cons 41 W)
		 '(51 . 0.0)
		 (cons 7 TS)
		 '(71 . 0)
		 '(72 . 0)
		 '(11 0.0 0.0 0.0)
		 '(210 0.0 0.0 1.0)
		 '(100 . "AcDbText")
		 '(73 . 0)
	       );; list
      );; entmake
      (setq txt (entlast))
      (setq txtobj (vlax-ename->vla-object txt))
      (vla-getboundingbox txtobj 'll 'ur)
      (setq llpt  (vlax-safearray->list ll)
	    urpt  (vlax-safearray->list ur)
	    brpt  (list (car urpt) (cadr llpt) (caddr llpt))
	    Width (distance llpt brpt)
      )
      (entdel txt)
      Width
)

 Thanks,

 

Abbas

 

Message 10 of 16
hmsilva
in reply to: aqdam1978

Abbas,
using

 

(setq lastent (entlast))
(setq ss (ssadd))

;;here your text stuff for Column1
;;(command "text" "s" "romans" "j" "ML" (list X (setq Y (- Y 5))) 0 (nth i Column1))

(while (setq lastent (entnext lastent))
(ssadd lastent ss)
)

 

You get all the new text in the selection set "ss". then, if you use the Kent Cooper's method in

 

"The smallest rectangle enclosing selected set of objects"

 

is easy to calculate "dX" value...

 

hope that helps

Henrique

EESignature

Message 11 of 16
aqdam1978
in reply to: hmsilva

Hi Henrique,

 

Thanks for your new idea,

 

But before your comment I made a function: GetWidestSize!

because we had a function: GetTextWidth to each text object!

This code gives me "dX" value:

 

(defun GetWidestSize(lst TS TH TW / Result len n tmp)
(setq Result 0)
(if (> (setq len (length lst)) 0)
	(progn
		(load "GetTextWidth")
		(setq n -1)
		(repeat len
			(if (>(setq tmp (GetTextWidth (nth (setq n (1+ n)) lst) TS TH TW)) Result) (setq Result tmp))
		);;repeat
	);;progn
)
Result
)

;;usage
;;(setq lst (list "iiiii" "WWWWW" "------" "//////" "~~~~~"))
;;(GetWidestSize lst "RomanS" 2.5 0.8)

 

Thank you for your supports 🙂

But I will look for a solution without temporary creation of text objects.

 

Thanks,

 

Abbas

Message 12 of 16
hmsilva
in reply to: aqdam1978

You're welcome, Abbas

Cheers

EESignature

Message 13 of 16
aqdam1978
in reply to: aqdam1978

for text creating, we can use this function too:

 

(defun MakeText (str TS X Y H W C R O)
    (entmakex (list 
		'(0 . "TEXT")
		(cons 410 "Model")	;;Layout1,....
		(cons 8 "0")		;;layer name
		(cons 10 (list X Y 0.0));;Insertion Point
		(cons 40 H)			;;Height
		(cons 41 W)			;;Width Factor
		(cons 1 str)		;;Text value
		(cons 50 (* R 0.01745));;Rotation angle
		(cons 51 (* O 0.01745));;Oblique angle
		(cons 7 TS)			;;Text style name;"STANDARD";"RomanS"
		(cons 71 0)			;;[0]=regular text [2]=Text is backward|| [4]=Text is upside down
		(cons 62 C)			;;color 0..256; BYLAYER=256
         );;list
    );;entmake
)

 

;;usage:
;;(MakeText "This is a Text!" "STANDARD" 100 200 2.5 0.8 3 -45 -25)
;; or
;;(entget(MakeText "This is a Text!" "STANDARD" 100 200 2.5 0.8 3 -45 -25))

 

Message 14 of 16
pbejse
in reply to: aqdam1978


@aqdam1978 wrote:

Hi Henrique,

 

Thanks for your new idea,

 

But before your comment I made a function: GetWidestSize!

 

Abbas


This will give the same result using TEXTBOX function

 

(defun GetWidestSize2 (lst TS H W)
(apply 'max (mapcar '(lambda (d)
			(abs
			  (apply '- (mapcar 'car
                                            (textbox
                                              (list (cons 1 d)
                                                    (cons 7 ts)
                                                    (cons 40 h)
                                                    (cons 41 w)))))
			)
                       ) lst
                    )
       )
  )

 

 

Message 15 of 16
aqdam1978
in reply to: pbejse

Hi Pbejse,

 

As usual, your codes are amazing....

 

Thanks,

 

Abbas

 

Message 16 of 16
pbejse
in reply to: aqdam1978


@aqdam1978 wrote:

 

Thanks,

 

Abbas

 


You are welcome, Glad you like it.

 

🙂

Can't find what you're looking for? Ask the community or share your knowledge.

Post to forums  

Autodesk Design & Make Report

”Boost