2 Replies Latest reply on Mar 3, 2004 1:37 AM by (oksale)

    Help: problem with OS/2 table

      I try programmicaly read OS/2 table.
      First part of table I read without problems, but with the second there are some problems. For example, I want obtain fsSelection value, and for any font this value equal 32(bold). When I obtain macStyle from HEAD table, all right. But values of macStyle and fsSelection must be identical! In what there can be a problem?
        • 1. Re: Help: problem with OS/2 table
          It's a little hard to tell without seeing your code but I would guess that you should double-check your code that reads in the panose and vendor values. Since they are arrays, multiple bytes need to be read before reaching the fsSelection value.
          • 2. Re: Help: problem with OS/2 table
            Level 1
            My Code:
            But in panose and vendor information is right. And method of working with tables is the same. But problems only with this table, and I don't know why :(

            typedef struct _tagTT_OFFSET_TABLE{
            USHORT uMajorVersion;
            USHORT uMinorVersion;
            USHORT uNumOfTables;
            USHORT uSearchRange;
            USHORT uEntrySelector;
            USHORT uRangeShift;
            }TT_OFFSET_TABLE;

            typedef struct _tagTT_TABLE_DIRECTORY{
            char szTag[4]; //table name
            ULONG uCheckSum; //Check sum
            ULONG uOffset; //Offset from beginning of file
            ULONG uLength; //length of the table in bytes
            }TT_TABLE_DIRECTORY;

            typedef struct _tagTT_OS_RECORD{
            USHORT version;
            SHORT xAvgCharWidth;
            USHORT usWeightClass;
            USHORT usWidthClass;
            SHORT fsType;
            SHORT ySubscriptXSize;
            SHORT ySubscriptYSize;
            SHORT ySubscriptXOffset;
            SHORT ySubscriptYOffset;
            SHORT ySuperscriptXSize;
            SHORT ySuperscriptYSize;
            SHORT ySuperscriptXOffset;
            SHORT ySuperscriptYOffset;
            SHORT yStrikeoutSize;
            SHORT yStrikeoutPosition;
            SHORT sFamilyClass;
            PANOSE panose;
            ULONG ulUnicodeRange1;
            ULONG ulUnicodeRange2;
            ULONG ulUnicodeRange3;
            ULONG ulUnicodeRange4;
            CHAR achVendID[4];
            USHORT fsSelection;
            USHORT usFirstCharIndex;
            USHORT usLastCharIndex;
            USHORT sTypoAscender;
            USHORT sTypoDescender;
            USHORT sTypoLineGap;
            USHORT usWinAscent;
            USHORT usWinDescent;
            ULONG ulCodePageRange[2];
            }TT_OS_RECORD;

            // structure for writing results
            typedef struct _tagFONT_PROPERTIES{
            CString csName;
            USHORT Weight;
            USHORT Width;
            BOOL bItalic;
            BOOL bUnderline;
            BOOL bStrikeOut;
            USHORT uFamily;
            }FONT_PROPERTIES, *LPFONT_PROPERTIES;

            // from Big Endian to Little Endian
            #define SWAPWORD(x) MAKEWORD(HIBYTE(x), LOBYTE(x))
            #define SWAPLONG(x) MAKELONG(SWAPWORD(HIWORD(x)), SWAPWORD(LOWORD(x)))

            ....
            LPFONT_PROPERTIES lpFontProps = new FONT_PROPERTIES;
            CString pstrName = "C:\\WINDOWS\\Fonts\\ANTQUABI.TTF";
            lpFontProps->csName = "";
            GetFontPropertiesFromOS(pstrName, lpFontProps);
            ....

            BOOL CMyDlg::GetFontPropertiesFromOS(LPCTSTR lpszFilePath, LPFONT_PROPERTIES lpFontProps)
            {
            CFile f;
            BOOL bRetVal = FALSE;

            if(f.Open(lpszFilePath, CFile::modeRead|CFile::shareDenyWrite)){
            TT_OFFSET_TABLE ttOffsetTable;
            f.Read(&ttOffsetTable, sizeof(TT_OFFSET_TABLE));
            ttOffsetTable.uNumOfTables = SWAPWORD(ttOffsetTable.uNumOfTables);
            ttOffsetTable.uMajorVersion = SWAPWORD(ttOffsetTable.uMajorVersion);
            ttOffsetTable.uMinorVersion = SWAPWORD(ttOffsetTable.uMinorVersion);

            //check is this is a true type font and the version is 1.0
            if(ttOffsetTable.uMajorVersion != 1 || ttOffsetTable.uMinorVersion != 0)
            return bRetVal;

            TT_TABLE_DIRECTORY tblDir;
            BOOL bFoundOS = FALSE;
            CString csTemp;

            for(int i=0; i< ttOffsetTable.uNumOfTables; i++){
            f.Read(&tblDir, sizeof(TT_TABLE_DIRECTORY));
            strncpy(csTemp.GetBuffer(5), tblDir.szTag, 4);
            csTemp.ReleaseBuffer(4);
            if(csTemp.CompareNoCase(_T("OS/2")) == 0){
            bFoundOS = TRUE;
            tblDir.uLength = SWAPLONG(tblDir.uLength);
            tblDir.uOffset = SWAPLONG(tblDir.uOffset);
            break;
            }
            else if(csTemp.IsEmpty())
            {
            break;
            }
            }

            if(bFoundOS)
            {
            int nPos = f.GetPosition();
            f.Seek(tblDir.uOffset, CFile::begin);
            TT_OS_RECORD ttOSRecord;
            bFoundOS = FALSE;

            if(lpFontProps->csName.IsEmpty())
            {
            f.Read(&ttOSRecord, sizeof(TT_OS_RECORD));
            ttOSRecord.version = SWAPWORD(ttOSRecord.version);
            lpFontProps->Weight = SWAPWORD(ttOSRecord.usWeightClass);
            lpFontProps->Width = SWAPWORD(ttOSRecord.usWidthClass);
            ttOSRecord.sFamilyClass = SWAPWORD(ttOSRecord.sFamilyClass);
            // high byte of this field contains the family class
            BYTE hb = HIBYTE(ttOSRecord.sFamilyClass);
            // low byte contains the family subclass
            BYTE lb = LOBYTE(ttOSRecord.sFamilyClass);
            ttOSRecord.fsSelection = SWAPWORD(ttOSRecord.fsSelection); // this is always 32

            lpFontProps->uFamily = ttOSRecord.panose.bFamilyType;
            ttOSRecord.usFirstCharIndex = SWAPWORD(ttOSRecord.usFirstCharIndex);
            bRetVal = TRUE;
            }
            }
            f.Close();
            }
            return bRetVal;
            }