You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
347 lines
9.4 KiB
347 lines
9.4 KiB
/**************************************************************************\
|
|
*
|
|
* Copyright (c) 1999 Microsoft Corporation
|
|
*
|
|
* Abstract:
|
|
*
|
|
* Font family
|
|
*
|
|
* Revision History:
|
|
*
|
|
* 27/06/1999 cameronb
|
|
* Created it.
|
|
*
|
|
\**************************************************************************/
|
|
|
|
#ifndef _GDIPLUSFONTFAMILY_H
|
|
#define _GDIPLUSFONTFAMILY_H
|
|
|
|
#define NumFontFaces 4
|
|
|
|
#define PFF_ENUMERABLE 0x1
|
|
|
|
#include "fontable.hpp"
|
|
|
|
class GpFontFace;
|
|
class FontFamily;
|
|
|
|
class GpFamilyFallback;
|
|
|
|
const UINT FamilyNameMax = 32;
|
|
|
|
typedef struct _FAMILYCACHEENTRY
|
|
{
|
|
UINT cjThis;
|
|
// Cache the data from here
|
|
INT iFont;
|
|
|
|
// Cache engine supprt
|
|
UINT cFilePathName[NumFontFaces];
|
|
|
|
WCHAR Name[FamilyNameMax]; // Captialized Family name
|
|
WCHAR NormalName[FamilyNameMax]; // Family name
|
|
|
|
// Alias name
|
|
WCHAR FamilyAliasName[FamilyNameMax]; // Captialized FamilyAliasName
|
|
WCHAR NormalFamilyAliasName[FamilyNameMax]; // FamilyAliasName
|
|
|
|
BOOL bAlias;
|
|
|
|
// Lang ID for Family name and FamilyAliasName
|
|
|
|
LANGID LangID;
|
|
LANGID AliasLnagID;
|
|
|
|
ULARGE_INTEGER LastWriteTime[NumFontFaces];
|
|
|
|
// We need to get a charset to let font select into DC
|
|
BYTE lfCharset;
|
|
} FAMILYCACHEENTRY;
|
|
|
|
struct FallbackFactory
|
|
{
|
|
GpStatus Create(const GpFontFamily *family);
|
|
void Destroy();
|
|
GpFamilyFallback *familyfallback;
|
|
};
|
|
|
|
|
|
/*********************************Class************************************\
|
|
* class GpFontFamily
|
|
*
|
|
* Font family consisiting of pointers to the following font styles:
|
|
* (1) regular
|
|
* (2) italic
|
|
* (3) bold
|
|
* (4) bold italic
|
|
*
|
|
* History:
|
|
*
|
|
* 27/06/1999 cameronb created it
|
|
*
|
|
\**************************************************************************/
|
|
|
|
class GpFontFamily
|
|
{
|
|
private:
|
|
// We now use an ObjectTag to determine if the object is valid
|
|
// instead of using a BOOL. This is much more robust and helps
|
|
// with debugging. It also enables us to version our objects
|
|
// more easily with a version number in the ObjectTag.
|
|
ObjectTag Tag; // Keep this as the 1st value in the object!
|
|
|
|
protected:
|
|
VOID SetValid(BOOL valid)
|
|
{
|
|
Tag = valid ? ObjectTagFontFamily : ObjectTagInvalid;
|
|
}
|
|
|
|
// This method is here so that we have a virtual function table so
|
|
// that we can add virtual methods in V2 without shifting the position
|
|
// of the Tag value within the data structure.
|
|
virtual VOID DontCallThis()
|
|
{
|
|
DontCallThis();
|
|
}
|
|
|
|
public:
|
|
GpFontFamily(const WCHAR *name, GpFontFile * fontfile, INT iFont, FAMILYCACHEENTRY * pCacheEntry, GpFontCollection *fontCollection = NULL);
|
|
|
|
GpFontFamily(FAMILYCACHEENTRY * pCacheEntry);
|
|
|
|
~GpFontFamily();
|
|
|
|
// If the famly came from a different version of GDI+, its tag
|
|
// will not match, and it won't be considered valid.
|
|
BOOL IsValid() const
|
|
{
|
|
#ifdef _X86_
|
|
// We have to guarantee that the Tag field doesn't move for
|
|
// versioning to work between releases of GDI+.
|
|
ASSERT(offsetof(GpFontFamily, Tag) == 4);
|
|
#endif
|
|
|
|
ASSERT((Tag == ObjectTagFontFamily) || (Tag == ObjectTagInvalid));
|
|
#if DBG
|
|
if (Tag == ObjectTagInvalid)
|
|
{
|
|
WARNING1("Invalid Font Family");
|
|
}
|
|
#endif
|
|
|
|
return (Tag == ObjectTagFontFamily);
|
|
}
|
|
|
|
// Name has been captialized
|
|
const WCHAR *GetCaptializedName() {return cacheEntry->Name;}
|
|
|
|
// The original name is not capitalized
|
|
GpStatus GetFamilyName(WCHAR name[LF_FACESIZE], LANGID language = MAKELANGID(LANG_NEUTRAL, SUBLANG_NEUTRAL)) const;
|
|
|
|
void SetFaceAndFile(INT style, GpFontFace *face, GpFontFile * fontfile);
|
|
|
|
GpFontFace *GetFace(INT style) const;
|
|
|
|
GpFontFace *GetFaceAbsolute(INT style) const;
|
|
|
|
BOOL GpFontFamily::IsFileLoaded(BOOL loadFontFile = TRUE) const;
|
|
|
|
GpFontFile * GetFontFile(UINT i) { return FontFile[i]; }
|
|
|
|
GpFontCollection *GetFontCollection ()
|
|
{
|
|
return associatedFontCollection;
|
|
}
|
|
|
|
BOOL FaceExist(INT style) const
|
|
{
|
|
// Return face for the given style - either the direct face
|
|
// or one which can support this style through simulation.
|
|
|
|
if (Face[style&3])
|
|
{
|
|
// Distinct font exists
|
|
return TRUE;
|
|
}
|
|
else
|
|
{
|
|
return FALSE;
|
|
}
|
|
}
|
|
|
|
GpFamilyFallback *GetFamilyFallback() const
|
|
{
|
|
if (!FamilyFallbackInitialized)
|
|
{
|
|
if (fallback.Create(this) != Ok)
|
|
return NULL;
|
|
|
|
FamilyFallbackInitialized = TRUE;
|
|
}
|
|
|
|
return fallback.familyfallback;
|
|
}
|
|
|
|
BOOL IsPrivate() const;
|
|
|
|
INT AvailableFaces(void) const;
|
|
|
|
BOOL SupportsLanguage (INT style, LANGID lang) const;
|
|
BOOL SupportsCharacters(INT style, WCHAR* str, INT len) const;
|
|
|
|
BOOL IsStyleAvailable (INT style) const {return GetFace(style) != NULL;}
|
|
|
|
UINT16 GetDesignEmHeight (INT style) const;
|
|
UINT16 GetDesignCellAscent (INT style) const;
|
|
UINT16 GetDesignCellDescent (INT style) const;
|
|
UINT16 GetDesignLineSpacing (INT style) const;
|
|
UINT16 GetDesignUnderscoreSize (INT style) const;
|
|
INT16 GetDesignUnderscorePosition (INT style) const;
|
|
UINT16 GetDesignStrikeoutSize (INT style) const;
|
|
INT16 GetDesignStrikeoutPosition (INT style) const;
|
|
|
|
|
|
GpStatus GetFontData(FontStyle style, UINT32 tag, INT* tableSize, BYTE** pjTable);
|
|
void ReleaseFontData(FontStyle style);
|
|
|
|
BOOL Deletable(); /* the font family can be removed from the font family list */
|
|
BOOL IncFontFamilyRef(void); /* return false if all the faces are removed */
|
|
void DecFontFamilyRef(void);
|
|
|
|
// API support for Family Alias name
|
|
BOOL IsAliasName() const
|
|
{
|
|
return cacheEntry->bAlias;
|
|
}
|
|
|
|
WCHAR * GetAliasName()
|
|
{
|
|
return cacheEntry->bAlias ? cacheEntry->FamilyAliasName : NULL;
|
|
}
|
|
|
|
FAMILYCACHEENTRY * GetCacheEntry()
|
|
{
|
|
return cacheEntry;
|
|
}
|
|
|
|
VOID ReleaseCacheEntry()
|
|
{
|
|
|
|
ASSERT(cacheEntry);
|
|
|
|
if (!bLoadFromCache && cacheEntry)
|
|
{
|
|
GpFree(cacheEntry);
|
|
cacheEntry = NULL;
|
|
}
|
|
}
|
|
|
|
static GpStatus CreateFontFamilyFromName
|
|
(const WCHAR *name,
|
|
GpFontCollection *fontCollection,
|
|
GpFontFamily **fontFamily);
|
|
|
|
static GpStatus GetGenericFontFamilySansSerif
|
|
(GpFontFamily **nativeFamily);
|
|
|
|
static GpStatus GetGenericFontFamilySerif
|
|
(GpFontFamily **nativeFamily);
|
|
|
|
static GpStatus GetGenericFontFamilyMonospace
|
|
(GpFontFamily **nativeFamily);
|
|
|
|
// private member function
|
|
private:
|
|
BOOL AreAllFacesRemoved();
|
|
BOOL WriteToCache();
|
|
BOOL ReadFromCache();
|
|
|
|
// private data
|
|
private:
|
|
FAMILYCACHEENTRY * cacheEntry;
|
|
|
|
// Indicate
|
|
mutable BOOL bFontFileLoaded;
|
|
|
|
// Ref count for FontFamily objects that point to this GpFontFamily
|
|
INT cFontFamilyRef;
|
|
|
|
// GpFontFace
|
|
mutable GpFontFace *Face[NumFontFaces]; // Pointers to instance of each face
|
|
|
|
// GpFontFile
|
|
mutable GpFontFile *FontFile[NumFontFaces]; // Pointer to font file
|
|
|
|
|
|
mutable FallbackFactory fallback;
|
|
mutable BOOL FamilyFallbackInitialized;
|
|
BOOL bLoadFromCache;
|
|
|
|
GpFontCollection * associatedFontCollection; // if NULL, then GpInstalledFontCollection
|
|
};
|
|
|
|
|
|
/*********************************Class************************************\
|
|
* class GpFontFamilyList
|
|
*
|
|
* Handles the enumerated list of font families
|
|
*
|
|
* History:
|
|
*
|
|
* 27/06/1999 cameronb created it
|
|
*
|
|
\**************************************************************************/
|
|
|
|
class GpFontFamilyList
|
|
{
|
|
public:
|
|
|
|
// Internal structure for list handling
|
|
struct FamilyNode
|
|
{
|
|
GpFontFamily *Item;
|
|
FamilyNode *Prev;
|
|
FamilyNode *Next;
|
|
|
|
FamilyNode(GpFontFamily *family=NULL)
|
|
{
|
|
Item = family;
|
|
Prev = NULL;
|
|
Next = NULL;
|
|
}
|
|
|
|
};
|
|
|
|
public:
|
|
GpFontFamilyList();
|
|
~GpFontFamilyList();
|
|
|
|
private:
|
|
void DeleteList(void);
|
|
|
|
public:
|
|
INT Enumerable(GpGraphics* graphics = 0) const;
|
|
Status Enumerate(INT numSought, GpFontFamily * gpfamilies[], INT& numFound,
|
|
GpGraphics * graphics = 0) const;
|
|
|
|
GpFontFamily* GetFamily(const WCHAR *familyName) const;
|
|
GpFontFamily* GetAnyFamily() const;
|
|
|
|
BOOL AddFont(GpFontFile* fontFile, GpFontCollection *fontCollection);
|
|
BOOL RemoveFontFamily(GpFontFamily* fontFamily);
|
|
VOID UpdateFamilyListToCache(BOOL bLoadFromRegistry, HKEY hkey, ULONG registrySize, ULONG numExpected);
|
|
BOOL BuildFamilyListFromCache(BOOL bLoadFromRegistry);
|
|
|
|
private:
|
|
BOOL InsertOrdered(GpFontFamily * family, FontStyle style, GpFontFile * fontfile,
|
|
GpFontFace * face, BOOL bSetFace);
|
|
|
|
// Data members
|
|
private:
|
|
FamilyNode* Head; // The enumerated list
|
|
BYTE * FamilyCacheEntry;
|
|
|
|
};
|
|
|
|
|
|
#endif
|