Chuyển đến nội dung
Diễn đàn CADViet
Đăng nhập để thực hiện theo  
Nộ Thiên

Có vấn đề với việc tạo TextStyle bằng lisp

Các bài được khuyến nghị

Mình có 1 đọan lisp tạo textstyle như sau:

 

;;;\\\\\\\\\-----Kiem tra TextStyle, neu chua co thi tao moi -----\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\

(defun chStyle (Tenstyle tenfont)

(if (null (setq item (tblsearch "style" tenstyle)))

(command "-style" tenstyle tenfont "0" "1" "0" "n" "n")

)

)

 

Đọan code trên nó chạy đúng với đa số các lọai front. Nhưng với 1 số font thì bị lỗi.

Sau khi tìm hiểu thì phát hiện ra nguyênnhân như sau.

 

Có hiệu ứng vertical

textstyle1.jpg

 

Kg có hiệu ứng Vertical (đọan code trên chỉ đúng với lọai này)

textstyle2.jpg

 

Như vậy vấn đề đặt ra là làm thế nào để đọan code trên mang tính tổng quát (đúng với mọi font)???

Chia sẻ bài đăng này


Liên kết tới bài đăng
Chia sẻ trên các trang web khác

Không thấy ai trả lời, crazy tôi xin ké một tí.

 

Để giải quyết triệt để vấn đề này, chúng ta sẽ cố tạo mới một textstyle bằng hàm entmake. Khó khăn là làm sao để biết được hàm entmake cần những dữ liệu gì. Ta sẽ dùng hàm entget để lấy và xem dữ liệu của text style. Nhưng làm sao để lấy được ename của đối tượng textstyle để sử dụng hàm entget. Ta dùng hàm tblobjname để tìm ename của một text style có sẵn.

 

Khi ta dùng lệnh (entget (tblobjname "style" "standard")) để xem dữ liệu chứa text style, sẽ có kết quả:

((-1 . <Entity name: 7ef8fc88>) (0 . "STYLE") (330 . <Entity name: 7ef8fc18>)

(5 . "11") (100 . "AcDbSymbolTableRecord") (100 . "AcDbTextStyleTableRecord")

(2 . "Standard") (70 . 0) (40 . 0.0) (41 . 1.0) (50 . 0.0) (71 . 0) (42 . 0.2)

(3 . "txt") (4 . ""))

Vậy là trong mục 2 chứa tên style, mục 3 chứa fontname.

 

Công việc của chúng ta bây giờ rất đơn giản, dùng hàm entmake để tạo đối tượng có dữ liệu như ở trên nhưng mục 2 là tên style, mục 3 là fontstyle. Đoạn mã đó như sau:

(setq

DuLieu (entget (tblobjname "style" "standard"))

DuLieu (subst (cons 2 Tenstyle) (assoc 2 DuLieu) DuLieu)

DuLieu (subst (cons 3 tenfont) (assoc 3 DuLieu) DuLieu)

)

(entmake DuLieu)

 

Kết hợp với đoạn mã của Nộ Thiên, ta có đoạn mã như sau:

(defun chStyle (Tenstyle tenfont)

(if (null (setq item (tblsearch "style" tenstyle)))

(progn

(setq DuLieu (entget (tblobjname "style" "standard"))

DuLieu (subst (cons 2 Tenstyle) (assoc 2 DuLieu) DuLieu)

DuLieu (subst (cons 3 tenfont) (assoc 3 DuLieu) DuLieu))

(entmake DuLieu)

)

)

)

Chúc vui vẻ.

  • Vote tăng 1

Chia sẻ bài đăng này


Liên kết tới bài đăng
Chia sẻ trên các trang web khác
Để giải quyết triệt để vấn đề này, chúng ta sẽ cố tạo mới một textstyle bằng hàm entmake. Khó khăn là làm sao để biết được hàm entmake cần những dữ liệu gì. Ta sẽ dùng hàm entget để lấy và xem dữ liệu của text style. Nhưng làm sao để lấy được ename của đối tượng textstyle để sử dụng hàm entget. Ta dùng hàm tblobjname để tìm ename của một text style có sẵn...

Hoàn toàn đồng ý với bạn, các vấn đề tương tự như trên dùng entmake là hợp lý nhất. Tuy nhiên, không cần phải "dựa hơi" style có sẵn, có vẻ không "chính quy" lắm. Mình ví dụ, nếu ai đó đổi tên Standard thành MyStandard chẳng hạn thì hàm chStyle của bạn không tạo được style?

Bạn tham khảo đoạn sau:

