tags:

views:

39

answers:

1

Hi, I was wondering if anyone knows how to programatically get things like the version and copyright details out of a true type font. If you open it in explorer as well as the preview you get this info in the windows font viewer. I've looked at the Logfont structure but the info doesn't seem to be in here

Cheers Luke

+2  A: 

I had to do this a couple years ago for a work project. I can't post this as it's proprietary, but the spec for TT fonts is here.

I wrote classes for offset table, name record, name table header, and table directory elements such that each class had a static FromStream method.

I also wrote a utility class called BigEndianReader to handle reading data in from a big endian ordered stream, which I'm happy to put here to make your life easier:

public class BigEndianReader
{
    public static bool Read(Stream stm, out uint i)
    {
        int bhihi = stm.ReadByte();
        if (bhihi == -1)
        {
            i = 0;
            return false;
        }
        int bhi = stm.ReadByte();
        if (bhi == -1)
        {
            i = 0;
            return false;
        }
        int blo = stm.ReadByte();
        if (blo == -1)
        {
            i = 0;
            return false;
        }
        int blolo = stm.ReadByte();
        if (blolo == -1)
        {
            i = 0;
            return false;
        }
        i = (uint)((bhihi << 24) | (bhi << 16) | (blo << 8) | blolo);
        return true;
    }

    public static bool Read(Stream stm, out int i)
    {
        int bhihi = stm.ReadByte();
        if (bhihi == -1)
        {
            i = 0;
            return false;
        }
        int bhi = stm.ReadByte();
        if (bhi == -1)
        {
            i = 0;
            return false;
        }
        int blo = stm.ReadByte();
        if (blo == -1)
        {
            i = 0;
            return false;
        }
        int blolo = stm.ReadByte();
        if (blolo == -1)
        {
            i = 0;
            return false;
        }
        i = ((bhihi << 24) | (bhi << 16) | (blo << 8) | blolo);
        return true;
    }


    public static bool Read(Stream stm, out ushort s)
    {
        int bhi = stm.ReadByte();
        if (bhi == -1)
        {
            s = 0;
            return false;
        }
        int blo = stm.ReadByte();
        if (blo == -1)
        {
            s = 0;
            return false;
        }
        s = (ushort)(((bhi << 8) | blo) & 0xffff);
        return true;
    }

    public static bool Read(Stream stm, out short s)
    {
        int bhi = stm.ReadByte();
        if (bhi == -1)
        {
            s = 0;
            return false;
        }
        int blo = stm.ReadByte();
        if (blo == -1)
        {
            s = 0;
            return false;
        }
        s = (short)(((bhi << 8) | blo) & 0xffff);
        return true;
    }
}

This is not especially elegant, but it's easy enough to use:

int val;

if (!BigEndianReader.Read(stm, out val))
    throw new SomeErrorOfSomeKind();

I imagine that if you cared enough you could make this all extension methods on Stream and then your could would read:

int val;

if(!stm.BERead(out val)) // BE prefix for Big Endian
    throw new SomeErrorOfSomeKind();
plinth
thanks plinth it gives me a starting point
beakersoft