General information
Category:
Windows API functions
>Anyone know of a API to register a new font from a FoxPro app? I would like to have a .TTF file on the network and have the FoxPro app check to see if it is installed on the local machine, if not, install it!
>
>-Tim
its simple
//font.h
#ifndef _FONT_
#define _FONT_
#define F_INSTALLED (-1)
#define F_INSYSTEM (-2)
#define F_READFAILED (-3)
#define F_NAMENOTFOUND (-4)
#define F_NOTTRUETYPE (-5)
#define F_SUCCESS (1)
#endif
=====================================================================
//fontinst.cpp
#include "stdafx.h"
#include
#include
#include
#include
#include
#include "font.h"
// Type definitions and macros
#define tag_NamingTable 0x656d616e // 'name'
// Executable file header information
typedef struct {
WORD wFileSignature; // 0x5A4D
WORD wLengthMod512; // bytes on last page
WORD wLength; // 512 byte pages
WORD wRelocationTableItems;
WORD wHeaderSize; // Paragraphs
WORD wMinAbove; // Paragraphs
WORD wDesiredAbove; // Paragraphs
WORD wStackDisplacement; // Paragraphs
WORD wSP; // On entry
WORD wCheckSum;
WORD wIP; // On entry
WORD wCodeDisplacement; // Paragraphs
WORD wFirstRelocationItem; // Offset from beginning
WORD wOverlayNumber;
WORD wReserved[ 16 ];
LONG lNewExeOffset;
} OLDEXE;
// FontInfo structure located at beginning of a .fnt file
typedef struct {
WORD fontOrdinal;
WORD dfVersion;
DWORD dfSize;
char dfCopyright[60];
WORD dfType;
WORD dfPoints;
WORD dfVertRes;
WORD dfHorizRes;
WORD dfAscent;
WORD dfInternalLeading;
WORD dfExternalLeading;
BYTE dfItalic;
BYTE dfUnderline;
BYTE dfStrikeOut;
WORD dfWeight;
BYTE dfCharSet;
WORD dfPixWidth;
WORD dfPixHeight;
BYTE dfPitchAndFamily;
WORD dfAvgWidth;
WORD dfMaxWidth;
BYTE dfFirstChar;
BYTE dfLastChar;
BYTE dfDefaultChar;
BYTE dfBreakChar;
WORD dfWidthBytes;
DWORD dfDevice;
DWORD dfFace;
DWORD dfReserved;
char dfCharTable[100];
} FONTDIRENTRY;
// New executable file header
typedef struct {
WORD wNewSignature; // 0x454e
char cLinkerVer; // Version number
char cLinkerRev; // Revision number
WORD wEntryOffset; // Offset to Entry Table
WORD wEntrySize; // Number of bytes in Entry Table
long lChecksum; // 32 bit check sum for the file
WORD wFlags; // Flag word
WORD wAutoDataSegment; // Seg number for automatic data seg
WORD wHeapInit; // Initial heap allocation; 0 for no heap
WORD wStackInit; // Initial stack allocation; 0 for libraries
WORD wIPInit; // Initial IP setting
WORD wCSInit; // Initial CS segment number
WORD wSPInit; // Initial SP setting
WORD wSSInit; // Initial SS segment number
WORD wSegEntries; // Count of segment table entries
WORD wModEntries; // Entries in Module Reference Table
WORD wNonResSize; // Size of non-resident name table (bytes)
WORD wSegOffset; // Offset of Segment Table
WORD wResourceOffset; // Offset of Resource Table
WORD wResOffset; // Offset of resident name table
WORD wModOffset; // Offset of Module Reference Table
WORD wImportOffset; // Offset of Imported Names Table
long lNonResOffset; // Offset of Non-resident Names Table
// THIS FIELD IS FROM THE BEGINNING OF THE FILE
// NOT THE BEGINNING OF THE NEW EXE HEADER
WORD wMoveableEntry; // Count of movable entries in entry table
WORD wAlign; // Segment alignment shift count
WORD wResourceSegs; // Count of resource segments
BYTE bExeType; // Operating System flags
BYTE bAdditionalFlags; // Additional exe flags
WORD wFastOffset; // offset to FastLoad area
WORD wFastSize; // length of FastLoad area
WORD wReserved;
WORD wExpVersion; // Expected Windows version number
} NEWEXE, *PNEWEXE;
// Macros for TrueType portability
#define FS_2BYTE(p) (((unsigned short) ((p)[0]) << 8) | (p)[1])
#define FS_4BYTE(p) (FS_2BYTE((p) + 2) | ( (FS_2BYTE(p) + 0L) << 16))
#define SWAPW(a) ((short) FS_2BYTE((unsigned char *) (&a)))
#define SWAPL(a) ((long) FS_4BYTE((unsigned char *) (&a)))
typedef short int16;
typedef unsigned short uint16;
typedef long int32;
typedef unsigned long uint32;
typedef long sfnt_TableTag;
typedef struct {
uint16 platformID;
uint16 specificID;
uint16 languageID;
uint16 nameID;
uint16 length;
uint16 offset;
} sfnt_NameRecord;
typedef struct {
uint16 format;
uint16 count;
uint16 stringOffset;
} sfnt_NamingTable;
typedef struct {
sfnt_TableTag tag;
uint32 checkSum;
uint32 offset;
uint32 length;
} sfnt_DirectoryEntry;
typedef struct {
int32 version; // 0x10000 (1.0)
uint16 numOffsets; // number of tables
uint16 searchRange; // (max2 <= numOffsets) * 16
uint16 entrySelector; // log2 (max2 <= numOffsets)
uint16 rangeShift; // numOffsets * 16 - searchRange
sfnt_DirectoryEntry table[1]; // table[numOffsets]
} sfnt_OffsetTable;
// Function prototypes
extern "C" __declspec(dllexport) long InstallRasterVector(char *pszFile, char *pszTitle);
extern "C" __declspec(dllexport) long InstallTrueType(char *pszFile, char *pszTitle);
extern "C" __declspec(dllexport) BOOL ReadExeDesc(LPSTR lpszFile, LPSTR lpszDesc, LPLOGFONT lf);
extern "C" __declspec(dllexport) LPSTR ReadLongName(LPSTR pszFile);
///////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////
// Function: InstallRasterVector
//
// Purpose: Installs a raster or vector font to the system
//
// Parameters:
// pszFile == Name of file to install including path
// pszTitle == Name of file without path
//
// Returns: Integer value indicating success or failure
//
///////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////
extern "C" __declspec(dllexport) long InstallRasterVector(char *pszFile, char *pszTitle) {
LPSTR lpszName;
char lpszDesc[256],
szTemp[256],
szDst[256],
szName[256];
OFSTRUCT ofStrSrc,
ofStrDest;
HFILE hfSrcFile,
hfDstFile;
BOOL bRaster = TRUE;
LOGFONT lf;
szTemp[0] = '\0';
szDst[0] = '\0';
szName[0] = '\0';
lpszDesc[0] = '\0';
AnsiUpperBuff(pszTitle, lstrlen(pszTitle));
// readthe description table of the .FON font file
if (!(ReadExeDesc(pszFile, lpszDesc, &lf)))
return F_READFAILED;
// Is it a vector font?
if (strstr(lpszDesc, "CONTINUOUSSCALING"))
bRaster = FALSE;
if (!(lpszName = strstr(lpszDesc, ":")))
return F_NAMENOTFOUND;
lstrcpy(szName, lpszName + 2);
if (!bRaster)
lstrcat(szName, " (Plotter)");
// Is this font already installed?
if (GetProfileString("fonts", szName, NULL, szTemp, 256))
return F_INSTALLED;
hfSrcFile = LZOpenFile(pszFile, &ofStrSrc, OF_READ);
GetWindowsDirectory(szDst, 256);
AnsiUpperBuff(szDst, lstrlen(szDst));
lstrcat(szDst, "\\SYSTEM\\");
lstrcat(szDst, pszTitle);
/* Create the destination file. */
hfDstFile = LZOpenFile(szDst, &ofStrDest, OF_CREATE);
// Make sure it isn't already in the system directory
if (lstrcmp(szDst, pszFile) == 0) {
// Close the files.
LZClose(hfSrcFile);
LZClose(hfDstFile);
return F_INSYSTEM;
}
else {
// Copy the source file to the destination file.
LZCopy(hfSrcFile, hfDstFile);
// Close the files.
LZClose(hfSrcFile);
LZClose(hfDstFile);
// Add it to the system
AddFontResource(szDst);
// Tell everyone else what you have done
SendMessage(HWND_BROADCAST, WM_FONTCHANGE, 0, 0);
WriteProfileString("fonts", szName, pszTitle);
SendMessage(HWND_BROADCAST, WM_WININICHANGE, 0, (LPARAM) (LPCSTR) "fonts");
return F_SUCCESS;
}
return 0;
}
///////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////
// Function: InstallTrueType
//
// Purpose: Installs a TrueType font to the system
//
// Parameters:
// pszFile == Name of file to install including path
// pszTitle == Name of file without path
//
// Returns: long value indicating success or failure
//
///////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////
extern "C" __declspec(dllexport) long InstallTrueType(char *pszFile, char *pszTitle) {
LPSTR lpszLongName;
static char szDst[256],
szFileName[256],
szDstFot[256],
szDstName[256],
szTemp[256];
OFSTRUCT ofStrSrc,
ofStrDest;
HFILE hfSrcFile,
hfDstFile;
szDst[0] = '\0';
szFileName[0] = '\0';
szDstFot[0] = '\0';
szDstName[0] = '\0';
szTemp[0] = '\0';
AnsiUpperBuff(pszTitle, lstrlen(pszTitle));
// Find the facename of the font file
if (lpszLongName = ReadLongName(pszFile)) {
hfSrcFile = LZOpenFile(pszFile, &ofStrSrc, OF_READ);
GetWindowsDirectory(szDst, 256);
AnsiUpperBuff(szDst, lstrlen(szDst));
lstrcat(szDst, "\\SYSTEM\\");
lstrcat(szDst, pszTitle);
// Create the destination file.
hfDstFile = LZOpenFile(szDst, &ofStrDest, OF_CREATE);
if (lstrcmp(szDst, pszFile) == 0) {
// Close the files.
LZClose(hfSrcFile);
LZClose(hfDstFile);
return F_INSYSTEM;
}
// Copy the source file to the destination file.
LZCopy(hfSrcFile, hfDstFile);
// Close the files.
LZClose(hfSrcFile);
LZClose(hfDstFile);
lstrcpy(szDstFot, szDst);
szDstFot[lstrlen(szDst)-3] = NULL;
lstrcat(szDstFot, "FOT");
// Create a .FOT file for the .TTF file
CreateScalableFontResource(0, szDstFot, szDst, NULL);
AddFontResource(szDstFot);
SendMessage(HWND_BROADCAST, WM_FONTCHANGE, 0, 0);
lstrcpy(szDstName, lpszLongName);
lstrcpy(szFileName, pszTitle);
szFileName[lstrlen(szFileName)-3] = NULL;
lstrcat(szFileName, "FOT");
lstrcat(szDstName, " (TrueType)");
// Is it already installed?
if (GetProfileString("fonts", szDstName, NULL, szTemp, 256))
return F_INSTALLED;
WriteProfileString("fonts", szDstName, szFileName);
SendMessage(HWND_BROADCAST, WM_WININICHANGE, 0, (LPARAM) (LPCSTR) "fonts");
return F_SUCCESS;
}
return F_NOTTRUETYPE;
}
///////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////
// Function: ReadExeDesc
//
// Purpose: Reads the "Description" statement in the .EXE file header.
//
// Parameters:
// lpszFile == Name of file to readincluding path
// lpszTitle == "Description" of file to be filled by function
//
// Returns: Boolean value indicating success or failure
//
///////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////
extern "C" __declspec(dllexport) BOOL ReadExeDesc(LPSTR lpszFile, LPSTR lpszDesc, LPLOGFONT lf) {
OFSTRUCT of;
int fFile = 0;
OLDEXE OldExe;
NEWEXE NewExe;
long lNonResTable;
WORD wNonResSize;
FONTDIRENTRY *fdEntry;
HRSRC hResource;
HINSTANCE hModule;
fFile = OpenFile(lpszFile, &of, OF_READ);
if (!fFile)
return NULL;
_lread(fFile, (LPSTR) &(OldExe), sizeof(OLDEXE));
_llseek(fFile, OldExe.lNewExeOffset, 0 );
_lread(fFile, (LPSTR) &(NewExe), sizeof(NEWEXE));
lNonResTable = NewExe.lNonResOffset;
_llseek(fFile, lNonResTable, 0);
wNonResSize = 0;
// readstring size
_lread(fFile, (LPSTR) &wNonResSize, 1);
_lread(fFile, (LPSTR) lpszDesc, wNonResSize);
_lclose( fFile );
lpszDesc[wNonResSize] = '\0';
if (lpszDesc[0] == '\0')
return FALSE;
if ((hModule = LoadLibrary(lpszFile)) == NULL)
return FALSE;
// readFont Directory
if ((hResource = FindResource(hModule, "fontdir", RT_FONTDIR)) == NULL)
return FALSE;
if(LoadResource(hModule, hResource) == NULL)
return FALSE;
if (fdEntry = (FONTDIRENTRY *) LockResource(hResource)) {
LPSTR lpstr = (LPSTR)fdEntry->dfCharTable;
LPSTR FaceName;
while (*lpstr == '\0')
lpstr++;
FaceName = lpstr;
lstrcpy(lf->lfFaceName, FaceName);
lf->lfWeight = fdEntry->dfWeight;
lf->lfItalic = fdEntry->dfItalic;
lf->lfUnderline = fdEntry->dfUnderline;
lf->lfStrikeOut = fdEntry->dfStrikeOut;
lf->lfCharSet = fdEntry->dfCharSet;
// convert dfPitchAndFamily to lfPitchAndFamily
lf->lfPitchAndFamily = (fdEntry->dfPitchAndFamily & 0xF1) + 1;
UnlockResource(hResource);
FreeResource(hResource);
FreeLibrary(hModule);
return TRUE;
}
else
return FALSE;
}
///////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////
// Function: ReadLongName
//
// Purpose: Reads the Face Name of a TrueType font.
//
// Parameters:
// pszFile == Name of file to readincluding path
//
// Returns: Face name of the font in the .TTF file
//
///////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////
extern "C" __declspec(dllexport) LPSTR ReadLongName(LPSTR pszFile) {
static char lpszLongName[256];
unsigned i;
char namebuf[255];
int fp;
unsigned short numNames;
long curseek;
unsigned cTables;
sfnt_OffsetTable OffsetTable;
sfnt_DirectoryEntry Table;
sfnt_NamingTable NamingTable;
sfnt_NameRecord NameRecord;
lpszLongName[0] = '\0';
if ((fp = open (pszFile, O_RDONLY | O_BINARY)) == -1)
return NULL;
// First off, readthe initial directory header on the TTF. We're only
// interested in the "numOffsets" variable to tell us how many tables
// are present in this file.
//
// Remember to always convert from Motorola format (Big Endian to
// Little Endian).
read(fp, &OffsetTable, sizeof (OffsetTable) - sizeof (sfnt_DirectoryEntry));
cTables = (int) SWAPW (OffsetTable.numOffsets);
for (i = 0; i < cTables && i < 40; i++) {
if ((read(fp, &Table, sizeof(Table))) != sizeof(Table))
return NULL;
if (Table.tag == tag_NamingTable) { /* defined in sfnt_en.h */
// Now that we've found the entry for the name table, seek to that
// position in the file and readin the initial header for this
// particular table. See "True Type Font Files" for information
// on this record layout.
lseek(fp, SWAPL (Table.offset), SEEK_SET);
read(fp, &NamingTable, sizeof(NamingTable));
numNames = SWAPW(NamingTable.count);
while (numNames--) {
read(fp, &NameRecord, sizeof(NameRecord));
curseek = tell(fp);
if (SWAPW(NameRecord.platformID) == 1 &&
SWAPW(NameRecord.nameID) == 4) {
lseek(fp, SWAPW (NameRecord.offset) +
SWAPW(NamingTable.stringOffset) +
SWAPL(Table.offset), SEEK_SET);
read(fp, &namebuf, SWAPW(NameRecord.length));
namebuf[SWAPW(NameRecord.length)] = '\0';
lstrcpy(lpszLongName, namebuf);
lseek(fp, curseek, SEEK_SET);
}
}
close(fp);
return lpszLongName;
}
}
close(fp);
return FALSE;
}
Previous
Next
Reply
View the map of this thread
View the map of this thread starting from this message only
View all messages of this thread
View all messages of this thread starting from this message only