Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations Mike Lewis on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Font filename converting code.

Status
Not open for further replies.

Tremorblue

Programmer
Apr 30, 2004
56
0
0
GB
I am trying to convert the following code (freely available on the net) into C++ Builder..
Its used to find the Name of a ttf font file. I have posted my attempt at the end ( I nearly have it done).

The code I am stuck on converting is this.
csTemp.ReleaseBuffer();
if(csTemp.GetLength() > 0)
{
csRetVal = csTemp;
break;
}

I can see the font file name is being read into lpszNameBuf when I debug.
Sometimes its ascii and sometimes unicode.
I tried using WideStringToChar and others to convert the unicode into normal ascii but never seems to work.
Can anyone help ?

--------------------------------------------------------
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_NAME_TABLE_HEADER{
USHORT uFSelector; //format selector. Always 0
USHORT uNRCount; //Name Records count
USHORT uStorageOffset; //Offset for strings storage, from start of the table
}TT_NAME_TABLE_HEADER;

typedef struct _tagTT_NAME_RECORD{
USHORT uPlatformID;
USHORT uEncodingID;
USHORT uLanguageID;
USHORT uNameID;
USHORT uStringLength;
USHORT uStringOffset; //from start of storage area
}TT_NAME_RECORD;

#define SWAPWORD(x) MAKEWORD(HIBYTE(x), LOBYTE(x))
#define SWAPLONG(x) MAKELONG(SWAPWORD(HIWORD(x)), SWAPWORD(LOWORD(x)))


CString GetFontNameFromFile(LPCTSTR lpszFilePath)
{
CFile f;
CString csRetVal;

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 csRetVal;

TT_TABLE_DIRECTORY tblDir;
BOOL bFound = 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("name")) == 0){
bFound = TRUE;
tblDir.uLength = SWAPLONG(tblDir.uLength);
tblDir.uOffset = SWAPLONG(tblDir.uOffset);
break;
}
}

if(bFound){
f.Seek(tblDir.uOffset, CFile::begin);
TT_NAME_TABLE_HEADER ttNTHeader;
f.Read(&ttNTHeader, sizeof(TT_NAME_TABLE_HEADER));
ttNTHeader.uNRCount = SWAPWORD(ttNTHeader.uNRCount);
ttNTHeader.uStorageOffset = SWAPWORD(ttNTHeader.uStorageOffset);
TT_NAME_RECORD ttRecord;
bFound = FALSE;

for(int i=0; i<ttNTHeader.uNRCount; i++){
f.Read(&ttRecord, sizeof(TT_NAME_RECORD));
ttRecord.uNameID = SWAPWORD(ttRecord.uNameID);
if(ttRecord.uNameID == 1){
ttRecord.uStringLength = SWAPWORD(ttRecord.uStringLength);
ttRecord.uStringOffset = SWAPWORD(ttRecord.uStringOffset);
int nPos = f.GetPosition();
f.Seek(tblDir.uOffset + ttRecord.uStringOffset + ttNTHeader.uStorageOffset, CFile::begin);

//bug fix: see the post by SimonSays to read more about it
TCHAR lpszNameBuf = csTemp.GetBuffer(ttRecord.uStringLength + 1);
ZeroMemory(lpszNameBuf, ttRecord.uStringLength + 1);
f.Read(lpszNameBuf, ttRecord.uStringLength);
csTemp.ReleaseBuffer();
if(csTemp.GetLength() > 0){
csRetVal = csTemp;
break;
}
f.Seek(nPos, CFile::begin);
}
}
}
f.Close();
}
return csRetVal;
}


This is my code...

//---------------------------------------------------------------------------
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_NAME_TABLE_HEADER{
USHORT uFSelector; //format selector. Always 0
USHORT uNRCount; //Name Records count
USHORT uStorageOffset; //Offset for strings storage, from start of the table
}TT_NAME_TABLE_HEADER;

typedef struct _tagTT_NAME_RECORD{
USHORT uPlatformID;
USHORT uEncodingID;
USHORT uLanguageID;
USHORT uNameID;
USHORT uStringLength;
USHORT uStringOffset; //from start of storage area
}TT_NAME_RECORD;

#define SWAPWORD(x) MAKEWORD(HIBYTE(x), LOBYTE(x))
#define SWAPLONG(x) MAKELONG(SWAPWORD(HIWORD(x)), SWAPWORD(LOWORD(x)))