;;;--------------------------------------------------------------------------
(defun emk_style (MyStyle MyFont MyFlag)
(entmake (list
   (cons 0 "STYLE")
   (cons 100 "AcDbSymbolTableRecord")
   (cons 100 "AcDbTextStyleTableRecord")
   (cons 2 MyStyle)
   (cons 3  MyFont)
   (cons 70 MyFlag)
))
)
;;;--------------------------------------------------------------------------
(defun C:VD()
(emk_style "MyStyle1" "txt" 0)
(emk_style "MyStyle2" "txt" 4)
)
;;;--------------------------------------------------------------------------

Chạy VD sẽ tạo 2 style: MyStyle1 bỉnh thường và MyStyle2 có hiệu ứng Vertical như ý bạn Nộ Thiên.

Mình đã thử emk_style với nhiều tổ hợp mã DXF khác nhau. Các mã 0, 100, 100, 2, 3, 70 như trên là bắt buộc, nghĩa là tối thiểu cần phải có để tạo thành style. Bạn lưu ý: các code 100 là bắt buộc trong đa số trường hợp để tạo các đối tượng Symbol Table bằng entmake.

Ngoài các code tối thiểu trên, có thể bổ sung các code khác theo ý đồ và nhu cầu sử dụng. Bạn có thể tham khảo DXF Reference trong Help để biết cụ thể hơn.

