Halo text on ttf lisp

Halo text on ttf lisp

simon.connellRBKGZ
Contributor Contributor
6,945 Views
45 Replies
Message 1 of 46

Halo text on ttf lisp

simon.connellRBKGZ
Contributor
Contributor

I would like to make a lsp routine to make halo text for a ttf font. There are numerous posts about how it cant be done but I have worked out a way to make it work.

 

I have figured out how to do it manually but want to automate the process so others at work can do it also.

 

If some could whip up a lsp for me that would be amazing otherwise give me some direction as i have no idea how to start.

 

The list of events that needs to happen is:

 

select a mtext word in model space

copytolayer

G-HALO_TEXT

then select that copied mtext

TXPEXP

then select that exploded  mtext

REGION

then select that  mtext

UNION

then select that  mtext

EXPLODE

then select those shapes

EXPLODE

then select those lines

JOIN

then select those Polylines

give them a global width of 1 and send them behind the original text layer.

 

I think with time I might be able to work out a script that could do it to a whole layer but I want to be able to select the mtext to start.

 

 

And that should do it.

 

I am happy to take pointer and learn what I can but it's a fair bit to start with, all help greatly appreciated.

 

Cheerrs

 

Simon

 

0 Likes
Accepted solutions (2)
6,946 Views
45 Replies
Replies (45)
Message 2 of 46

roland.r71
Collaborator
Collaborator

What's txPexp?

 

or is it a typo for txTexp?

 

0 Likes
Message 3 of 46

simon.connellRBKGZ
Contributor
Contributor
It's a typo sorry txtexp
0 Likes
Message 4 of 46

roland.r71
Collaborator
Collaborator

I was afraid of that.

 

txtexp is a lisp file from Express Tools, not an autocad command.

& as it takes no arguments its hard, if not impossible, to make it work from a lisp.

 

The trick is to select the (copy) of the mtext & pass it to txtexp.

otherwise you will have to select it manually.

 

...and i'm guessing the rest of it is for making it look a bit better, as you can already apply a global width to the polylines created by txtexp.

(which actually uses a similar way i used long ago. Export it to WMF format & import the WMF data.)

 

 

 

0 Likes
Message 5 of 46

dbroad
Mentor
Mentor

The trick with txtexp is to preselect the object/s

