Тема: Отображение руского текста (mtext) в AutoCad2002

Народ. Така проблема.
Надписи MTEXT на руском языке в AutoCad2002 получаются при печати почти не видимыми. Хотя при zoom'e видны довольно толстыми.
Исправить удается в 2005. Открываю mtext. Применяю стиль(тотже что и был) и все встает на свои места.
При просмотре content'a выдаёт чтото типа следующего
{\fRomanS|b0|i0|c204|p2;СМ}. {\fRomanS|b0|i0|c204|p2;ДЕТАЛЬНЫЙ} {\fRomanS|b0|i0|c204|p2;ЧЕРТЕЖ} {\fRomanS|b0|i0|c204|p2;ВАРИАНТОВ} {\fRomanS|b0|i0|c204|p2;СОЕДИНЕНИЯ} {\fRomanS|b0|i0|c204|p2;КОНТАКТОВ} {\fRomanS|b0|i0|c204|p2;ГРОМКОГОВОРИТЕЛЯ}: RUSA-GDE-GL-TD-88100.9027.
При применении тогоже стиля (см.выше) все эти фигурные скобки исчезают и текст отображается хорошо.
Как можно устранить эту проблему и почему она возникла.
Очееееень много чертежей с таким траблом и все приходится исправлять.

Re: Отображение руского текста (mtext) в AutoCad2002

Не помню, в каком сообщении было это:
В файл mtextmap.ini в секции [SHX Map] меняем
txt.shx=Txt,0,0,0,2
на txt.shx=Txt,0,0,204,2
Теперь после редактирования мтекста или его создания русские символы в чертеже отображаются
нормально, а латинские "жирноватые". Чтобы избавиться от "жирноватости" делаем шаг2.
2. Делаем шесть кликов мышью:
2.1 Нажимаем кнопку редактировать текст
2.2 Выбираем Ваш текст
2.3 Выбираем вкладку Свойсвтва в редакторе МТекста
2.4 Раскрываем список текстовых стилей
2.5 Выбираем из списка тот же стиль
2.6 Ок
Теперь должно всё выглядеть красиво. Опробывал на Вин2000, Акад2000i.
п.2.1 и п2.2 можно объединить в дабл-клик.
Я испольую нестандартный wwcade. У меня в mtextmap.ini такая запись - wwcade.shx=Arial,0,0,204,2
Tahoma отдыхает.
Я это применял на Акаде 2002. Поищи по форуму всю ветку.

Re: Отображение руского текста (mtext) в AutoCad2002

Нет, сейчас проблемма в другом.
Чертежи готовы, перешли на AutoCAD 2005 и надо исправлять все надписи, а их около 100 000(кошмар). Что можно сделать, чтобы не открывать каждую надпись и менять стиль на тотже, тем более проблемы с MTEXT всем известны. Кстати в 2002 была такая же проблема, но её не удавалось решить(вернее никто за это не брался). И вот её решили в 2005. Ну и руководство забурдело. А чертежей ой как много.

Re: Отображение руского текста (mtext) в AutoCad2002

http://dwg.ru/forum/viewtopic.php?t=3537
Посмотрите сюда :)

Re: Отображение руского текста (mtext) в AutoCad2002

Взорвать можно весь MText

Re: Отображение руского текста (mtext) в AutoCad2002

> Vook
А если без взрыва?

Re: Отображение руского текста (mtext) в AutoCad2002

В общем, тестируйте:

