Сообщество программистов Autodesk в СНГ

ADN Club => AutoCAD .NET API => Тема начата: Алексей (IdeaSoft) от 22-12-2014, 23:27:57

Название: Получить содержимое строки верхнего или нижнего индексов в строке Mtext
Отправлено: Алексей (IdeaSoft) от 22-12-2014, 23:27:57
Всем привет! В AutoCAD API (2006 по 2015 версиях) можно получить содержимое используя метод
Mtext.ExplodeFragments. Этот метод дал мне только содержимое основного текста.
На практике нужна задача получить содержимое верхних индексов содержимого Mtext.

Что первое приходит в голову - это проанализировать формат строки объекта Mtext
к примеру такого вида Mtext.contents = " ...{H2.5;\Sa^;}..."
и выгрузить из нее символ "а" верхнего индекса.
Но может все же в AutoCAD API есть стандартные методы для
"вытаскивания" содержимого верхних или нижних индексов.

В принципе нужно пока только, когда Mtext имеет одну строку.
 
     
Название: Re: Получить содержимое строки верхнего или нижнего индексов в строке Mtext
Отправлено: Александр Ривилис от 23-12-2014, 00:48:19
Но может все же в AutoCAD API есть стандартные методы для
"вытаскивания" содержимого верхних или нижних индексов.
Стандартных нет. Да и вообще как таковых верхних/нижних индексов нет. Это лишь элемент условного форматирования. Скорее уж можно попытаться средствами Regex в .NET проанализировать строку и получить индексы. Но тут я не эксперт.
Название: Re: Получить содержимое строки верхнего или нижнего индексов в строке Mtext
Отправлено: Александр Ривилис от 23-12-2014, 01:22:55
А вообще возможен и такой метод:

Код - C# [Выбрать]
  1. using System;
  2. using System.Runtime.InteropServices;
  3. using System.Reflection;
  4. using Autodesk.AutoCAD.Runtime;
  5. using Autodesk.AutoCAD.ApplicationServices;
  6. using Autodesk.AutoCAD.DatabaseServices;
  7. using Autodesk.AutoCAD.Geometry;
  8. using Autodesk.AutoCAD.EditorInput;
  9. using AcRx = Autodesk.AutoCAD.Runtime;
  10. using AcAp = Autodesk.AutoCAD.ApplicationServices;
  11. using AcDb = Autodesk.AutoCAD.DatabaseServices;
  12. using AcGe = Autodesk.AutoCAD.Geometry;
  13. using AcEd = Autodesk.AutoCAD.EditorInput;
  14. // This line is not mandatory, but improves loading performances
  15. [assembly: CommandClass(typeof(MTextIndex.MyCommands))]
  16.  
  17. namespace MTextIndex
  18. {
  19.  
  20.   public class MyCommands
  21.   {
  22.     public MTextFragmentCallbackStatus
  23.       MTextCallback(MTextFragment frag, object userData)
  24.     {
  25.       Editor ed = Application.DocumentManager.MdiActiveDocument.Editor;
  26.       string fragText = frag.Text;
  27.       if (frag.StackBottom)
  28.       {
  29.         ed.WriteMessage("\nНижний индекс: \"{0}\"", fragText);
  30.       }
  31.       else if (frag.StackTop)
  32.       {
  33.         ed.WriteMessage("\nВерхний индекс: \"{0}\"", fragText);
  34.       }
  35.       return MTextFragmentCallbackStatus.Continue;
  36.     }
  37.  
  38.     [CommandMethod("TestMText")]
  39.     public void TestMText()
  40.     {
  41.       Document doc = Application.DocumentManager.MdiActiveDocument;
  42.       Database db = doc.Database;
  43.       Editor ed = doc.Editor;
  44.       PromptEntityResult per = ed.GetEntity("Выберите MText для проверки :");
  45.  
  46.       if (per.Status != PromptStatus.OK)
  47.         return;
  48.       if (!per.ObjectId.ObjectClass.IsDerivedFrom(RXClass.GetClass(typeof(MText))))
  49.       {
  50.         ed.WriteMessage("Это не MText!");
  51.         return;
  52.       }
  53.       using (MText mtext = per.ObjectId.Open(OpenMode.ForRead) as MText)
  54.       {
  55.         mtext.ExplodeFragments(new MTextFragmentCallback(MTextCallback));
  56.       }
  57.     }
  58.   }
  59. }

