четверг, 5 июня 2014 г.

Текстовые стили в AutoCAD

Заметка содержит пример программного создания и детальной настройки текстового стиля в AutoCAD.


В результате работы кода (команда CreateOrEditTextStyle) будет создан и настроен новый текстовый стиль:


В коде каждая изменяемая нами опция настроек помечена комментарием, содержащим наименование этой опции в англоязычной версии AutoCAD.

/* TextStyleSample.cs
 * AutoCAD 2009-2015
 * © Андрей Бушман, 2014 
 * Пример по работе с текстовым стилем. 
 */
using System;
 
#if AUTOCAD
using cad = Autodesk.AutoCAD.ApplicationServices
.Application;
using Ap = Autodesk.AutoCAD.ApplicationServices;
using Db = Autodesk.AutoCAD.DatabaseServices;
using Rt = Autodesk.AutoCAD.Runtime;
#endif
 
[assembly: Rt.CommandClass(typeof(Bushman.CAD
  .Samples.Styles.TextStyleSample))]
 
namespace Bushman.CAD.Samples.Styles {
  public static class TextStyleSample {
    // Наименование группы команд
    const String ns = "Samples";
    /// <summary>
    /// В текущем чертеже данная команда либо 
    /// создаёт новый текстовый стиль и полностью
    /// настраивает его, либо выполняет его 
    /// перенастройку, если нужный стиль уже 
    /// существует.
    /// </summary>
    [Rt.CommandMethod(ns,
      "CreateOrEditTextStyle",
      Rt.CommandFlags.Modal)]
    public static void CreateOrEditTextStyle() {
      Ap.Document doc = cad.DocumentManager
        .MdiActiveDocument;
      if(doc == null)
        return;
      using(doc.LockDocument()) {
        CreateOrEditTextStyle(doc.Database);
      }
    }
 
    /// <summary>
    /// В указанной базе данных данная команда 
    /// либо создаёт новый текстовый стиль и 
    /// полностью настраивает его, либо выполняет
    /// его перенастройку, если нужный стиль уже 
    /// существует.
    /// </summary>
    /// <param name="db">База данных, подлежащая 
    /// обработке</param>
    private static void CreateOrEditTextStyle(
      Db.Database db) {
      if(db == null)
        throw new ArgumentNullException("db");
      using(Db.Transaction tr =
        db.TransactionManager.StartTransaction()) 
        {
        Db.TextStyleTable tst =
          (Db.TextStyleTable)tr.GetObject(
          db.TextStyleTableId, Db.OpenMode
          .ForWrite);
 
        String textStyleName = "Курсив";
        Db.TextStyleTableRecord rec = null;
 
        // Если нужного текстового стиля нет, то 
        // создаём его
        if(!tst.Has(textStyleName))
          rec = new Db.TextStyleTableRecord();
        else // Если стиль существует, то 
          // открываем его для редактирования.
          rec = tr.GetObject(tst[textStyleName],
            Db.OpenMode.ForWrite)
            as Db.TextStyleTableRecord;
 
        // ttf или, к примеру, "txt.shx".
        String fontName = "Times New Roman.ttf";
        String bigFontName = String.Empty;
        FillTextStyle(rec, textStyleName,
          fontName, bigFontName,
          Db.AnnotativeStates.NotApplicable, 0,
          0.8, 15, falsefalsefalsefalse);
 
        // Если это новый текстовый стиль, то не 
        // забываем добавить его в базу данных 
        // чертежа.
        if(rec.Database == null) {
          tst.Add(rec);
          tr.AddNewlyCreatedDBObject(rec, true);
        }
        tr.Commit();
      }
    }
 