;|=============================================================================
*    Функция сносит форматирование многострочного текста. Удаляются символы "{"
* и "}", поскольку именно символ "}" является окончанием применения определенного
* фонта. Удаляются наборы типа {fTimes New Roman|b0|i0|c204|p18; и т.п.
*    Параметры вызова:
*    string-to-normalize    - строка, которую надо нормализовать
*    Примеры вызова:
(_kpblc-clear-mtext (cdr (assoc 1 (entget(car(entsel))))))
    ; для выбранного многострочного текста очищает форматирование.
=============================================================================|;
(defun _kpblc-clear-mtext (string-to-normalize               /
               sub_string         sub_pos           left_string
               right_string
               )
  (if (or
    (setq sub_pos (vl-string-search "{f" string-to-normalize))
    (setq sub_pos (vl-string-search "{\f" string-to-normalize))
    ) ;_ end of or
    (progn
      (setq left_string            ;все, что до "{"
             (substr
               string-to-normalize
               1
               (vl-string-position (ascii "{") string-to-normalize sub_pos)
               ) ;_ end of substr
        right_string        ;все, что между {f и ;
             (substr
               string-to-normalize
               (+ (vl-string-position (ascii ";") string-to-normalize sub_pos) 2)
               ) ;_ end of substr
        ) ;_ end of setq
      (_kpblc-clear-mtext (strcat left_string right_string))
      ) ;_ end of progn
    (vl-string-trim "}" (vl-string-trim "{" string-to-normalize))
    ) ;_ end of if
  ) ;_ end of defun

Re: Отображение руского текста (mtext) в AutoCad2002

Оппаньки, нашел несколько ошибок. Чтобы всем было хорошо, сделаю следующее:
1. для начала выбираем редактируемые тексты (мне-то требовалось выбирать все, поэтому сделал дополнительную команду)
2. Меняем для них значение.
Погнали

(defun c:clr_all( / selset)
  (setq selset (ssget '((0 . "MTEXT"))))
  (_kpblc-modify-mtext selset)
  )
(defun c:clr_sel( / selset)
  (setq selset (ssget "_X" '((0 . "MTEXT"))))
  (_kpblc-modify-mtext selset)
  )
(defun _kpblc-modify_mtext (selset)
  (while (and
       selset
       (> (sslength selset) 0)
       ) ;_ end of and
    (setq item (ssname selset 0))
    (ssdel item selset)
    (_kpblc-ent-modify-autoregen
      item
      1
      (_kpblc-clear-mtext (cdr (assoc 1 (entget item))))
      nil
      ) ;_ end of _kpblc-ent-modify-autoregen
    ) ;_ end of while
  ) ;_ end of defun
;|=============================================================================
*    Функция сносит форматирование многострочного текста. Удаляются символы "{"
* и "}", поскольку именно символ "}" является окончанием применения определенного
* фонта. Удаляются наборы типа {fTimes New Roman|b0|i0|c204|p18; и т.п.
*    Параметры вызова:
*    string-to-normalize    - строка, которую надо нормализовать
*    Примеры вызова:
(_kpblc-clear-mtext (cdr (assoc 1 (entget(car(entsel))))))
    ; для выбранного многострочного текста очищает форматирование.
=============================================================================|;
(defun _kpblc-clear-mtext    (string-to-normalize             /
             sub_string       sub_pos         left_string
             right_string
             )
  (if (or
    (setq sub_pos (vl-string-search "{f" string-to-normalize))
    (setq sub_pos (vl-string-search "{\\" string-to-normalize))
    (setq sub_pos (vl-string-search "\\f" string-to-normalize))
    (setq sub_pos (vl-string-search "{\\f" string-to-normalize))
    ) ;_ end of or
    (progn
      (setq left_string            ;все, что до "{"
             (substr
               string-to-normalize
               1
               (vl-string-position (ascii "\\") string-to-normalize sub_pos)
               ) ;_ end of substr
        right_string        ;все, что между {f и ;
             (substr
               string-to-normalize
               (+ (vl-string-position (ascii ";") string-to-normalize sub_pos) 2)
               ) ;_ end of substr
        ) ;_ end of setq
      (_kpblc-clear-mtext (strcat left_string right_string))
      ) ;_ end of progn
    (vl-string-trim "}" string-to-normalize)
    ) ;_ end of if
  ) ;_ end of defun
;|=======================================================================================
*    Функция модификации указанного бита примитива
*    Параметры вызова:
*    entity    - примитив, полученный через (entsel), (entlast) etc
*    bit    - dxf-код, значение которого надо установить
*    value    - новое значение
*    regen    - выполнять или нет регенерацию примитива сразу. t/ nil
*    Примеры вызова:
(_kpblc-ent-modify (entlast) 8 "0" t)    ; перенести последний примитив на слой 0
(_kpblc-ent-modify (entsel) 62 10 nil)    ; установить выбранному примитиву цвет 10
*    Возвращаемое значение:
*    примитив с модифицированным dxf-списком. Примитив автоматически перерисовывается.
=======================================================================================|;
(defun _kpblc-ent-modify-autoregen (ent bit value ext_regen / ent_list old_dxf new_dxf)
  (if (not
    (and
      (or
        (= (cdr (assoc 0 (entget ent))) "STYLE")
        (= (cdr (assoc 0 (entget ent))) "DIMSTYLE")
        (= (cdr (assoc 0 (entget ent))) "LAYER")
        ) ;_ end of or
      (= bit 100)
      ) ;_ end of and
    ) ;_ end of not
    (progn
      (setq ent_list (entget ent)
        new_dxf  (cons bit
               (if (and (= bit 62) (= (type value) 'str))
                 (if (= (strcase value) "BYLAYER")
                   256
                   0
                   ) ;_ end of if
                 value
                 ) ;_ end of if
               ) ;_ end of cons
        ) ;_ end of setq
      (if (not (equal new_dxf (setq old_dxf (assoc bit ent_list))))
    (progn
      (entmod (if old_dxf
            (subst new_dxf old_dxf ent_list)
            (append ent_list (list new_dxf))
            ) ;_ end of if
          ) ;_ end of entmod
      (if ent_regen
        (entupd ent)
        (redraw ent)
        ) ;_ end of if
      ) ;_ end of progn
    ) ;_ end of if
      ) ;_ end of progn
    ) ;_ end of if
  ent
  ) ;_ end of defun

Значится так, чтобы не разбираться во всех тонкостях - для очистки форматирования выделения с ком.строки набираем clr_sel, для прохода по всему файлу - clr_all.
Ессно, лисп должен быть подгружен.

Re: Отображение руского текста (mtext) в AutoCad2002

Сейчас вроде работает. Если будут еще какие-то баги замечены, прошу сообщать.

Re: Отображение руского текста (mtext) в AutoCad2002

Большое спасибо за участие.
Но...
Когда в следующем формате
FOR DETAILS SEE DRAWING RUSA-GDE-N1-82600.4111.004
N1-EDP-230V-02
{\fRomanS|b0|i0|c204|p2;ПОДРОБНЕЕ СМ. ЧЕРТЕЖ
GDE-N1-82600.4111.004
N1-EDP-230V-02}
то все отлично.
Когда в формате
{\fRomanS|b0|i0|c204|p2;ВЫПРЯМИТЕЛИ},
{\fRomanS|b0|i0|c204|p2;ЗАМЕНЯЕМЫЕ} {\fRomanS|b0|i0|c204|p2;ПОД}
то исправляет последнюю строку и оставляет '}' кроме последней то есть остаётся
{\fRomanS|b0|i0|c204|p2;ВЫПРЯМИТЕЛИ},
ЗАМЕНЯЕМЫЕ} ПОД}
Ну незнаю я ещё всех функций лиспа.
Сенкс всем

Re: Отображение руского текста (mtext) в AutoCad2002

Пометка.
Обрабатывает только часть текста.
Выудил в VisualLISP в Broswe Drawing DataBase
Короче дает не всю строку а её часть.
Соответственно функция
(cdr (assoc 1 (entget item)))
возвращает эту часть строки.
Буду искать куда девается остальная часть.

Re: Отображение руского текста (mtext) в AutoCad2002

Вычислил.
Идёт в паре с 3.
Ну строку загружаем с 1
(cdr (assoc 1 (entget item)))
Ставлю 3 выдает ошибку.

Re: Отображение руского текста (mtext) в AutoCad2002

Вообщем идея такова.
Загружать все со списка в память (проверять пару на 3 и 1 и начинать с первой 3-и и заканчивать 1-й) работать в памяти, потом как-то разбивать на блоки по 255 байт и записывать обратно....
Но как!!!!!

Re: Отображение руского текста (mtext) в AutoCad2002

Не, не надо. Там просто надо дополнительно, помимо группы 1, еще обрабатывать группу 3 - сам только поздно вечером допер. Но там не все так просто, как хотелось: в группе 3 хранятся блоки по 255 символов, включая служебные. А (assoc 3 (entget item)) выдает только первый. Поэтому надо будет поизвращаться. Как только гарантированно получится, положу код, нет - сорри, значит, не хватило меня.

Re: Отображение руского текста (mtext) в AutoCad2002

Проблема не в получении значений группы 3, а в изменении их корректном. :(

Re: Отображение руского текста (mtext) в AutoCad2002

Проблема в том что ещё блоки могут разбиваатся в середине, скажем подблока({\f....;текс}).
В принципе загружать эти секции в строку не проблема(сейчас пыхчу над этим) но надо будет отслеживать разбивку подблока и ставить какие-то флаги для корректной обработки следующего блока. А самоя большая проблема в точ, что я в LISP'е дуболом. Вот выдалась минутка и сижу читаю Help и что-то пытаюсь родить.

Re: Отображение руского текста (mtext) в AutoCad2002

Кстати, я в лиспе тоже не ас.
Насчет проблемы я в курсе, старался сделать, чтобы ее можно было игнорировать (чего и добился вроде как).
Слушай, может, я просто закошмарил ситуацию? И тебе просто надо перезаписать 7-ю группу? А? В таком варианте код становится достаточно простым - используются функции из "повыше"

Re: Отображение руского текста (mtext) в AutoCad2002

Если перезаписывать на тотже результат то ничего не получается (Bad DXF field 7) или чтото в этом роде. Если менять дважды подряд. Надо попробовать.

Re: Отображение руского текста (mtext) в AutoCad2002

Нет, в группе 7 там увидишь - хранится название стиля. Может, получить текущий стиль да и перезаписать его туда? а?

Re: Отображение руского текста (mtext) в AutoCad2002

Звгвозда.
Получаю текст из списка

(setq entl (entget ent)) ; ent->mtext
(setq ct 0)
  (textpage)
  (repeat (length entl)
    (setq cn (car (nth ct entl)))
    (if  (= cn 3)
      (progn
        (setq cs (cdr (nth ct entl)))
        (print cs)
        [b](clear-mtext cs)[/b]
        (print cs)
        )
       )
    (setq ct (+ ct 1))
  )

Получаю ошибку (на вызове отмечено жирным)
error: bad argument type: numberp: nil
3 часа сижу как дибил и немогу понять в чём дело

Re: Отображение руского текста (mtext) в AutoCad2002

Так, давай по почте или по аське, ок? А то мы сейчас тут все идеи похороним.
Я так полагаю, что (clear-mtext) у меня в коде была как _kpblc-clear-mtext? Если да, то тут шансов ноль. Надо переделывать ее и _kpblc-ent-modify-autoregen - именно там и кроется проблема.
Обрати внимание, что в _kpblc-ent-modify-autoregen используется subst, а она меняет первое вхождение группы, не затрагивая прочие. Так что корень зла именно здесь. По идее надо каким-то образом (скорее всего, через (entmake)) удалять имеющийся многострочный текст и по-новой его создавать. Гимор...

Re: Отображение руского текста (mtext) в AutoCad2002

Ну в общем дело обстоит так:
Функция (_kpblc-mtext-clear) у меня почему-то стала работать нормально (проверялось на ADT 2005, 2006 eng), теперь проблема с очисткой.
Строку из многострочного текста получаю через

(setq string (_kpblc-clear-mtext (vlax-get-property item "textstring")))

А потом тут же делаю

    (vlax-put-property
      item
      "textstring"
      string
      ) ;_ end of vlax-put-property

И вот какие проблемы.
1. Работает ооочень медленно. Особенно при работе в листе.
2. На некоторых элементах мало того, что думает минуты по 2 (пауза именно на обработке строки), так еще под конец и вываливает сообщение о нехватке памяти (ERRNO # 0: no memory for string body: 188743738).
Чтобы не быть голословным, списки обрабатываемого примитива и необрабатываемого:
Подвергается обработке:

(
(-1 . <Entity name: 7ef899c0>)
(0 . "MTEXT")
(330 . <Entity name: 7ef88e90>)
(5 . "54B0")
(100 . "AcDbEntity")
(67 . 1)
(410 . "секция 9")
(8 . "03.Лист штамп")
(48 . 10.0)
(100 . "AcDbMText")
(10 284.252 42.8368 0.0)
(40 . 2.3)
(41 . 83.5938)
(71 . 1)
(72 . 5)
(1 . "{\\fTimes New Roman|b1|i1|c204|p18;Здесь идет текст, который можно обработать, т.е. потереть times new roman}")
(7 . "Standard")
(210 0.0 0.0 1.0)
(11 1.0 -1.1331e-015 0.0)
(42 . 75.3362)
(43 . 3.03295)
(50 . 6.28319)
(73 . 1)
(44 . 1.0)
)

Не подвергается:

(
(-1 . <Entity name: 7ef899c8>)
(0 . "MTEXT")
(330 . <Entity name: 7ef88e90>)
(5 . "54B1")
(100 . "AcDbEntity")
(67 . 1)
(410 . "секция 9")
(8 . "03.Лист штамп")
(48 . 10.0)
(100 . "AcDbMText")
(10 283.913 47.0995 0.0)
(40 . 2.3)
(41 . 83.5938)
(71 . 1)
(72 . 5)
(1 . "{\\fTimes New Roman|b1|i1|c204|p18;Многоэтажный жилой комплекс\\fTimes New
Roman|b1|i1|c0|p18; \\fTimes New Roman|b1|i1|c204|p18;по адресу:}")
(7 . "Standard")
(210 0.0 0.0 1.0)
(11 1.0 -1.1331e-015 0.0)
(42 . 67.03)
(43 . 3.03295)
(50 . 6.28319)
(73 . 1)
(44 . 1.0)
)

Т.е. получается, что функция обработки строки требует доработки специально для таких случаев - некорректной (?) записи (кстати, еще вопрос - а что будет, если группа 3 тоже будет задействована)? Кто в силах все предусмотреть, подключитесь, плиз! Фантазии уже просто не хватает!
Вариант "сделать из строки массив и по массиву проходиться с удалением элементов проверяю, но слишком высока верятность удалить чего-нить не то.
Т.е. надо добиться гарантированно правильной работы (это раз) и очень высокой скорости (это два).

Re: Отображение руского текста (mtext) в AutoCad2002

Т.е. получается, что функция обработки строки требует доработки специально для таких случаев - некорректной (?) записи (кстати, еще вопрос - а что будет, если группа 3 тоже будет задействована)?

Получать текст с помощью ActiveX (vla-get-TextString обрабатывать и ложить обратно (vla-put-TextString. В этом случае текст передаётся полностью без деления на группы 1 и 3. Настоятельно рекомендую, потому что большинство билеберды возникает как раз на стыке  групп.
Кстати функцию очичтки строк в своё время писал ZZZ. Я её даже тестировал, вроде нормально работала. Ищи на "родном" форуме поиском. Я не говорю что у него лучше просто может чего почерпнёшь.
А у меня сегодня голова болит сильно, извиняй...

Re: Отображение руского текста (mtext) в AutoCad2002

> {Smirnoff}
Да ладно, я вечером допер, как сделать и почему не работало - я вторую часть делал не по тому набору. В общем, ща проверю и положу - мало ли, вдруг кому понадобится...

Re: Отображение руского текста (mtext) в AutoCad2002

Ну вот и код для проверки на других условиях:

;|=============================================================================
*    Функция сносит форматирование многострочного текста. Удаляются символы "{"
* и "}", поскольку именно символ "}" является окончанием применения определенного
* фонта. Удаляются наборы типа {fTimes New Roman|b0|i0|c204|p18; и т.п.
*    Параметры вызова:
*  string-to-normalize  - строка, которую надо нормализовать
*    Примеры вызова:
(_kpblc-clear-mtext (cdr (assoc 1 (entget(car(entsel))))))
  ; для выбранного многострочного текста очищает форматирование.
=============================================================================|;
(defun _kpblc-clear-mtext (string-to-normalize               /
               sub_string         sub_pos           left_string
               right_string
               )
  (if (or
    (setq sub_pos (vl-string-search "{f" string-to-normalize))
    (setq sub_pos (vl-string-search "{\\" string-to-normalize))
    (setq sub_pos (vl-string-search "\\f" string-to-normalize))
    (setq sub_pos (vl-string-search "{\\f" string-to-normalize))
    ) ;_ end of or
    (progn
      (setq left_string            ;все, что до "{"
         (vl-string-trim
           "{"
           (substr
         string-to-normalize
         1
         (vl-string-position
           (ascii "\\")
           string-to-normalize
           sub_pos
           ) ;_ end of vl-string-position
         ) ;_ end of substr
           ) ;_ end of vl-string-trim
        ) ;_ end of setq
      ;; Вот здесь была ошибка при некоторых условиях
      (if (vl-string-position
        (ascii ";")
        string-to-normalize
        sub_pos
        ) ;_ end of vl-string-position
    (setq right_string        ;все, что между {f и ;
           (substr
         string-to-normalize
         (+ (vl-string-position
              (ascii ";")
              string-to-normalize
              sub_pos
              ) ;_ end of vl-string-position
            2
            ) ;_ end of +
         ) ;_ end of substr
          ) ;_ end of setq
    (setq right_string "")
    ) ;_ end of if
      (_kpblc-clear-mtext (strcat left_string right_string))
      ) ;_ end of progn
    ;; Старый вариант попытки снесения "}"
    ;;(vl-string-trim "}" string-to-normalize)
    ;; Новый вариант снесения "}"
    (vl-list->string
      (vl-remove
    (ascii "}")
    (vl-string->list string-to-normalize)
    ) ;_ end of vl-remove
      ) ;_ end of vl-list->string
    ) ;_ end of if
  ) ;_ end of defun
;|=============================================================================
*    Функция удаления форматирования на выбранных элементах
=============================================================================|;
(defun c:unf-sel (/ selset item)
  (setq selset (ssget '((0 . "MTEXT"))))
  (while (and
       selset
       (> (sslength selset) 0)
       ) ;_ end of and
    (setq item (ssname selset 0))
    (ssdel item selset)
    (vlax-put-property
      (vlax-ename->vla-object item)
      "TextString"
      (_kpblc-clear-mtext
    (vlax-get-property (vlax-ename->vla-object item) "TextString")
    ) ;_ end of _kpblc-clear-mtext
      ) ;_ end of vlax-put-property
    ) ;_ end of while
  ) ;_ end of defun
;|=============================================================================
*    Функция удаления форматирования на выбранных элементах
=============================================================================|;
(defun c:unf-all (/ selset item)
  (setq selset (ssget "_X" '((0 . "MTEXT"))))
  (while (and
       selset
       (> (sslength selset) 0)
       ) ;_ end of and
    (setq item (ssname selset 0))
    (ssdel item selset)
    (vlax-put-property
      (vlax-ename->vla-object item)
      "TextString"
      (_kpblc-clear-mtext
    (vlax-get-property (vlax-ename->vla-object item) "TextString")
    ) ;_ end of _kpblc-clear-mtext
      ) ;_ end of vlax-put-property
    ) ;_ end of while
  ) ;_ end of defun
(princ (strcat
     "\nНаберите unf-sel для очистки форматирования выбранных текстов;"
     "\nunf-all - для полной очистки на всем файле"
     ) ;_ end of strcat
       ) ;_ end of princ