Leaked source code of windows server 2003
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.
 
 
 
 
 
 

552 lines
16 KiB

#ifndef _FACEREALIZATION_
#define _FACEREALIZATION_
#define GLYPHDATABLOCKCOUNT 16
#define MAXRECENTLYUSEDCOUNT 32
#define EMPTY_GLYPH_FFFF 0xFFFF // Display nothing, neither ink nor width.
// Typedefs for cached funtion pointers in GpFaceRealization.
class GpFaceRealization;
/* used in aatext.cxx and facerealization.cpp : */
#define CJ_CTGD(cx,cy) (ALIGN4(offsetof(GLYPHBITS,aj)) + ALIGN4((cx) * (cy)))
#define ALIGN4(X) (((X) + 3) & ~3)
#define ALIGN(object, p) p = (p + ((UINT)sizeof(object) - 1)) & ~((UINT)sizeof(object) - 1);
inline BOOL IsGridFittedTextRealizationMethod(TextRenderingHint method)
{
switch (method)
{
case TextRenderingHintSingleBitPerPixelGridFit:
case TextRenderingHintAntiAliasGridFit:
case TextRenderingHintClearTypeGridFit:
return TRUE;
default:
return FALSE;
}
}
///// GpGlyphMetrics
//
// Metrics for text handling and glyph placement.
// There are separate records for horizontal and vertical baselines.
struct GpGlyphMetrics {
// Metrics along baseline in 28.4
INT AdvanceWidth;
INT LeadingSidebearing;
INT TrailingSidebearing;
PointF Origin; // Float
};
struct GpGlyphAABits
{
GpGlyphAABits * Next;
ULONG X, Y;
BYTE Bits[1]; // variable size
};
struct GpGlyphData {
GpGlyphMetrics GlyphMetrics[2]; // one for horizontal metrics and one for vertical metrics
union {
GLYPHBITS *GlyphBits; // Same as GDI structure at this moment
GpGlyphPath *GlyphPath;
GpGlyphAABits *GlyphAABits; // null terminated singly-linked list
};
};
struct GlyphDataBlock
{
GlyphDataBlock *NextGlyphDataBlock;
GpGlyphData GlyphDataArray[GLYPHDATABLOCKCOUNT];
};
// blocks of memory used to store glyphbits
struct GlyphBitsBlock
{
GlyphBitsBlock *NextGlyphBitsBlock; // next block in the list
UINT SizeGlyphBitsBlock; // Bytes allocated
BYTE Bits[1]; // bits
};
//// CacheFaceRealization - cache entries referenced by FaceRealization
//
//
class EXTFONTOBJ
{
public:
FONTOBJ fobj; // pass to DDI, we need to have it to back compatible with GDI
};
enum GpGlyphDataCacheType
{
CacheBits,
CachePath,
CacheAABits
};
class CacheFaceRealization : public EXTFONTOBJ
{
public:
// New type information
BOOL NoCache; // Cache type -
GpGlyphDataCacheType CacheType; // bits, path or AA bits
BOOL ForcedPath; // was this CacheFaceRealization forced to use path because of huge font size
// claudebe, try to get rid of both, redundant with fontObj flags : should correspond to what is actually realized
TextRenderingHint realizationMethod;
ULONG QueryFontDataMode;
// Physical font information (font source).
const GpFontFace *Face; // pointer to physical font entry
// Font transform information.
// DDI callback transform object. A reference to this EXFORMOBJ is passed
// to the driver so that it can callback XFORMOBJ_ services for the notional
// to device transform for this font.
GpMatrix mxForDDI; // xoForDDI's matrix
// cached here upon font realization for fast access
ULONG MaxGlyphByteCount; // (MaxGlyphPixelWidth + 7)/8 * MaxGlyphPixelHeight, or at least it should be for 1 bpp
FD_DEVICEMETRICS DeviceMetrics; // Hinted metric indformation
// Root of per glyph metrics and images
GpGlyphData **GlyphDataArray; // array of pointers to GpGlyphData's
// CacheFaceRealization linked list for a particular face
CacheFaceRealization *NextCacheFaceRealization;
CacheFaceRealization *PreviousCacheFaceRealization;
// CacheFaceRealization last recently used linked list
CacheFaceRealization *NextRecentCacheFaceRealization;
CacheFaceRealization *PreviousRecentCacheFaceRealization;
// Font cache information.
GlyphDataBlock *FirstGlyphDataBlock; // First block in chain - used for destruction
GlyphBitsBlock *FirstGlyphBitsBlock;
// Info for GlyphDataBlock being constructed
GlyphDataBlock *GlyphDataBlockUnderConstruction;
UINT NextFreeGlyphDataIndex; // (All other blocks are already full)
// Info for GlyphBitBlock under construction
GlyphBitsBlock *GlyphBitsBlockUnderConstruction;
UINT SizeGlyphBitsBlockUnderConstruction; // Bytes allocated
UINT UsedBytesGlyphBitsBlockUnderConstruction; // Bytes used
// Lookaside cache - holds bits or path and metrics for a single glyph, used whern
// data too big for cache block.
GpGlyphData *LookasideGlyphData; // Same as GDI structure at this moment
SIZE_T LookasideByteCount; // size of current lookaside buffer
// claudebe : still need to be updated to use the global cache size limit :
UINT cBlocksMax; // max # of blocks allowed
UINT cBlocks; // # of blocks allocated so far
};
//// FaceRealization
//
// Represents a font at a given size (?on a given device?)
class GpFaceRealization
{
private:
mutable CacheFaceRealization *prface;
GpStatus Status;
INT Style;
BOOL LimitSubpixel;
public:
// Constructors -- Lock the CacheFaceRealization.
GpFaceRealization()
: prface (NULL),
Status (InvalidParameter)
{}
GpFaceRealization(
const GpFontFace *pface,
INT style,
const GpMatrix *matrix,
const SizeF dpi,
TextRenderingHint renderMethod,
BOOL bPath,
BOOL bCompatibleWidth, /* we want ClearType compatible width when we come from DrawDriverString */
BOOL bSideways /* for far east vertical writing, run of glyph layed out sideways,
used to do the italic simulation in the right direction */
);
// Destructor -- Unlocks the CacheFaceRealization
~GpFaceRealization();
// To clone another GpFaceRealiztion from Bits to Path
void CloneFaceRealization(
const GpFaceRealization * pfaceRealizaton,
BOOL bPath
);
// GetStatus - Called following instantiation to check that construction worked.
GpStatus GetStatus() const {return Status;}
INT GetStyle() const
{
#if DBG
INT style = 0;
if ( prface->Face->pifi->fsSelection & FM_SEL_BOLD
|| prface->fobj.flFontType & FO_SIM_BOLD)
{
style |= FontStyleBold;
}
if ( prface->Face->pifi->fsSelection & FM_SEL_ITALIC
|| prface->fobj.flFontType & FO_SIM_ITALIC_SIDEWAYS
|| prface->fobj.flFontType & FO_SIM_ITALIC)
{
style |= FontStyleItalic;
}
ASSERT(style == (Style & (FontStyleBold | FontStyleItalic)));
#endif
return Style;
}
BOOL bInit(
const GpFontFace *pface,
INT style,
const GpMatrix *matrix,
SizeF dpi,
TextRenderingHint textMode,
BOOL bPath,
BOOL bCompatibleWidth, /* we want ClearType compatible width when we come from DrawDriverString */
BOOL bSideways /* for far east vertical writing, run of glyph layed out sideways,
used to do the italic simulation in the right direction */
);
// bDelete -- Removes an CacheFaceRealization
BOOL DeleteRealizedFace();
// Reuse an CacheFaceRealization
BOOL ReuseRealizedFace();
// bInitCache -- Initialize the cache
BOOL bInitCache() const;
BOOL AllocateCache() const;
// vDeleteCache -- Delete the CACHE from existence.
VOID vDeleteCache() const;
BOOL noCache() const {return prface->NoCache ;}
// FindRealizedFace -- check to see whether there is existing realization
// on the CacheFaceRealization list in the GpFontFile.
BOOL FindRealizedFace(
FD_XFORM *fdx,
const GpFontFace *fontFace,
BOOL needPaths,
FLONG fl
) const;
// RealizeFont -- Initializer; for IFI, calls driver to realize
// font represented by PFE.
BOOL Realize(
SizeF dpi,
const GpFontFace *pfe,
INT style, // style - which may require simulation
PFD_XFORM pfdx, // font xform (Notional to Device)
FLONG fl, // these two really modify the xform
BOOL bNeedPaths
);
// Valid -- Returns TRUE if object was successfully locked
BOOL IsValid ()
{
return(prface != 0);
}
ULONG QueryFontDataMode() const
{
return prface->QueryFontDataMode;
}
BOOL bGetDEVICEMETRICS();
// return the font face for this RFace
const GpFontFace * GetFontFace() const {return(prface->Face);}
// Is it in private font file table or not
BOOL IsPrivate() const {return prface->Face->IsPrivate();}
// pfdx -- Return pointer to the notional to device font transform.
FD_XFORM *pfdx() const {return (&prface->fobj.fdx);}
// pfo -- Return pointer to the font object
FONTOBJ *pfo() const {return(&prface->fobj);}
// kill driver realization of the font, i.e. "FONT CONTEXT" in the old lingo.
// Method calling DrvDestroyFont before CacheFaceRealization is killed itself.
VOID vDestroyRealizedFace();
// vGetCache -- Claims the cache semaphore
VOID vGetCache ()
{
// EnterCriticalSection(&prface->FaceRealizationCritSection);
}
// vReleaseCache -- Releases the cache semaphore
VOID vReleaseCache ()
{
if ( prface->LookasideGlyphData != NULL )
{
GpFree((PVOID) prface->LookasideGlyphData);
prface->LookasideByteCount = 0;
prface->LookasideGlyphData = NULL;
}
// LeaveCriticalSection(&prface->FaceRealizationCritSection);
}
ULONG GetGlyphsSupported() const
{
if (prface && prface->Face)
{
return (prface->Face->NumGlyphs);
}
return 0;
}
GpStatus GetGlyphStringDeviceAdvanceVector(
const UINT16 *glyphs,
INT glyphCount,
BOOL vertical,
REAL *deviceAdvances
) const;
GpStatus GetGlyphStringDeviceAdvanceVector(
const UINT16 *glyphs,
INT glyphCount,
BOOL vertical,
INT *deviceAdvances // Returned in 28.4
) const;
GpStatus GetGlyphStringIdealAdvanceVector(
const UINT16 *glyphs,
INT glyphCount,
REAL deviceToIdeal,
BOOL vertical,
INT *idealAdvances
) const;
GpStatus GetGlyphStringSidebearings(
const UINT16 *glyphs,
INT glyphCount,
BOOL vertical,
BOOL reverse, // For example right-to-left
INT *leadingSidebearing, // 28.4
INT *trailingSidebearing // 28.4
) const;
GpStatus GetGlyphStringVerticalOriginOffsets(
IN const UINT16 *glyphs,
IN INT glyphCount,
OUT PointF *offsets
) const;
// GetGlyphPath
GpStatus
GetGlyphPath(
const UINT16 glyphIndice,
GpGlyphPath **pGlyphPath,
PointF *sidewaysOffset
) const;
// GetGlyphPos
INT GetGlyphPos(
const INT cGlyphs, // How many glyphs Client want to request
const UINT16 *glyphIndex, // An array of glyph index
GpGlyphPos *pgpos, // An array of GLYPHPOS
const PointF *glyphOrigin, // X,Y positions for sub-pixel calculation
INT *cParsed, // How many glyphs we parsed
BOOL sideways // e.g. FE characters in vertical text
) const;
// Realization mode
inline TextRenderingHint RealizationMethod() const {return(prface->realizationMethod);}
// IisPathFont -- Is this a path font?
inline BOOL IsPathFont() const {return(prface->CacheType == CachePath);}
VOID FlushCache() const;
// Construction hack used by GpFaceRealizationTMP during CacheFaceRealization cleanup
void Setprface(CacheFaceRealization *rface) {prface = rface;}
CacheFaceRealization *Getprface() const {return prface;}
INT GetXMin() const {return prface->DeviceMetrics.xMin;};
INT GetXMax() const {return prface->DeviceMetrics.xMax;};
INT GetYMin() const {return prface->DeviceMetrics.yMin;};
INT GetYMax() const {return prface->DeviceMetrics.yMax;};
BOOL IsHorizontalTransform() const {return prface->DeviceMetrics.HorizontalTransform;};
BOOL IsVerticalTransform() const {return prface->DeviceMetrics.VerticalTransform;};
BOOL IsFixedPitch() const {return (prface->Face->pifi->flInfo & FM_INFO_OPTICALLY_FIXED_PITCH);};
BOOL GetLimitSubpixel() { return LimitSubpixel; }
void SetLimitSubpixel(BOOL limitSubpixel) { LimitSubpixel = limitSubpixel; }
private:
GpStatus CheckGlyphStringMetricsCached(const UINT16 *glyphs, INT glyphCount) const;
// vInsert -- Insert this CacheFaceRealization onto the head of an CacheFaceRealization doubly linked list.
VOID vInsert (CacheFaceRealization **pprfaceHead);
// vRemove -- Remove this CacheFaceRealization from an CacheFaceRealization doubly linked list.
VOID vRemove (CacheFaceRealization **pprfaceHead);
// Access to cached glyph data
GpGlyphData *GetGlyphDataCached(UINT16 glyphIndex, BOOL allowFlush) const;
GpGlyphData *GetGlyphDataLookaside(UINT16 glyphIndex) const;
BOOL CheckMetricsCache() const;
VOID *pgbCheckGlyphCache(SIZE_T cjNeeded) const;
VOID ConvertGLYPHDATAToGpGlyphMetrics(
IN INT glyphIndex,
IN GLYPHDATA *pgd,
OUT GpGlyphData *pgpgd
) const;
GpStatus IsMetricsCached(UINT16 glyph, ULONG * pcjNeeded) const;
BOOL InsertGlyphBits(UINT16 glyph, ULONG cjNeeded, BOOL bFlushOk) const;
BOOL InsertGlyphPath(UINT16 glyph, BOOL allowFlush) const;
// bMatchFDXForm -- Is pfdx identical to current font xform?
inline BOOL MatchFDXForm(FD_XFORM *pfdx) const
{
return(!memcmp((PBYTE)pfdx, (PBYTE)&prface->fobj.fdx, sizeof(FD_XFORM)));
}
// Calculating sub-pixel position
BOOL GetAAGlyphDataCached(
UINT16 glyphIndex,
GpGlyphPos * pgpos,
BOOL allowFlush,
INT x,
INT y,
BOOL sideways // e.g. FE characters in vertical text
) const;
};
class GpFaceRealizationTMP : public GpFaceRealization
{
public:
GpFaceRealizationTMP(CacheFaceRealization *_prface) {Setprface(_prface);}
~GpFaceRealizationTMP() {Setprface(NULL);}
};
class GpCacheFaceRealizationList
{
public:
GpCacheFaceRealizationList() { head = NULL; count = 0; }
~GpCacheFaceRealizationList();
void AddMostRecent(CacheFaceRealization *prface);
void RemoveFace(CacheFaceRealization *prface);
CacheFaceRealization *ReuseLeastRecent (void);
INT GetCount() {return count; }
private:
CacheFaceRealization *head;
INT count;
};
#endif // __FACEREALIZATION__