AnsiString GetFontNameFromFile(char *sFileName)
{
AnsiString aTemp;
if(FileExists(sFileName))
{
int iFileHandle = FileOpen(sFileName, fmOpenRead);
int iFileLength = FileSeek(iFileHandle,0,2);
FileSeek(iFileHandle,0,0);
TT_OFFSET_TABLE ttOffsetTable;
FileRead(iFileHandle, &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 "";

TT_TABLE_DIRECTORY tblDir;
BOOL bFound = FALSE;
char csTemp[sizeof(TT_TABLE_DIRECTORY)+1];

for(int i=0; i< ttOffsetTable.uNumOfTables; i++){
FileRead(iFileHandle,&tblDir, sizeof(TT_TABLE_DIRECTORY));
strncpy(csTemp, tblDir.szTag, 4);
if(strncmp(csTemp,"name",4)== 0)
{
bFound = TRUE;
tblDir.uLength = SWAPLONG(tblDir.uLength);
tblDir.uOffset = SWAPLONG(tblDir.uOffset);
break;
}
}

if(bFound){
FileSeek(iFileHandle,(int)tblDir.uOffset,0);
TT_NAME_TABLE_HEADER ttNTHeader;
FileRead(iFileHandle,&ttNTHeader, sizeof(TT_NAME_TABLE_HEADER));
ttNTHeader.uNRCount = SWAPWORD(ttNTHeader.uNRCount);
ttNTHeader.uStorageOffset = SWAPWORD(ttNTHeader.uStorageOffset);
TT_NAME_RECORD ttRecord;
bFound = FALSE;

for(int i=0; i<ttNTHeader.uNRCount; i++){
FileRead(iFileHandle,&ttRecord, sizeof(TT_NAME_RECORD));
ttRecord.uNameID = SWAPWORD(ttRecord.uNameID);
if(ttRecord.uNameID == 1){
ttRecord.uStringLength = SWAPWORD(ttRecord.uStringLength);
ttRecord.uStringOffset = SWAPWORD(ttRecord.uStringOffset);
int nPos = FileSeek(iFileHandle,1,0);
FileSeek(iFileHandle,(int)(tblDir.uOffset + ttRecord.uStringOffset + ttNTHeader.uStorageOffset),0);
TCHAR lpszNameBuf[100];
ZeroMemory(lpszNameBuf,ttRecord.uStringLength+1);
FileRead(iFileHandle,lpszNameBuf,ttRecord.uStringLength);

// What goes here ???

FileSeek(iFileHandle,nPos,0);
}
}
}
FileClose(iFileHandle);
}
return aTemp;
}

Thanks TBlue
 
Look at thread101-49144 and thread101-989298 and see if they can help.

James P. Cottingham
-----------------------------------------
[sup]I'm number 1,229!
I'm number 1,229![/sup]
 
For completeness heres the code that works...

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_NAME_TABLE_HEADER{
USHORT uFSelector; //format selector. Always 0
USHORT uNRCount; //Name Records count
USHORT uStorageOffset; //Offset for strings storage, from start of the table
}TT_NAME_TABLE_HEADER;

typedef struct _tagTT_NAME_RECORD{
USHORT uPlatformID;
USHORT uEncodingID;
USHORT uLanguageID;
USHORT uNameID;
USHORT uStringLength;
USHORT uStringOffset; //from start of storage area
}TT_NAME_RECORD;

#define SWAPWORD(x) MAKEWORD(HIBYTE(x), LOBYTE(x))
#define SWAPLONG(x) MAKELONG(SWAPWORD(HIWORD(x)), SWAPWORD(LOWORD(x)))


AnsiString unicode2ascii(TCHAR* buf,int len){
AnsiString temp;
int i=0;
while(i<len){
if(buf!='\0')
temp+=buf;
i++;
}
return temp;
}


AnsiString GetFontNameFromFile(char *sFileName)
{
AnsiString aTemp;
if(FileExists(sFileName))
{
int iFileHandle = FileOpen(sFileName, fmOpenRead);
int iFileLength = FileSeek(iFileHandle,0,2);
FileSeek(iFileHandle,0,0);
TT_OFFSET_TABLE ttOffsetTable;
FileRead(iFileHandle, &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 "";

TT_TABLE_DIRECTORY tblDir;
BOOL bFound = FALSE;
char csTemp[sizeof(TT_TABLE_DIRECTORY)+1];

for(int i=0; i< ttOffsetTable.uNumOfTables; i++)
{
FileRead(iFileHandle,&tblDir, sizeof(TT_TABLE_DIRECTORY));
strncpy(csTemp, tblDir.szTag, 4);
if(strncmp(csTemp,"name",4)== 0)
{
bFound = TRUE;
tblDir.uLength = SWAPLONG(tblDir.uLength);
tblDir.uOffset = SWAPLONG(tblDir.uOffset);
break;
}
}

if(bFound){
FileSeek(iFileHandle,(int)tblDir.uOffset,0);
TT_NAME_TABLE_HEADER ttNTHeader;
FileRead(iFileHandle,&ttNTHeader, sizeof(TT_NAME_TABLE_HEADER));
ttNTHeader.uNRCount = SWAPWORD(ttNTHeader.uNRCount);
ttNTHeader.uStorageOffset = SWAPWORD(ttNTHeader.uStorageOffset);
TT_NAME_RECORD ttRecord;
bFound = FALSE;

for(int i=0; i<ttNTHeader.uNRCount; i++)
{
FileRead(iFileHandle,&ttRecord, sizeof(TT_NAME_RECORD));
ttRecord.uNameID = SWAPWORD(ttRecord.uNameID);
if(ttRecord.uNameID == 1)
{
ttRecord.uStringLength = SWAPWORD(ttRecord.uStringLength);
ttRecord.uStringOffset = SWAPWORD(ttRecord.uStringOffset);
int nPos = FileSeek(iFileHandle,1,0);
FileSeek(iFileHandle,(int)(tblDir.uOffset + ttRecord.uStringOffset + ttNTHeader.uStorageOffset),0);
TCHAR lpszNameBuf[50];
ZeroMemory(lpszNameBuf,ttRecord.uStringLength+1);
FileRead(iFileHandle,lpszNameBuf,ttRecord.uStringLength);
aTemp= unicode2ascii(lpszNameBuf,ttRecord.uStringLength);
break;
}
}
}
FileClose(iFileHandle);
}
return aTemp;
}
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top