;;;     TEXTMASK.LSP
;;;     Copyright (C) 1997 by Autodesk, Inc.
;;;
;;;     Created 3/12/97 by Dominic Panholzer
;;;
;;;     Permission to use, copy, modify, and distribute this software
;;;     for any purpose and without fee is hereby granted, provided
;;;     that the above copyright notice appears in all copies and 
;;;     that both that copyright notice and the limited warranty and 
;;;     restricted rights notice below appear in all supporting 
;;;     documentation.
;;;
;;;     AUTODESK PROVIDES THIS PROGRAM "AS IS" AND WITH ALL FAULTS.  
;;;     AUTODESK SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTY OF 
;;;     MERCHANTABILITY OR FITNESS FOR A PARTICULAR USE.  AUTODESK, INC. 
;;;     DOES NOT WARRANT THAT THE OPERATION OF THE PROGRAM WILL BE 
;;;     UNINTERRUPTED OR ERROR FREE.
;;;
;;;     Use, duplication, or disclosure by the U.S. Government is subject to 
;;;     restrictions set forth in FAR 52.227-19 (Commercial Computer 
;;;     Software - Restricted Rights) and DFAR 252.227-7013(c)(1)(ii) 
;;;     (Rights in Technical Data and Computer Software), as applicable. 
;;;
;;;  ----------------------------------------------------------------
;;;
;;;     TEXTMASK works in conjunction with WIPEOUT.ARX to hide all
;;;     entities behind the selected text or mtext. The text object
;;;     is then grouped together with the wipeout object such that
;;;     they move, copy, erase, etc. together. To update after editing
;;;     text, run TEXTMASK again and select the text item to be updated.
;;;     The the previous wipeout object will be erased and a new one
;;;     will be created.
;;;     
;;;
;;;
;;;  External Functions:
;;;
;;;     INIT_BONUS_ERROR  --> AC_BONUS.LSP   Intializes bonus error routine
;;;     RESTORE_OLD_ERROR --> AC_BONUS.LSP   Restores old error routine
;;;
(defun  &textyc( /  WIPOUT OSET TMP SS FLTR sca xh wid_pline  )
;;;(setq *error* nil)
 	;;(set_0)
 (setq wid_pline (getvar "plinewid"))
  (setvar "plinewid" 0)
  (setvar "cmdecho" 0) 
  (if (or (member "wipeout.arx" (arx)) (member "acwipeout.arx" (arx)))
    (setq WIPOUT T)
    (progn
     ;;; (hy_loadsysarx "wipeout")
      ;;(arxload (strcat (hy_getinstalldir) "wipeout"))
      (if (= (substr (getvar "ACADVER") 1 2) "15")
        (arxload (strcat (hy_getinstalldir) "wipeout"))
        (arxload "acwipeout")
      )
      (setq WIPOUT T)
    )
  )
  (if WIPOUT                                           ; if wipeout.arx is loaded
    (progn
    	;;;;(setq sca (dbl))
    	(setq sca (dl_getdrawingfactor))
    	(if (= &hy_gps_offset_wzpb nil)
    	  (setq &hy_gps_offset_wzpb 0.5)
      )
      (initget 6)
      (setq OSET (getreal (strcat "\n 输入文字外每侧屏蔽长度<" (rtos &hy_gps_offset_wzpb 2 2) "mm>:")) )
      (if (= OSET nil)
        (setq OSET &hy_gps_offset_wzpb)
        (setq &hy_gps_offset_wzpb OSET)
      )

; ---------------------- get text to mask ------------------------

      (setq FLTR '((-4 . "<or") (0 . "TEXT") (0 . "MTEXT") (-4 . "or>")) )
      (setq xh t)
      (while xh
        (prompt "\n选择要屏蔽的文字:")
        (setq SS (ssget FLTR))                       ; Select text and mtext
        (if (= SS nil)
          (setq xh nil)
          (progn
            ;;;;(sa_var)
            (hy_sv)
            (&textyc2 ss (* sca OSET))
            ;;;(re_var)
            (hy_rv)
          );progn
        );if SS
      )
    );progn
  );if wipeout
  (setvar "plinewid" wid_pline)
  ;;;(set_1)
  ;;;(hy_set1)
  (setvar "cmdecho" 1) 
  (princ)
)    ;end of defun
;
;
(defun &textyc2(ss dist_offset_wid /  
       WIPOUT CNT GLST TMP ENT PNTLST ZM LOCKED GDICT OSET  ss_text ent_name
       GNAM GRP MLST TXT TOS TXTLAY TXLCK wbg TmpEnt
               )

				  (if (or (member "wipeout.arx" (arx)) (member "acwipeout.arx" (arx)));;(member "wipeout.arx" (arx))
				    (setq WIPOUT T)
				    (progn
				     ;;;; (#gpas "wipeout")
				     (if (= (substr (getvar "ACADVER") 1 2) "15")
				      (arxload (strcat (hy_getinstalldir) "wipeout"))
				      (arxload "acwipeout")
				     )
				      (setq WIPOUT T)
				    )
				  )
				  (setq CNT   0                                    ; Initilize the counter.
				        GLST  (mask_grplst)                        ; Get all the groups in drawing
				        GDICT (if GLST
				                  (dictsearch (namedobjdict) "ACAD_GROUP")
				              )
				  )
          (command "_.wipeout" "F" "OFF")        ; Turn off wipeout frames
          (if (b_layer_locked (getvar "clayer"))       ; if current layer is locked
            (progn
              (command "_.layer" "unl" (getvar "clayer") "")  ; unlock it
              (setq LOCKED T)
            )
          )

; ----------------- Step through each and mask -------------------
          (setq ss_text (ssadd)) 
          (cond
           ((= (type ss) 'ENAME)
            (ssadd ss ss_text)
           )
           ((= (type ss) 'PICKSET)
            (setq ss_text ss)
           )
           ((= (type ss) 'LIST)
            (foreach ent_name ss
                (ssadd ent_name ss_text)
            )
           )
           (t
            (setq ss_text nil)
           )
          )
          (setq ss ss_text)
          (While (setq ENT (ssname SS CNT))            ; step through each object in set
            (setq wbg (cdr (assoc 40 (entget ent))) )
            (setq oset (/ dist_offset_wid wbg))
            (and
              GLST                                     ; if groups are present in the drawing
              (setq GNAM (mask_getgname ENT GLST))          ; and the text item is in one or more
              (foreach GRP GNAM                        ; step through those groups
                (and
                  (setq MLST (mask_getgmem GRP))            ; Get the members of the group.
                  (= (length MLST) 2)                  ; If the group has two members
                  (if (eq (car MLST) ENT)              ; get the member which is not
                    (setq MLST (cadr MLST))            ; the text.
                    (setq MLST (car MLST))
                  )
                  (= "WIPEOUT" (cdr (assoc 0 (entget MLST))))   ; If it is a wipeout entity
                  (dictremove (cdr (assoc -1 GDICT)) (cdr GRP)) ; explode the group
                  (entdel MLST)                                 ; and delete the wipeout
                )
              )
            )
                  
            (setq TXT   (entget ENT (list "*"))
                  TXTYP (cdr (assoc 0 TXT))            ; Text or Mtext
            )

            (if (= TXTYP "TEXT")
              (command "_.ucs" "object" ENT) ; set UCS to object
               (mask_ucs_2_mtext ENT)
            )

            (setq TXTLAY (cdr (assoc 8 TXT))           ; Get the layer of the text
                  TOS    (* (cdr (assoc 40 TXT)) OSET) ; Set the offset for the text
            )

            (setq TmpEnt (mask_drawbox TXT TOS))                          ; Draw pline around text
           
               	

            (command "_.ucs" "previous")              ; reset the ucs

            (if (= TXTYP "MTEXT")
              (command "_.ucs" "previous")         ; second previous needed for mask_ucs_2_mtext
            )
            
             (if TmpEnt 
               (progn
 
 	    (if (= (substr (getvar "ACADVER") 1 2) "15")
               (command "_.wipeout" "N" TmpEnt "Y")  ; create wipeout entity
               (command "_.wipeout" "P" TmpEnt "Y")  ; create wipeout entity
            )  
            (setq WIPOUT (entlast))

            (command "_.change" WIPOUT "" "Prop" "Layer" TXTLAY "") ; and set its layer

            (if (setq TXLCK (b_layer_locked TXTLAY))   ; If text layer is locked
              (command "_.layer" "unl" TXTLAY "")     ; unlock it
            )

            (entmake TXT)                              ; recreate text
            (setq TXT (entlast))                       ; such that it's on top

            (mask_makgrp (list WIPOUT TXT) "In use by TEXTMASK") ; make the text and wipeout a group
  
        
            (entdel ENT)                               ; delete original text

            (if TXLCK (command "_.layer" "lock" TXTLAY "")) : relock if needed
        );;;progn
)

            (setq CNT (1+ CNT))                        ; get the next text item
          ); while

          (if LOCKED (command "_.layer" "lock" (getvar "clayer") "")) : relock if needed

          (command "ucs" "world")

)    ;end of defun
;
;
  (defun mask_grplst (/ GRP MSTR ITM NAM ENT GLST)

    (setq GRP  (dictsearch (namedobjdict) "ACAD_GROUP"))
    (while (setq ITM (car GRP))       ; While edata item is available
      (if (= (car ITM) 3)             ; if the item is a group name
        (setq NAM (cdr ITM)           ; get the name
              GRP (cdr GRP)           ; shorten the edata
              ITM (car GRP)           ; get the next item
              ENT (cdr ITM)           ; which is the ename
              GRP (cdr GRP)           ; shorten the edata
              GLST                    ; store the ename and name
                  (if GLST
                    (append GLST (list (cons ENT NAM)))
                    (list (cons ENT NAM))
                  )
        )
        (setq GRP (cdr GRP))          ; else shorten the edata
      )
    )
    GLST                              ; return the list
  )

; ------------------- GET GROUP NAME FUNCTION --------------------
;   This function returns a list of all the group names in GLST
;   where ENT is a member. The list has the same form as GLST
; ----------------------------------------------------------------

  (defun mask_getgname (ENT GLST / MSTR GRP GDATA ITM NAM NLST)
    (if (and GLST (listp GLST))
      (progn
        (foreach GRP GLST
          (setq GDATA (entget (car GRP)))
          (foreach ITM GDATA                   ; step through the edata
            (if (and
                  (= (car ITM) 340)            ; if the item is a entity name
                  (eq (setq NAM (cdr ITM)) ENT) ; and the ename being looked for
                )
              (setq NLST                       ; store the ename and name
                      (if NLST
                        (append NLST (list (cons (car GRP) (cdr GRP))))
                        (list (cons (car GRP) (cdr GRP)))
                      )
              )
            )
          )
        )
      )
    )
    NLST
  )

; --------------------- GROUP MEMBER FUNCTION ----------------------
;   This function returns a list of all the entity names of the
;   members of group GNAM. GNAM is a list (<ename1> . <name1>).
; ----------------------------------------------------------------

  (defun mask_getgmem (GNAM / GRP GDATA ITM NLST)

    (if GNAM
      (progn
        (setq GDATA (entget (car GNAM)))
        (foreach ITM GDATA                    ; step through the edata
          (if (= (car ITM) 340)               ; if the item is a entity name
            (setq NLST  (cons (cdr ITM) NLST) ; store the ename
            )
          )
        )
      )
    )
    NLST
  )

; ---------------------- MAKGROUP FUNCTION -----------------------
;   This will create a selectable unnamed group using the entities 
;   in the list LST, and give it the description DESC. 
; ----------------------------------------------------------------

  (defun mask_makgrp (LST DESC / NAM EN LST GDICT GDATA flag)
  
   (setq GDICT (dictsearch (namedobjdict) "ACAD_GROUP"))
   (while (null flag)
     (setq NAM (strcat "ZZ_BNS" (substr (rtos (getvar "CDATE") 2 8) 10)))
     (setq GDATA (dictsearch (cdr (assoc -1 GDICT)) NAM))
     (if (null GDATA) 
         (setq flag T)
     )
   )
   
    (command "_.-group" "create" NAM DESC)
    (foreach EN LST (command EN))
    (command "")

    (setq GDATA (dictsearch (cdr (assoc -1 GDICT)) NAM)
          GDATA (subst (cons 70 1) (assoc 70 GDATA) GDATA)
    )
    
    (dictrename (cdr (assoc -1 GDICT)) NAM "*A")
    (entmod GDATA)
  )

; ------------------- SET MTEXT UCS FUNCTION ---------------------
;   AutoCAD does not accept mtext as a valid object for setting
;   the ucs. This function will set the current ucs to the 
;   mtext entity name ENT.
; ----------------------------------------------------------------

  (defun mask_ucs_2_mtext (ENT / PT)

    (setq PT (cdr (assoc 210 (entget ENT)))
          PT (strcat "*"
               (rtos (car PT) 2 8) ","
               (rtos (cadr PT) 2 8) ","
               (rtos (caddr PT) 2 8)
             );strcat
    );setq
    (command "_.ucs" "za" "*0.0,0.0,0.0" PT)
    (command "_.ucs" "or" (trans (cdr (assoc 10 (entget ENT))) 0 1))
  )


; --------------------- mask_mtextbox FUNCTION ------------------------
;   This function returns a list of four points describing the 
;   bounding box of the mtext (MTXT).
; ----------------------------------------------------------------

  (defun mask_mtextbox (MTXT / WDTH HGHT INS JUST ANG P1 P2 P3 P4)
    (if (and (listp MTXT) (= "MTEXT" (cdr (assoc 0 MTXT))))
      (progn
        (setq WDTH (cdr (assoc 42 MTXT))
              HGHT (cdr (assoc 43 MTXT))
              INS  (trans (cdr (assoc 10 MTXT)) 0 1)
              JUST (cdr (assoc 71 MTXT))
              ANG  (cdr (assoc 50 MTXT))
        )
        (cond
          ((= JUST 1)
            (setq P1 (polar INS (- ANG (* Pi 0.5)) HGHT) ; lower-left
                  P2 (polar P1 ANG WDTH)                 ; lower-right
                  P3 (polar INS ANG WDTH)                ; upper-right
                  p4 INS                                 ; upper-left
            )
          )
          ((= JUST 2)
            (setq P3 (polar INS ANG (/ WDTH 2))
                  P4 (polar INS (+ ANG Pi) (/ WDTH 2))
                  P1 (polar P4 (- ANG (* Pi 0.5)) HGHT)
                  P2 (polar P1 ANG WDTH)
            )
          )
          ((= JUST 3)
            (setq P3 INS
                  P4 (polar INS (+ ANG Pi) WDTH)
                  P1 (polar P4 (- ANG (* Pi 0.5)) HGHT)
                  P2 (polar P1 ANG WDTH)
            )
          )
          ((= JUST 4)
            (setq P4 (polar INS (+ ANG (* Pi 0.5)) (/ HGHT 2))
                  P3 (polar P4 ANG WDTH)
                  P1 (polar P4 (- ANG (* Pi 0.5)) HGHT)
                  P2 (polar P1 ANG WDTH)
            )
          )
          ((= JUST 5)
            (setq P4 (polar INS (- ANG Pi) (/ WDTH 2))
                  P4 (polar P4 (+ ANG (* Pi 0.5)) (/ HGHT 2))
                  P3 (polar P4 ANG WDTH)
                  P1 (polar P4 (- ANG (* Pi 0.5)) HGHT)
                  P2 (polar P1 ANG WDTH)
            )
          )
          ((= JUST 6)
            (setq P3 (polar INS (+ ANG (* Pi 0.5)) (/ HGHT 2))
                  P4 (polar P3 (+ ANG Pi) WDTH)
                  P1 (polar P4 (- ANG (* Pi 0.5)) HGHT)
                  P2 (polar P1 ANG WDTH)
            )
          )
          ((= JUST 7)
            (setq P1 INS
                  P2 (polar P1 ANG WDTH)
                  P3 (polar P2 (+ ANG (* Pi 0.5)) HGHT)
                  P4 (polar P1 (+ ANG (* Pi 0.5)) HGHT)
            )
          )
          ((= JUST 8)
            (setq P1 (polar INS (+ ANG Pi) (/ WDTH 2))
                  P2 (polar P1 ANG WDTH)
                  P3 (polar P2 (+ ANG (* Pi 0.5)) HGHT)
                  P4 (polar P1 (+ ANG (* Pi 0.5)) HGHT)
            )
          )
          ((= JUST 9)
            (setq P2 INS
                  P1 (polar INS (+ ANG Pi) WDTH)
                  P3 (polar P2 (+ ANG (* Pi 0.5)) HGHT)
                  P4 (polar P1 (+ ANG (* Pi 0.5)) HGHT)
            )
          )
        )
      )
      (prompt "\nEntity Not Mtext!")
    )
    (list P1 P2 P3 P4)
  )


; ---------------------- mask_drawbox FUNCTION ------------------------
;   Function to draw the pline bounding box with the specified
;   offset (DIST) around text or mtext (TXT).    
; ----------------------------------------------------------------


  (defun mask_drawbox (TXT DIST / TBX PT ORGBND TmpEnt)

    (if (= TXTYP "TEXT")
      (progn
        (setq TBX (textbox TXT))    ; normal text
        (command "_.pline" (car TBX) (list (caadr TBX)(cadar TBX))
                 (cadr TBX) (list (caar TBX)(cadadr TBX)) "_close"
        )
      )
      (progn
        (setq TBX (mask_mtextbox TXT))   ; Mtext
        (command "_.pline")
        (foreach PT TBX (command PT))
        (command "_c")
      )
    )

    (setq ORGBND (entlast))

    (command "_.offset" DIST (entlast))
    (if (= TXTYP "TEXT")
      (command "-1,-1" "")
      (command (polar 
                 (cdr (assoc 10 TXT))
                 (cdr (assoc 50 TXT))
                 (* 2 (cdr (assoc 42 TXT)))
               )
               ""
      ) 
    )
    (setq TmpEnt (entlast))

    (if (equal ORGBND TmpEnt)
        (progn
           (entdel ORGBND)
           (setq TmpEnt nil)
        )
        (entdel ORGBND)
    )
    TmpEnt
  );end defun

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;Takes a layer name and returns 
;True if the layer is locked, and nil if unlocked.
;
(defun b_layer_locked ( la / na e1)
 (setq na (tblobjname "layer" la)
       e1 (entget na)
 );setq
 (equal 4 
        (logand 4 (cdr (assoc 70 e1)))
 );equal
);defun b_layer_locked
;
;;;文本屏蔽撤消
(defun jh_txt_mask_del( / ss int_var lay_var ns ns1 ent ss_del wb ent2 biao len_text hei_text 
       sca  )
  ;;;(set_0)
  (hy_set0)
  (setq int_var (getvar "pickstyle") sca (dl_getdrawingfactor))
  (setvar "pickstyle" 0)
  (prompt "\n 选择要去屏蔽的文字:")
	(setq ss (ssget '((0 . "TEXT"))))
	(if	ss (progn
	  (command "wipeout" "f" "on")
	  (setq ns (sslength ss) ns1 0)
	  (repeat ns
	   (setq ent (ssname ss ns1) wb (entget ent) p01 (cdr (assoc 10 wb)) ang (cdr (assoc 50 wb)) )
	   (setq biao (textbox wb) len_text (+ (- (caadr biao) (caar biao)) sca)
	         hei_text (+ (- (cadadr biao) (cadar biao)) sca)
	   )
	   (&view_ptb (list p01))
	   (setq ss_del (ssget "CP" (list p01 (setq p01 (polar p01 ang len_text))
	                                  (setq p01 (polar p01 (+ ang (* pi 0.5)) hei_text))
	                                  (polar p01 (+ pi ang) len_text)
	                            ) '((0 . "WIPEOUT"))
	                )
	   )
	   (if ss_del (command "erase" ss_del ""))            
	   (setq ns1 (+ ns1 1))
	  )
	  (command "wipeout" "f" "off")
	))
	(setvar "pickstyle" int_var)
	(princ "\n 文本屏蔽已去除!")
	(hy_set1)
	(princ)
)
;
(princ)
