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
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__
|
|
|