    /// <summary>
    /// Настройка текстового стиля.
    /// </summary>
    /// <param name="rec">Текстовый стиль, 
    /// подлежащий обработке.</param>
    /// <param name="styleName">Имя текстового 
    /// стиля.</param>
    /// <param name="fontName">Наименование 
    /// используемого шрифта: Font Name в 
    /// диалоговом окне Text Style.</param>
    /// <param name="fontStyle">Наименование 
    /// большого шрифта: Font Style в 
    /// диалоговом окне Text Style. Если этому 
    /// свойству назначить непустое 
    /// значение, то в диалоговом окне Text Style 
    /// будет включена опция Use Big 
    /// Font.</param>
    /// <param name="annotativeStatus">Должен ли 
    /// текстовый стиль быть 
    /// аннотативным: True - аннотативен, False 
    /// или NotApplicable - не 
    /// аннотативен. Опция Annotative в 
    /// диалоговом окне Text Style.</param>
    /// <param name="textHeight">Высота текста: 
    /// Paper Text Height в диалоговом 
    /// окне Text Style.</param>
    /// <param name="widthFactor">Коэффициент 
    /// сжатия текста по горизонтали: 
    /// Width Factor в диалоговом окне Text Style
    /// </param>
    /// <param name="obliquingAngle">Угол наклона
    /// текста. Указывается в градусах и 
    /// отсчитывается от вертикали по часовой 
    /// стрелке. Oblique Angle в диалоговом окне 
    /// Text Style.</param>
    /// <param name="setPaperOrientation">Опция 
    /// Match text orientation to layout в 
    /// диалоговом окне Text Style.</param>
    /// <param name="upsideDown">
    /// Опция Upside down в диалоговом окне Text 
    /// Style.</param>
    /// <param name="backwards">
    /// Опция Backwards в диалоговом окне Text 
    /// Style.</param>
    /// <param name="vertical">
    /// Опция Vertical в диалоговом окне Text 
    /// Style.</param>
    private static void FillTextStyle(
      Db.TextStyleTableRecord rec,
      String styleName, String fontName,
      String fontStyle,
      Db.AnnotativeStates annotativeStatus,
      Double textHeight,
      Double widthFactor, Double obliquingAngle,
      Boolean setPaperOrientation,
      Boolean upsideDown, Boolean backwards,
      Boolean vertical) {
 
      if(rec == null)
        throw new ArgumentNullException("rec");
 
      if(styleName == null)
        throw new ArgumentNullException(
          "styleName");
      if(fontName == null)
        throw new ArgumentNullException(
          "fontName");
      if(fontStyle == null)
        throw new ArgumentNullException(
          "fontStyle");
 
      if(styleName.Trim() == String.Empty)
        throw new ArgumentException("styleName");
      if(fontName.Trim() == String.Empty)
        throw new ArgumentException("fontName");
      if(fontStyle.Length > 0 &&
        fontStyle.Trim() == String.Empty)
        throw new ArgumentException("fontStyle");
 
      rec.Name = styleName;
      rec.Annotative = annotativeStatus;
      rec.FileName = fontName;
      rec.XScale = widthFactor;
      // Переводим градусы в радианы
      rec.ObliquingAngle = obliquingAngle *
        Math.PI / 180;
      rec.SetPaperOrientation(
        setPaperOrientation);
 
      // Если мы назначаем значение свойству 
      // BigFontFileName, то в диалоговом окне 
      // Text Style автоматически включается 
      // галочка "Use Big Font"
      rec.BigFontFileName = fontStyle;
 
      // эти флаги хранят значения опций "Upside 
      // down" и "Backwards"
      rec.FlagBits = (Byte)0;
 
      rec.FlagBits += upsideDown ? (Byte)2 :
        (Byte)0; // Upside down      
      rec.FlagBits += backwards ? (Byte)4 :
        (Byte)0; // Backwards
 
      rec.TextSize = textHeight;
      rec.IsVertical = vertical;
    }
  }
}

5 комментариев:

Виктор Тарнаев комментирует...

А можно скомпилировать в в dll?

Андрей Бушман комментирует...

Обозначенный выше код компилируется в dll и подгружается в AutoCAD командой NETLOAD.

Виктор Тарнаев комментирует...

Это я понимаю, и уже пользуюсь вашей библиотекой ConvertTable.dll, но я не знаю как превратить код в dll?
Изучать видимо уж поздно, но если это не сложно я попытаюсь освоить. В какой программе это можно сделать7

Андрей Бушман комментирует...

Данная заметка предназначена для программистов, дабы показать, как программно оперировать настройками текстового стиля. С точки зрения рядового пользователя она не представляет никакого интереса, т.к. все обозначенные действия легко выполняются пользователем вручную в обозначенном диалоговом окне.

При желании откомпилировать данный код можно в Visual Studio 2008-2013 или в Sharp Develop. Так же потребуется ObjectARX SDK. Информацию о .NET программировании под AutoCAD можно почитать здесь: https://sites.google.com/site/bushmansnetlaboratory/translate-manual

Виктор Тарнаев комментирует...

Спасибо, я уже понял, что мне не осилить этого. Но Ваша библиотека мне уже сегодня дважды помогла вытащить таблицы в excel. Большое спасибо!