И вроде даже работает:
(https://adn-cis.org/forum/proxy.php?request=http%3A%2F%2Fimg-fotki.yandex.ru%2Fget%2F15591%2F7842324.3%2F0_f1c03_2b3d9f50_orig.png&hash=52f3266f743a1b6f1365deb657d5061f)
Название: Re: Получить содержимое строки верхнего или нижнего индексов в строке Mtext
Отправлено: Алексей (IdeaSoft) от 23-12-2014, 15:45:09
Саша, спасибо все работает функции StackTop и StackBottom делают свою работу.

Я раньше считал, что фрагменты - это строки для многострочного текста, а получается, что
в общем случае фрагменты текстов могут не соответствовать строкам.
Т.е. получается что многострочный текст может содержать одну строку, а фрагментов в ней несколько.

Пока не могу найти решения, как отследить переход строки?
Хорошо, если  есть еще функция проверки перехода строки между этими фрагментами фрагментов.
Название: Re: Получить содержимое строки верхнего или нижнего индексов в строке Mtext
Отправлено: Александр Ривилис от 23-12-2014, 16:08:28
Тут тебе придется самостоятельно отслеживать свойства Extents и Location объекта MTextFragment, чтобы понять, что произошел переход на новую строку.  Или (это предположение, которое я не проверял) проверять совпадение всех остальных свойств MTextFragment у текущего и предыдущего фрагмента.
Название: Re: Получить содержимое строки верхнего или нижнего индексов в строке Mtext
Отправлено: Александр Ривилис от 23-12-2014, 16:38:52
Т.е. получается что многострочный текст может содержать одну строку, а фрагментов в ней несколько.
Фрагмент - это кусок текста, в котором изменено форматирование по сравнению с предыдущим куском текста. Например, поменялся шрифт или цвет, или наклон текста, или произошел переход на следующую строку.
Название: Re: Получить содержимое строки верхнего или нижнего индексов в строке Mtext
Отправлено: Алексей (IdeaSoft) от 23-12-2014, 16:59:45
Extents и Location
У меня тоже была идея проверять переход строки по координатам Location.
Это нужно проверить написать тест.
Ведь если подумать, то скорее Location.Y следующей строки меньше чем предыдущей (если угол поворота Mtext = 0).
Что бы не заморачиваться с углом поворота всего Mtext,
то можно создать копию Mtext в памяти с углом поворота = 0.
Название: Re: Получить содержимое строки верхнего или нижнего индексов в строке Mtext
Отправлено: Алексей (IdeaSoft) от 23-12-2014, 18:00:42
Я проверил свойство point3d Location вполне подходит для анализа перехода строки.
У следующей строки Location.Y меньше чем у предыдущей (при повороте = 0).
При повороте 90 гр. можно проверять координату X.

1) Исключение может составить случай, когда Location.Y нижнего индексного
   выражения меньше чем у основного текста этой же строки.
   Но зная что он нижний его в сравнении не задействовать.
2) Второй момент при котором анализ перехода строки может быть некорректным,
    когда в следующая срока начнется с индексного текста,   
   а не с основного, в этом случае индексный символ войдет в строку выше.
3) Еще может быть случай, когда в строке нет основных символов, а только индексные.
    Такой вариант маловероятен, но возможен.

Если не заморачиваться со всякими извращенными формами форматирования и принять за стандарт,
что есть верхние и нижние индексы шрифт одинаковый, то вполне подойдет анализ координаты Y.