Ngoài ra, theo mình, không nên đưa các biểu thức điều kiện như (if (null (setq item (tblsearch "style" tenstyle)))... vào các function mang tính public như cái chúng ta đang xây dựng. Các điều kiện như vậy nên đặt trong chương trình chính khi áp dụng, dễ xử lý tình huống một cách triệt để hơn.

  • Vote tăng 1

Chia sẻ bài đăng này


Liên kết tới bài đăng
Chia sẻ trên các trang web khác
Hoàn toàn đồng ý với bạn, các vấn đề tương tự như trên dùng entmake là hợp lý nhất. Tuy nhiên, không cần phải "dựa hơi" style có sẵn, có vẻ không "chính quy" lắm. Mình ví dụ, nếu ai đó đổi tên Standard thành MyStandard chẳng hạn thì hàm chStyle của bạn không tạo được style?

Bạn tham khảo đoạn sau:

;;;--------------------------------------------------------------------------
(defun emk_style (MyStyle MyFont MyFlag)
(entmake (list
   (cons 0 "STYLE")
   (cons 100 "AcDbSymbolTableRecord")
   (cons 100 "AcDbTextStyleTableRecord")
   (cons 2 MyStyle)
   (cons 3  MyFont)
   (cons 70 MyFlag)
))
)
;;;--------------------------------------------------------------------------
(defun C:VD()
(emk_style "MyStyle1" "txt" 0)
(emk_style "MyStyle2" "txt" 4)
)
;;;--------------------------------------------------------------------------

Chạy VD sẽ tạo 2 style: MyStyle1 bỉnh thường và MyStyle2 có hiệu ứng Vertical như ý bạn Nộ Thiên.

Mình đã thử emk_style với nhiều tổ hợp mã DXF khác nhau. Các mã 0, 100, 100, 2, 3, 70 như trên là bắt buộc, nghĩa là tối thiểu cần phải có để tạo thành style. Bạn lưu ý: các code 100 là bắt buộc trong đa số trường hợp để tạo các đối tượng Symbol Table bằng entmake.

Ngoài các code tối thiểu trên, có thể bổ sung các code khác theo ý đồ và nhu cầu sử dụng. Bạn có thể tham khảo DXF Reference trong Help để biết cụ thể hơn.

Ngoài ra, theo mình, không nên đưa các biểu thức điều kiện như (if (null (setq item (tblsearch "style" tenstyle)))... vào các function mang tính public như cái chúng ta đang xây dựng. Các điều kiện như vậy nên đặt trong chương trình chính khi áp dụng, dễ xử lý tình huống một cách triệt để hơn.

Đúng là mình bị "ì" rồi. Quên mất là còn khả năng tạo textstyle bằng entmake. Thank so much.

 

không nên đưa các biểu thức điều kiện như (if (null (setq item (tblsearch "style" tenstyle)))...

Còn cái này cũng do "ì" mà ra bởi vì nguồn gốc của nó do hàm public (chlayer) mà ra. Chứ nếu viết nó độc lập thì mình đã đặt tên hàm là (creatstyle) rồi chứ kg phải (chstyle).

 

(emk_style "MyStyle1" "VNI-Helve-Condense" 0)

Cái dòng code trên có gì đó kg ổn, kg biết SSG có nhận thấy kg vì:

Nếu tetstyle bằng lệnh của CAD thì kg bao giờ có thể tick vào "Vertical" đc.

Nhưng với dòng code trên thì có thể. Kg biết có rắc rối chi về sau kg. Cái này để test sau vậy.

Một lần nữa gửi lời cảm ơn đến 2 bạn: Crazylisp và Ssg

Chia sẻ bài đăng này


Liên kết tới bài đăng
Chia sẻ trên các trang web khác

xin hỏi các bác còn 1 vấn đề nhỏ là Fontstyle thì thiết lập thế nào?Em tạo 1 style "CHU TO" có fontstyle = bold bằng style dialog nhưng không biết là cái fontstyle nó chứa ở đâu khi sử dụng hàm enget:

(entget (tblobjname "style" "CHU TO"))

((-1 . <Entity name: 7ef73058>) (0 . "STYLE") (330 . <Entity name: 7ef71d18>)

(5 . "83") (100 . "AcDbSymbolTableRecord") (100 . "AcDbTextStyleTableRecord")

(2 . "CHU TO") (70 . 0) (40 . 0.0) (41 . 1.0) (50 . 0.0) (71 . 0) (42 . 450.0)

(3 . "VHARIALB.ttf") (4 . ""))

so sánh với cái standard thì chỉ khác 2,3 và 42

Chia sẻ bài đăng này


Liên kết tới bài đăng
Chia sẻ trên các trang web khác
xin hỏi các bác còn 1 vấn đề nhỏ là Fontstyle thì thiết lập thế nào?Em tạo 1 style "CHU TO" có fontstyle = bold bằng style dialog nhưng không biết là cái fontstyle nó chứa ở đâu khi sử dụng hàm enget:

(entget (tblobjname "style" "CHU TO"))

((-1 . <Entity name: 7ef73058>) (0 . "STYLE") (330 . <Entity name: 7ef71d18>)

(5 . "83") (100 . "AcDbSymbolTableRecord") (100 . "AcDbTextStyleTableRecord")

(2 . "CHU TO") (70 . 0) (40 . 0.0) (41 . 1.0) (50 . 0.0) (71 . 0) (42 . 450.0)

(3 . "VHARIALB.ttf") (4 . ""))

so sánh với cái standard thì chỉ khác 2,3 và 42

Mính vừa test thử và thấy điểm đặc biệt là ở đây:

Cùng một style CHUTO, với font .VNARIAL.ttf

Fontstyle BOLD ITALIC cho kết quả :

((-1 . <Entity name: 7ef91048>) (0 . "STYLE") (330 . <Entity name: 7ef8fc18>)

(5 . "B9") (100 . "AcDbSymbolTableRecord") (100 . "AcDbTextStyleTableRecord")

(2 . "Chuto") (70 . 0) (40 . 0.0) (41 . 1.0) (50 . 0.0) (71 . 0) (42 . 0.2) (3

. "VNARIABI.ttf") (4 . ""))

 

Fontstyle ITALIC cho kết quả :

((-1 . <Entity name: 7ef91048>) (0 . "STYLE") (330 . <Entity name: 7ef8fc18>)

(5 . "B9") (100 . "AcDbSymbolTableRecord") (100 . "AcDbTextStyleTableRecord")

(2 . "Chuto") (70 . 0) (40 . 0.0) (41 . 1.0) (50 . 0.0) (71 . 0) (42 . 0.2) (3

. "VNARIALI.ttf") (4 . ""))

 

 

Fontstyle regular cho kết quả :

((-1 . <Entity name: 7ef91048>) (0 . "STYLE") (330 . <Entity name: 7ef8fc18>)

(5 . "B9") (100 . "AcDbSymbolTableRecord") (100 . "AcDbTextStyleTableRecord")

(2 . "Chuto") (70 . 0) (40 . 0.0) (41 . 1.0) (50 . 0.0) (71 . 0) (42 . 0.2) (3

. "VNARIAL.ttf") (4 . ""))

 

Vậy là có thể kết luận được cách đặt fontstyle chính là ở tên của font file (mỗi font style tương ứng với một file font).

Còn tên riêng của các file (tên font) đó như thế nào thì ...chỉ có test thử và lưu lại thôi (vì tên font file trong Win ko giống như vậy)

Chia sẻ bài đăng này


Liên kết tới bài đăng
Chia sẻ trên các trang web khác

Các bác cho em hỏi :

Em có test ở 2 loại font :  "Arial CE"  và "Arial CYR".image.png

Em kiểm tra Entget của 2 loại Font Style này: 

 

(entget (tblobjname "style" "5_Arial CE"))
((-1 . <Entity name: 7ff40a105c90>) (0 . "STYLE") (330 . <Entity name: 7ff40a103830>) (5 . "1C1") (100 . "AcDbSymbolTableRecord") (100 . "AcDbTextStyleTableRecord")

(2 . "5_Arial CE")   (70 . 0) (40 . 0.0) (41 . 1.0)  (50 . 0.0) (71 . 0) (42 . 0.2) (3 . "arial.ttf") (4 . ""))

 

(entget (tblobjname "style" "6_Arial CYR"))
((-1 . <Entity name: 7ff40a105cb0>) (0 . "STYLE") (330 . <Entity name: 7ff40a103830>) (5 . "1C3") (100 . "AcDbSymbolTableRecord") (100 . "AcDbTextStyleTableRecord")

(2 . "6_Arial CYR") (70 . 0) (40 . 0.0) (41 . 1.0)  (50 . 0.0) (71 . 0) (42 . 0.2) (3 . "arial.ttf") (4 . ""))

 

----> Tức là Entget của 2 font này tương đồng nhau:   ----> Vậy các bác cho em hỏi : Nếu em muốn tạo font "Arial CE", "Arial CYR"  thì em phải code entmake kiểu gì ạ ??

Chia sẻ bài đăng này


Liên kết tới bài đăng
Chia sẻ trên các trang web khác
58 phút trước, NTHAHT đã nói:

Bài này: 

 

Em tạo bài chủ đề trên đấy bác ơi @@.  Trước là em lấy dc tên font thôi, giờ code entmake ko ra thì mới lại hỏi tiếp :))))

