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,
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.
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
@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?
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
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
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
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
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
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))
@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 ) ) )