AutoCAD .net : Check is font file missing

28 Views Asked by At

Achievement

Hi! In AutoCAD, there's a yellow icon displayed if the font is missing.

enter image description here

I'm working on AutoCAD .net api in C#. I want to check if there's any font file missing in AutoCAD.

Approaches

My idea to approach this is:

  1. Implement a method checkIsFontFileMissing with a TextStyleTableRecord input, it returns a boolean indicates that if the font file of this text style is missing.(missing icon is shown in AutoCAD)
  2. Iterate all text style and check them with checkIsFontFileMissing

something like below:

using Autodesk.AutoCAD.ApplicationServices;
using Autodesk.AutoCAD.DatabaseServices;
using Autodesk.AutoCAD.EditorInput;
using AcadApplication = Autodesk.AutoCAD.ApplicationServices.Application;

[CommandMethod("TT")]
public void TT()
{
    Document doc = AcadApplication.DocumentManager.MdiActiveDocument;
    Database database = doc.Database;
    Editor editor = doc.Editor;
    using (var tr = database.TransactionManager.StartTransaction())
    {
        var textStyleTbl = database.TextStyleTableId.GetObject(OpenMode.ForRead) as TextStyleTable;
        foreach (ObjectId objId in textStyleTbl)
        {
            var textStyle = objId.GetObject(OpenMode.ForRead) as TextStyleTableRecord;

            checkIsFontFileMissing(textStyle);
        }
    }
}

for checkIsFontFileMissing:

  1. if any of FileName / BigFontFileName not exists, return true(some file missing)
  2. only if both of FileName / BigFontFileName exist, return false(all file not missing)
  3. if FileName / BigFontFileName is empty string, regard it as not missing.

My idea is to find font file from all paths in support search path in AutoCAD. it looks like:

bool checkIsFontFileMissing(TextStyleTableRecord textStyle)
{
    //get all support search path in AutoCAD
    object acadObject = AcadApplication.AcadApplication;
    object preferences = acadObject.GetType().InvokeMember("Preferences", System.Reflection.BindingFlags.GetProperty, null, acadObject, null);
    object files = preferences.GetType().InvokeMember("Files", System.Reflection.BindingFlags.GetProperty, null, preferences, null);
    string supportPathStr = (string)files.GetType().InvokeMember("SupportPath", System.Reflection.BindingFlags.GetProperty, null, files, null);
    string[] supportPaths = supportPathStr.Split(';');

    //access file name of font
    string fontFile = textStyle.FileName;
    string bigFontFile = textStyle.BigFontFileName;

    //try to find font file in all support search path
    bool isFontFileMissing = fontFile == "" ? false : true;
    bool isBigFontFileMissing = bigFontFile == "" ? false : true;
    foreach (string supportPath in supportPaths)
    {
        string fontFilePath = System.IO.Path.Combine(supportPath, fontFile);
        string bigFontFilePath = System.IO.Path.Combine(supportPath, bigFontFile);

        if (System.IO.File.Exists(fontFilePath)) isFontFileMissing = false;
        if (System.IO.File.Exists(bigFontFilePath)) isBigFontFileMissing = false;
    }

    return isFontFileMissing || isBigFontFileMissing;
}

Problems

  1. most of FileName property contains ".shx" at the end. but some of them do not. for example we have txt.shx in some path, but FileName property return txt (not txt.shx), so it's unable to find a file in checkIsFontFileMissing

  2. some files that can't be found from all paths, but shown not missing in AutoCAD. for example I have a font stylu.ttf , this file can't be found from all paths, but shown not missing in AutoCAD. is it because there are some built-in font or something?

In summary, my approach seems not to be a good one. is there a better approach to do this? Any suggestion is really appreciated!

0

There are 0 best solutions below