Chia sẻ bài đăng này


Liên kết tới bài đăng
Chia sẻ trên các trang web khác
16 phút trước, Danh Cong đã nói:

Em tạo bài chủ đề trên đấy bác ơi @@.  Trước là em lấy dc tên font thôi, giờ code entmake ko ra thì mới lại hỏi tiếp :))))

Bác thêm cái đuôi (-3 (“ÁCAD”) ...) mà cũng không ra hả?

  • Vote tăng 1

Chia sẻ bài đăng này


Liên kết tới bài đăng
Chia sẻ trên các trang web khác
2 giờ trước, Danh Cong đã nói:

Em tạo bài chủ đề trên đấy bác ơi @@.  Trước là em lấy dc tên font thôi, giờ code entmake ko ra thì mới lại hỏi tiếp :))))

Thử:

(entget (tblobjname "STYLE" "5_Arial CE") '("*"))

hoặc:

(entget (tblobjname "STYLE" "5_Arial CE") '("ACAD"))

Của mình =>

((-1 . <Entity name: 25c49cb1d00>) (0 . "STYLE") (330 . <Entity name: 25c49cad830>) (5 . "208") (100 . "AcDbSymbolTableRecord") (100 . "AcDbTextStyleTableRecord") (2 . "5_Arial CE") (70 . 0) (40 . 0.0) (41 . 1.0) (50 . 0.0) (71 . 0) (42 . 0.2) (3 . "arial.ttf") (4 . "") (-3 ("ACAD" (1000 . "Arial CE") (1071 . 60962))))

  • Vote tăng 1

Chia sẻ bài đăng này


Liên kết tới bài đăng
Chia sẻ trên các trang web khác

Tham khảo.


;----- Tao TextStyle by Entmake, by HA. 27/11/2019
(defun MFont(FontS FontF FontN Int)
 (entmake (list '(0 . "STYLE") '(100 . "AcDbSymbolTableRecord") '(100 . "AcDbTextStyleTableRecord")
   (cons 2 FontS) '(70 . 0) '(40 . 0.0) '(41 . 1.0) '(50 . 0.0) '(71 . 0) '(42 . 0.2) (cons 3 FontF) '(4 . "")
   (cons -3 (list (list "ACAD" (cons 1000 FontN) (cons 1071 Int)))))))
; VD1: (MFont "Style1" "arial.ttf" "Arial" 34)
; VD2: (MFont "Style2" "arial.ttf" "Arial CE" 60962)
; VD3: (MFont "Style3" "arial.ttf" "Arial CYR" 52258)
; Cach tim gia tri Int: tao 1 style co ten la "MyStyle", dung dong lenh duoi day de lay gia tri Int.
; (setq Int (cdaddr (cadr (assoc -3 (entget (tblobjname "Style" "MyStyle") '("ACAD"))))))

  • Like 1

Chia sẻ bài đăng này


Liên kết tới bài đăng
Chia sẻ trên các trang web khác

Tạo một tài khoản hoặc đăng nhập để nhận xét

Bạn cần phải là một thành viên để lại một bình luận

Tạo tài khoản

Đăng ký một tài khoản mới trong cộng đồng của chúng tôi. Điều đó dễ mà.

Đăng ký tài khoản mới

Đăng nhập

Bạn có sẵn sàng để tạo một tài khoản ? Đăng nhập tại đây.

Đăng nhập ngay
Đăng nhập để thực hiện theo  

×