(setq ss (ssget '((0 . "mtext"))))
(sssetfirst nil ss)
(c:txtexp)
Architect, Registered NC, VA, SC, & GA.
0 Likes
Message 6 of 46

roland.r71
Collaborator
Collaborator

Doesn't that select all mtext, instead of just the selected & copied mtext (entlast) ?

Not that it matters, I've bypassed txtexp anyway, by doing my own wmf ex- & import, with a tiny code snippet from txtexp.lsp

 

This does the trick, for me at least:

 

(setq ent1 (entsel "\nSelect mtext: "))

(setq VIEW     (acet-geom-view-points)
      TMPFIL   (strcat (getvar "tempprefix") "txtexp.wmf")
      PT1      (acet-geom-midpoint (car view) (cadr view))
      PT2      (list (car PT1) (cadadr VIEW))
)

(command "_.WMFOUT" TMPFIL ent1 ""
         "_.-layer" "_M" "G-HALO_TEXT" "")
(setq ss (acet-wmfin TMPFIL))
(command "_region" ss "")
(setq ss (ssget "X" (list '(0 . "REGION")(cons 8 "G-HALO_TEXT"))))
(command "_union" ss ""
         "_explode" "_last")
(setq ss (ssget "X" (list '(0 . "REGION")(cons 8 "G-HALO_TEXT"))))
(setvar "qaflags" 1)
(command "_explode" ss "")
(setq ss (ssget "X" (list '(0 . "LINE")(cons 8 "G-HALO_TEXT"))))
(command "_join" ss "")
(setq ss (ssget "X" (list '(0 . "LWPOLYLINE")(cons 8 "G-HALO_TEXT"))))
(setq i 0)
(while (< i (sslength ss))
   (setq ent2 (entget (ssname ss i)))
   (setq ent2 (subst (cons 43 1)(assoc 43 ent2) ent2))
   (entmod ent2)
   (setq i (1+ i))
)      
(command "_.draworder" ent1 "" "f")

Note:

 

There's no checking if you did select a mtext or anything.

If there are more regions and polylines on the layer G-HALO_TEXT, things might go south, etc.

0 Likes
Message 7 of 46

dbroad
Mentor
Mentor

@roland.r71  No, it allows for a filtered selection set.  Which mtext objects selected would be up to the drafter but it would not allow selecting lines.  

Architect, Registered NC, VA, SC, & GA.
0 Likes
Message 8 of 46

roland.r71
Collaborator
Collaborator

?

 

I think you misread the question...

0 Likes
Message 9 of 46

dbroad
Mentor
Mentor

Quote: "I think with time I might be able to work out a script that could do it to a whole layer but I want to be able to select the mtext to start."

 

Why don't you let the OP respond?  Is it really necessary to write a whole program where it appears the person a) wants to write it himself, and b) is having problem selecting mtext and using txtexp?

Architect, Registered NC, VA, SC, & GA.
0 Likes
Message 10 of 46

roland.r71
Collaborator
Collaborator

Smiley Very Happy

Why?

Because:

Quote: "If some could whip up a lsp for me that would be amazing"

& for the fun & education i get from it, myself.

...and i wouldn't call that bare bones stuff "a whole program". Just the absolute minimum required.

 

Anyways, the question/problem you now avoid was: how to pass the (entlast) to txtexp. Not to have the user select the mtext, again.

 

after a good look at it, i decided it's a totall overkill to use txtexp for this, besides the unwanted effects of it deleting the source & putting it all on layer 0.

 

So... let's have a coffee Smiley Happy

 

0 Likes
Message 11 of 46

simon.connellRBKGZ
Contributor
Contributor
Hi guys, thanks for all your help. I'm on my way into work now so will let you know how it goes. I would like to learn how to write these myself but looking at that code it would have taken me way too long for this instance.

To clarify the point about what I said with selecting a whole later... that is probably the least desirable option, manually selecting individual mtext/s is what I am actually after. I thought though that selecting a whole layer might be easier to work out how to do though and be a first step.


0 Likes
Message 12 of 46

roland.r71
Collaborator
Collaborator

@simon.connellRBKGZ wrote:
Hi guys, thanks for all your help. I'm on my way into work now so will let you know how it goes. I would like to learn how to write these myself but looking at that code it would have taken me way too long for this instance.

To clarify the point about what I said with selecting a whole later... that is probably the least desirable option, manually selecting individual mtext/s is what I am actually after. I thought though that selecting a whole layer might be easier to work out how to do though and be a first step.



Actually it is a bit tricky when it comes to layers & multiple mtext's to convert.

It might even be best to use a temporary layer for the conversion, because the current code will simply select all lwpolyline's on the layer, so if you 'convert' multiple mtext in a row, the effects will probably be a disaster 😉 [ edit: on second look, probably not. But it will keep resetting that global width Smiley Indifferent ]

 

Another way to do it would be a selection window, to prevent selecting more as desired. (i did leave the pt1 & pt2 intact with that in mind)

 

Offcourse it is only the least code needed i could think of.

It does need some dressing. (like a defun, some checks, a filter to allow only mtext to be selected, etc.etc)

0 Likes
Message 13 of 46

simon.connellRBKGZ
Contributor
Contributor

I tried the code that you wrote and it does this. Capture.PNG

 

I'm not sure why, I don't really understand lsp but the is what was at the command window.

 

Command: (LOAD "H:/Scripts/untested/Halo test.lsp")
Select mtext:
1 closed, degenerate or unsupported object rejected.
0 loops extracted.
0 Regions created.
Unknown command "GHD_TEXT". Press F1 for help.
*Invalid selection*
Expects a point or Window/Last/Crossing/BOX/ALL/Fence/WPolygon/CPolygon/Group/Add/Remove/Multiple/Previous/Undo/AUto/SIngle
Cannot invoke (command) from *error* without prior call to (*push-error-using-command*).
Converting (command) calls to (command-s) is recommended.

 

 

0 Likes
Message 14 of 46

roland.r71
Collaborator
Collaborator

I'm currently getting the same results, on 2014. Tested before on 2015 without problem.

I can't find why...

Keep getting a purge window when using acet-wmfin as well (even straight on commandline with no other code)

...and the wmf gets imported as ... text. instead of polylines.

 

I'm at a loss for the moment as to how and why.

Been a while since i used wmf.

0 Likes
Message 15 of 46

john.uhden
Mentor
Mentor

Might it be possible to pass arguments to the c:txtexp function by changing it into a command?

 

(vlax-add-cmd "TXTEXP" 'c:txtexp)

 

Then I think you can (command "txtexp" whatever)

 

BTW, lay off my buddy, Doug, lest I provide you an innocent looking lisp routine that sends 120V through your mouse wheel.  smileymad:

John F. Uhden

0 Likes
Message 16 of 46

john.uhden
Mentor
Mentor

Might it be possible to pass arguments to the c:txtexp function by changing it into a command?

 

(vlax-add-cmd "TXTEXP" 'c:txtexp)

 

Then I think you can (command "txtexp" whatever)

 

BTW, lay off my buddy, Doug, lest I provide you an innocent looking lisp routine that sends 120V through your mouse wheel.  Smiley Mad

John F. Uhden

0 Likes
Message 17 of 46

roland.r71
Collaborator
Collaborator

Just tried again on 2015 & besides qaflags being able to mess things up, it works.

Made some minor changes and made it a function:

 

(defun c:txthalo(/)
   (setq ent1 (entsel "\nSelect mtext: "))
;   (setq flag (getvar "qaflags"))
   (setq VIEW     (acet-geom-view-points)
         TMPFIL   (strcat (getvar "tempprefix") "txtexp.wmf")
         PT1      (acet-geom-midpoint (car view) (cadr view))
         PT2      (list (car PT1) (cadadr VIEW))
   )
   (setvar "qaflags" 0)
   (command "_.WMFOUT" TMPFIL ent1 "")
   (command "_.-layer" "_M" "G-HALO_TEMP" "")
   (setq ss (acet-wmfin TMPFIL))
   (command "_region" ss "")
   (setq ss (ssget "X" (list '(0 . "REGION")(cons 8 "G-HALO_TEMP"))))
   (command "_union" ss "")
   (command "_explode" "_last")
   (setq ss (ssget "X" (list '(0 . "REGION")(cons 8 "G-HALO_TEMP"))))
   (setvar "qaflags" 1)
   (command "_explode" ss "")
   (setq ss (ssget "X" (list '(0 . "LINE")(cons 8 "G-HALO_TEMP"))))
   (command "_join" ss "")
   (setvar "qaflags" 0)
   (setq ss (ssget "X" (list '(0 . "LWPOLYLINE")(cons 8 "G-HALO_TEMP"))))
   (setq i 0)
   (command "_.-layer" "_M" "G-HALO_TEXT" "")
   (while (< i (sslength ss))
      (setq ent2 (entget (ssname ss i)))
      (setq ent2 (subst (cons 43 1)(assoc 43 ent2) ent2))
      (setq ent2 (subst (cons 8 "G-HALO_TEXT")(assoc 8 ent2) ent2))
      (entmod ent2)
      (setq i (1+ i))
   )      
   (command "_.draworder" ent1 "" "f")
;   (setvar "qaflags" flag)
   (princ)
)

Halo_test.png

0 Likes
Message 18 of 46

simon.connellRBKGZ
Contributor
Contributor

Hi Roland, I get the same result as I did before and it messes up my qaflags, took me ages to work out what was wrong with AutoCAD after running it.

I'm using 2016 

0 Likes
Message 19 of 46

dbroad
Mentor
Mentor

Try the attached.  In general, it's not a good idea to use qaflags without a reset error handler.

 

Architect, Registered NC, VA, SC, & GA.
0 Likes
Message 20 of 46

roland.r71
Collaborator
Collaborator

I've enhanced the code a little bit more, like getting a much better alternative for qaflags...

& this works on my 2014 install too

 

txthalo.png

 

I finally found the cause and it isn't with the code. You need to set your textstyle's width to anything but 1, to have the wmfin import the text as polyline, not text.

 

(defun c:txthalo ( / ent ent1 ent2 wmf view pt1 pt2 edge ss i cmdecho)
   (setq cmdecho (getvar "CMDECHO")
         wmf     (strcat (getvar "tempprefix") "txthalo")
         ent     (entsel "\nSelect mtext: ")
         ent1    (entget (car ent))
         VIEW    (acet-geom-view-points)
         PT1     (acet-geom-midpoint (car view) (cadr view))
         PT2     (list (car PT1) (cadadr VIEW))
         edge    1 ; Global width for polylines
   )
   (setvar "CMDECHO" 0)
   (command "_.WMFOUT" (strcat wmf ".wmf") ent1 "")
   (command "_.-layer" "_M" "G-HALO_TEMP" "")
   (setq ss (acet-wmfin (strcat wmf ".wmf")))
   (command "_region" ss "")
   (setq ss (ssget "X" (list '(0 . "REGION")(cons 8 "G-HALO_TEMP"))))
   (command "_union" ss "")
   (command "_explode" "_last")
   (setq ss (ssget "X" (list '(0 . "REGION")(cons 8 "G-HALO_TEMP"))))
   (initcommandversion 2)
   (command "_explode" ss "")
   (setq ss (ssget "X" (list '(0 . "LINE")(cons 8 "G-HALO_TEMP"))))
   (initcommandversion 2)
   (command "_join" ss "")
   (setq ss (ssget "X" (list '(0 . "LWPOLYLINE")(cons 8 "G-HALO_TEMP"))))
   (setq i 0)
   (while (< i (sslength ss))
      (setq ent2 (entget (ssname ss i)))
      (setq ent2 (subst (cons 43 edge)(assoc 43 ent2) ent2))
      (setq ent2 (subst (cons 8 "G-HALO_TEXT")(assoc 8 ent2) ent2))
      (entmod ent2)
      (setq i (1+ i))
   )
   (command "_.draworder" ent "" "f")
   (setvar "CMDECHO" cmdecho)
)
0 Likes