Click here to Skip to main content
15,886,518 members
Articles / Multimedia / GDI+

How to Use a Font Without Installing it

Rate me:
Please Sign up or sign in to vote.
4.93/5 (58 votes)
12 Apr 2016CPOL7 min read 200.6K   7.5K   185  
How to use a font without installing it first on user systems
/*
Font Name Library 1.0.0

Copyright (c) 2009 Wong Shao Voon

The Code Project Open License (CPOL)
http://www.codeproject.com/info/cpol10.aspx
*/

#pragma once

#include <string>
#include <vector>
#include <cstdio>
#include "EndianSwap.h"
#include "MemPtrReader.h"

class TTF
{
public:
	//! default constructor
	TTF(void);
	//! destructor
	~TTF(void);

	struct stOffsetTable
	{
		UINT	version;
		USHORT	numTables;
		USHORT	searchRange;
		USHORT	entrySelector;
		USHORT	rangeShift;
	};

	struct stTableDirectory
	{
		CHAR	tag[4];
		ULONG	checkSum;
		ULONG	offset;
		ULONG	length;
	};
	
	struct stNamingTable
	{
		USHORT	FormatSelector;
		USHORT	NumberOfNameRecords;
		USHORT	OffsetStartOfStringStorage;
	};

	struct stNameRecord
	{
		USHORT	PlatformID;
		USHORT	EncodingID;
		USHORT	LanguageID;
		USHORT	NameID;
		USHORT	StringLength;
		USHORT	OffsetFromStorageArea;
	};

	//! Parse file for font information
	bool Parse(const std::wstring& szFilePath);

	//! Meant to be used by TTC class only
	bool Parse(FILE* pFile, size_t nOffsetFromStart);

	//! Parse the memory buffer for font information
	//!
	//! @param[in]	pFile is the buffer pointer
	//! @param[in]	size is the size of the buffer
	//! @return true for success
	bool Parse(BYTE* pFile, size_t size);

	//! Parse the memory buffer for font information
	//!
	//! @param[in]	pFile is the buffer pointer
	//! @param[in]	size is the size of the buffer
	//! @param[in]	offset is the offset of pFile from the starting byte
	//! @return true for success
	bool Parse(BYTE* pFile, size_t size, size_t offset);

	//! Clear all information
	void Clear();

	std::wstring GetFontName() {return m_szFontName;};
	std::wstring GetCopyright() {return m_szCopyright;};
	std::wstring GetFontFamilyName() {return m_szFontFamilyName;};
	std::wstring GetFontSubFamilyName() {return m_szFontSubFamilyName;};
	std::wstring GetFontID() {return m_szFontID;};
	std::wstring GetVersion() {return m_szVersion;};
	std::wstring GetPostScriptName() {return m_szPostScriptName;};
	std::wstring GetTrademark() {return m_szTrademark;};

	bool IsBold();
	bool IsItalic();
	bool IsRegular();

	//! Converts a wide character string to narrow character string
	static std::string WideToNarrow(const std::wstring& szWide);
	//! Converts a narrow character string to wide character string
	static std::wstring NarrowToWide(const std::string& szNarrow);

private:
	//! Parse the OffsetTable
	bool ParseOffsetTable();
	//! Parse the OffsetTable in memory
	bool ParseOffsetTableMem();
	//! Parse the Naming tables for names
	bool ParseName(stTableDirectory& TableDirectory);
	//! Parse the Naming tables for names in memory buffer
	bool ParseNameMem(stTableDirectory& TableDirectory);
	//! Parse for the bold, italic or regular font properties
	void ParseStyles();


	//! Get the descriptive name for the numeric name id
	std::wstring GetNameID(USHORT uNameID);

	//! Set the (wide string) value to the name id
	void SetNameIDValue(USHORT uNameID, const std::wstring& str);
	//! Set the (narrow string) value to the name id
	void SetNameIDValue(USHORT uNameID, const std::string& str);

	//! Convert all wide characters to lower case
	std::wstring ToLower(const std::wstring& szNormal);
	//! Convert all narrow characters to lower case
	std::string ToLower(const std::string& szNormal);

	//! File pointer
	std::FILE* m_pFile;
	//! The font file
	std::wstring m_szFilePath;
	//! Font name
	std::wstring m_szFontName;
	//! Copyright
	std::wstring m_szCopyright;
	//! Font family name
	std::wstring m_szFontFamilyName;
	//! States whether the font is bold, italics or regular
	std::wstring m_szFontSubFamilyName;
	//! Font ID
	std::wstring m_szFontID;
	//! Font version text
	std::wstring m_szVersion;
	//! Font Postscript name
	std::wstring m_szPostScriptName;
	//! Trademark
	std::wstring m_szTrademark;
	//! Masked Flags to indicate if the vital information is filled
	BYTE m_nInfo;
	//! Indicates if the file pointer is passed in from caller
	bool m_bExternalFilePtr;
	//! Memory buffer reader
	MemPtrReader* m_pMemPtrReader;
	//! IsBold?
	bool m_bBold;
	//! IsRegular?
	bool m_bRegular;
	//! IsItalic?
	bool m_bItalic;
};

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Software Developer (Senior)
Singapore Singapore
Shao Voon is from Singapore. His interest lies primarily in computer graphics, software optimization, concurrency, security, and Agile methodologies.

In recent years, he shifted focus to software safety research. His hobby is writing a free C++ DirectX photo slideshow application which can be viewed here.

Comments and Discussions