C# - Font megnevezésének lekérdezése a TTF állomány alapján

forráskód letöltése
Ha adott egy TTF állomány, mely még nincs telepítve a rendszerbe, akkor felmerülhet az igény arra, hogy mi is lehet ennek a betűtípusnak a neve? Sajnos a TTF állomány nevéből ez valószínűleg nem fog kiderülni. Legalábbis a COPGOTHB.TTF-ből nem biztos, hogy mindenki számára evidens, hogy ez a Copperplate Gothic Bold BT nevű font. Ennél fogva viszont célszerű egy olyan kis függvényt készíteni, mely képes arra, hogy TTF állomány alapján kiderítse a betűtípus nevét.
Ez a függvény a GetFontNameFromTTF nevet kapta. Paraméterként kéri a TTF állomány nevét, visszatérési értékként a font nevét adja.
A megoldáshoz a következő trükköt használjuk fel: a CreateScalableFontResource Windows függvény hívásával létrehozunk a TTF állomány alapján egy FOT kiterjesztésű állományt. A függvény valójában arra szolgál, hogy méretezhető font erőforrásokat készítsünk, de nekünk most nem erre van szükségünk, hanem csak a FOT állomány létrejöttére. Ugyanis ebbe az állományba már belekerül a TTF állományban lévő betűtípus neve szövegesen és így azt onnan ki tudjuk olvasni. Bár ez az információ rendelkezésre áll a TTF-ben, onnan viszont sokkal körülményesebb módon tudnánk csak elővarázsolni a számunkra fontos sztringet.
FOT állomány létrehozásához tehát meghívjuk a CreateScalableFontResource függvényt.
    private string GetFontNameFromTTF(string ttfFileName)
    {
      string tempfile = Path.ChangeExtension(Path.GetTempFileName(), "fot");
      Win32.CreateScalableFontResource(1, tempfile, ttfFileName, "");
Ezek után már csak meg kell keresnünk a FOT állományban a betűtípus nevét. Ehhez az állományt beolvassuk egy bájtokat tartalmazó tömbbe.
      FileStream fs = new FileStream(tempfile, FileMode.Open);
      BinaryReader br = new BinaryReader(fs);
      byte[] fot = br.ReadBytes((int)fs.Length);
Az állomány ugyan bináris, de a betűtípus neve szövegesen olvasható, így az egyszerűség kedvéért ezt a bájt tömböt sztringként fogjuk kezelni. Ehhez azonban a nulla értékű bájtokat le kell cserélnünk, mondjuk a TAB (9) kódjára, mivel ha nullát hagynánk benne, ott a sztring véget érne.
      for (int i=0; i<fs.Length; i++)
      {
        if (fot[i]==0)
        {
          fot[i]=9;
        }
      }
Ezt követi az a lépés, amikor a bájt tömbből sztringet készítünk.
      string s = "";
      foreach (char c in fot)
      {
        s+=c;       
      }
Tudjuk azt, hogy a FOT állományban a „FONTRES:” sztring után olvasható be a betűtípus neve, így meg kell keresnünk az előállított sztringben ezt a szöveget.
      int pos = s.IndexOf("FONTRES:");
      pos+=8;
Végül már csak ki kell olvasnunk a megtalált pozícióról a karaktereket egészen az első TAB karakterig. Mivel az eredeti FOT állományban egy nulla bájt zárja a font nevét, amit ugye időközben kicseréltünk tab-ra, így biztosak lehetünk a tab találata esetén, hogy a font neve véget ért.
      string fontname="";
      while (s[pos]!='\t')
      {
        fontname+=s[pos];
        pos++;
      }
Most már csak zárnunk kell a megnyitott FOT állományt, majd egyúttal töröljük is, hogy ne maradjon „szemét” az alkalmazásunk után.
      fs.Close();
      File.Delete(tempfile);
      return fontname;
    }