408 lines
13 KiB
C++
408 lines
13 KiB
C++
/******************************************************************************
|
||
|
||
Header File: Glyph Translation.H
|
||
|
||
These classes define the mapping used from a Unicode or ANSI character to a
|
||
character sequence to render said character on a printer. They are content
|
||
equivalent to the CTT, RLE and GTT formats used in the various flavors of the
|
||
mini-driver architecture.
|
||
|
||
Copyright (c) 1997 by Microsoft Corporation. All Rights Reserved.
|
||
|
||
A Pretty Penny Enterprises Production
|
||
|
||
Change History:
|
||
02-13-97 Bob_Kjelgaard@Prodigy.Net Created it
|
||
|
||
******************************************************************************/
|
||
|
||
#if !defined(GLYPH_TRANSLATION)
|
||
|
||
#define GLYPH_TRANSLATION
|
||
|
||
#if defined(LONG_NAMES)
|
||
#include "Project Node.H"
|
||
#else
|
||
#include "ProjNode.H"
|
||
#endif
|
||
|
||
// Win16 CTT formats- since these can't change, I've recoded them to suit.
|
||
// Good thing, too- the mapping of direct was bogus- the union implies a word
|
||
// aligned structure, but the fact is that direct data is byte-aligned.
|
||
class CInvocation : public CObject {
|
||
CByteArray m_cbaEncoding;
|
||
DWORD m_dwOffset;
|
||
DECLARE_SERIAL(CInvocation)
|
||
|
||
void Encode(BYTE c, CString& cs) const;
|
||
|
||
public:
|
||
|
||
CInvocation() {}
|
||
void Init(PBYTE pb, unsigned ucb);
|
||
|
||
unsigned Length() const { return (int)m_cbaEncoding.GetSize(); }
|
||
const unsigned Size() const { return 2 * sizeof m_dwOffset; }
|
||
|
||
void GetInvocation(CString& csReturn) const;
|
||
|
||
BYTE operator[](unsigned u) const {
|
||
return u < Length() ? m_cbaEncoding[u] : 0;
|
||
}
|
||
|
||
CInvocation& operator =(CInvocation& ciRef) {
|
||
m_cbaEncoding.Copy(ciRef.m_cbaEncoding);
|
||
return *this;
|
||
}
|
||
|
||
void SetInvocation(LPCTSTR lpstrNew);
|
||
void NoteOffset(DWORD& dwOffset);
|
||
void WriteSelf(CFile& cfTarget) const;
|
||
void WriteEncoding(CFile& cfTarget, BOOL bWriteLength = FALSE) const;
|
||
virtual void Serialize(CArchive& car);
|
||
};
|
||
|
||
// The following class handles glyph handles and all associated details
|
||
|
||
class CGlyphHandle : public CObject {
|
||
|
||
CInvocation m_ciEncoding;
|
||
DWORD m_dwCodePage, m_dwidCodePage, m_dwOffset;
|
||
WORD m_wIndex;
|
||
WORD m_wCodePoint; // Unicode Representation of the glyph
|
||
WORD m_wPredefined;
|
||
|
||
public:
|
||
CGlyphHandle() ;
|
||
|
||
// Atributes
|
||
|
||
const unsigned RLESize() const { return sizeof m_dwCodePage; }
|
||
unsigned CodePage() const { return m_dwidCodePage; } // Only ID matters
|
||
WORD CodePoint() const { return m_wCodePoint; }
|
||
|
||
unsigned CompactSize() const;
|
||
|
||
unsigned MaximumSize() const {
|
||
return CompactSize() ?
|
||
sizeof m_wIndex + ((CompactSize() + 1) & ~1) : 0;
|
||
}
|
||
|
||
void GetEncoding(CString& csWhere) {
|
||
m_ciEncoding.GetInvocation(csWhere);
|
||
}
|
||
|
||
enum {Modified, Added, Removed};
|
||
WORD Predefined() const { return m_wPredefined; }
|
||
BOOL operator ==(CGlyphHandle& cghRef);
|
||
BOOL PairedRelevant() const { return m_ciEncoding.Length() == 2; }
|
||
|
||
// Operations
|
||
|
||
void Init(BYTE b, WORD wIndex, WORD wCode);
|
||
void Init(BYTE ab[2], WORD wIndex, WORD wCode);
|
||
void Init(PBYTE pb, unsigned ucb, WORD wIndex, WORD wCode);
|
||
|
||
CGlyphHandle& operator =(CGlyphHandle& cghTemplate);
|
||
|
||
void RLEOffset(DWORD& dwOffset, const BOOL bCompact);
|
||
void GTTOffset(DWORD& dwOffset, BOOL bPaired);
|
||
|
||
void SetCodePage(DWORD dwidPage, DWORD dwNewPage) {
|
||
m_dwCodePage = dwNewPage;
|
||
m_dwidCodePage = dwidPage;
|
||
}
|
||
|
||
void NewEncoding(LPCTSTR lpstrNew) {
|
||
m_ciEncoding.SetInvocation(lpstrNew);
|
||
}
|
||
|
||
void SetPredefined(WORD wNew) { m_wPredefined = wNew; }
|
||
|
||
// These write our contents for mini-driver files- they will throw
|
||
// exceptions on failure, so use an exception handler to handle errors
|
||
|
||
void WriteRLE(CFile& cfTarget, WORD wFormat) const;
|
||
void WriteGTT(CFile& cfTarget, BOOL bPredefined) const;
|
||
|
||
enum {GTT, RLEBig, RLESmall}; // Desired encoding format
|
||
void WriteEncoding(CFile& cfTarget, WORD wfHow) const;
|
||
};
|
||
|
||
// The next class maintains a record of the runs in the glyph set. It
|
||
// generates and merges instances of itself as glyphs are added to the map.
|
||
|
||
class CRunRecord {
|
||
WORD m_wFirst, m_wcGlyphs;
|
||
DWORD m_dwOffset; // These are the image...
|
||
CRunRecord *m_pcrrNext, *m_pcrrPrevious;
|
||
|
||
CPtrArray m_cpaGlyphs;
|
||
|
||
CRunRecord(CGlyphHandle *pcgh, CRunRecord* pcrrPrevious);
|
||
CRunRecord(CRunRecord* crrPrevious, WORD wWhere);
|
||
CRunRecord(CRunRecord* pcrrPrevious);
|
||
|
||
CGlyphHandle& Glyph(unsigned u) {
|
||
return *(CGlyphHandle *) m_cpaGlyphs[u];
|
||
}
|
||
|
||
const CGlyphHandle& GlyphData(unsigned u) const {
|
||
return *(CGlyphHandle *) m_cpaGlyphs[u];
|
||
}
|
||
|
||
public:
|
||
|
||
CRunRecord();
|
||
~CRunRecord();
|
||
|
||
unsigned Glyphs() const { return m_wcGlyphs; }
|
||
unsigned TotalGlyphs() const;
|
||
BOOL MustCompose() const;
|
||
unsigned RunCount() const {
|
||
return 1 + (m_pcrrNext ? m_pcrrNext -> RunCount() : 0);
|
||
}
|
||
|
||
WORD First() const { return m_wFirst; }
|
||
WORD Last() const {
|
||
return m_pcrrNext ? m_pcrrNext ->Last() : -1 + m_wFirst + m_wcGlyphs;
|
||
}
|
||
|
||
unsigned ExtraNeeded(BOOL bCompact = TRUE);
|
||
|
||
const unsigned Size(BOOL bRLE = TRUE) const {
|
||
return sizeof m_dwOffset << (unsigned) (!!bRLE);
|
||
}
|
||
|
||
void Collect(CPtrArray& cpaGlyphs) const {
|
||
cpaGlyphs.Append(m_cpaGlyphs);
|
||
if (m_pcrrNext) m_pcrrNext -> Collect(cpaGlyphs);
|
||
}
|
||
|
||
CGlyphHandle* GetGlyph(unsigned u ) const;
|
||
|
||
#if defined(_DEBUG) // While the linkage code seems to check out, keep this
|
||
// around in case of later problems
|
||
BOOL ChainIntact() {
|
||
_ASSERTE(m_wcGlyphs == m_cpaGlyphs.GetSize());
|
||
for (unsigned u = 0; u < Glyphs(); u++) {
|
||
_ASSERTE(Glyph(u).CodePoint() == m_wFirst + u);
|
||
}
|
||
return !m_pcrrNext || m_pcrrNext -> m_pcrrPrevious == this &&
|
||
m_pcrrNext -> ChainIntact();
|
||
}
|
||
#endif
|
||
|
||
// Operations
|
||
|
||
void Add(CGlyphHandle *pcgh);
|
||
void Delete(WORD wCodePoint);
|
||
void Empty();
|
||
|
||
void NoteOffset(DWORD& dwOffset, BOOL bRLE, BOOL bPaired);
|
||
void NoteExtraOffset(DWORD& dwOffset, const BOOL bCompact);
|
||
|
||
// File output operations
|
||
|
||
void WriteSelf(CFile& cfTarget, BOOL bRLE = TRUE) const;
|
||
void WriteHandles(CFile& cfTarget, WORD wFormat) const;
|
||
void WriteMapTable(CFile& cfTarget, BOOL bPredefined) const;
|
||
void WriteEncodings(CFile& cfTarget, WORD wfHow) const;
|
||
};
|
||
|
||
class CCodePageData : public CObject {
|
||
DWORD m_dwid;
|
||
CInvocation m_ciSelect, m_ciDeselect;
|
||
|
||
public:
|
||
|
||
CCodePageData() { m_dwid = 0; }
|
||
CCodePageData(DWORD dwid) { m_dwid = dwid; }
|
||
|
||
// Attributes
|
||
|
||
DWORD Page() const { return m_dwid; }
|
||
void Invocation(CString& csReturn, BOOL bSelect) const;
|
||
const unsigned Size() const {
|
||
return sizeof m_dwid + 2 * m_ciSelect.Size();
|
||
}
|
||
|
||
BOOL NoInvocation() const {
|
||
return !m_ciSelect.Length() && !m_ciDeselect.Length();
|
||
}
|
||
|
||
// Operations
|
||
void SetPage(DWORD dwNewPage) { m_dwid = dwNewPage; }
|
||
void SetInvocation(LPCTSTR lpstrInvoke, BOOL bSelect);
|
||
void SetInvocation(PBYTE pb, unsigned ucb, BOOL bSelect);
|
||
void NoteOffsets(DWORD& dwOffset);
|
||
void WriteSelf(CFile& cfTarget);
|
||
void WriteInvocation(CFile& cfTarget);
|
||
};
|
||
|
||
// This class is the generic class encompassing all glyph translation
|
||
// information. We can use it to output any of the other forms.
|
||
|
||
class CGlyphMap : public CProjectNode {
|
||
CSafeMapWordToOb m_csmw2oEncodings; // All of the defined encodings
|
||
CRunRecord m_crr;
|
||
long m_lidPredefined;
|
||
BOOL m_bPaired; // Use paired encoding...
|
||
CSafeObArray m_csoaCodePage; // Code page(s) in this map
|
||
|
||
// Framework support (workspace)
|
||
|
||
CString m_csSource; // Source CTT File name
|
||
|
||
// Predefined GTT support- must be in this DLL
|
||
|
||
static CSafeMapWordToOb m_csmw2oPredefined; // Cache loaded PDTs here
|
||
|
||
void MergePredefined(); // Use definitions to build "true" GTT
|
||
void UnmergePredefined(BOOL bTrackRemovals);
|
||
|
||
void GenerateRuns();
|
||
|
||
CCodePageData& CodePage(unsigned u) const {
|
||
return *(CCodePageData *) m_csoaCodePage[u];
|
||
}
|
||
|
||
DECLARE_SERIAL(CGlyphMap)
|
||
public:
|
||
bool ChngedCodePt() { return m_bChngCodePt ; } ;
|
||
void SetCodePt( bool b) { m_bChngCodePt = b ; }
|
||
// These variables hold parameters for PGetDefaultGlyphset().
|
||
|
||
WORD m_wFirstChar, m_wLastChar ;
|
||
|
||
// True iff GTT data should be loaded from resources or built.
|
||
|
||
bool m_bResBldGTT ;
|
||
|
||
CTime m_ctSaveTimeStamp ; // The last time this GTT was saved
|
||
|
||
// Predefined IDs, and a static function for retrieving predefined maps
|
||
|
||
enum {Wansung = -18, ShiftJIS, GB2312, Big5ToTCA, Big5ToNSA86, JISNoANK,
|
||
JIS, KoreanISC, Big5, CodePage863 = -3, CodePage850, CodePage437,
|
||
DefaultPage, NoPredefined = 0xFFFF};
|
||
|
||
static CGlyphMap* Public(WORD wID, WORD wCP = 0, DWORD dwDefCP = 0,
|
||
WORD wFirst = 0, WORD wLast = 255) ;
|
||
|
||
CGlyphMap();
|
||
|
||
// Attributes
|
||
|
||
unsigned CodePages() const { return m_csoaCodePage.GetSize(); }
|
||
DWORD DefaultCodePage() const { return CodePage(0).Page(); }
|
||
|
||
unsigned Glyphs() const {
|
||
return m_csmw2oEncodings.GetCount();
|
||
}
|
||
|
||
void CodePages(CDWordArray& cdaReturn) const;
|
||
unsigned PageID(unsigned u) const { return CodePage(u).Page(); }
|
||
long PredefinedID() const { return m_lidPredefined; }
|
||
|
||
CString PageName(unsigned u) const;
|
||
void Invocation(unsigned u, CString& csReturn, BOOL bSelect) const;
|
||
void UndefinedPoints(CMapWordToDWord& cmw2dCollector) const;
|
||
BOOL OverStrike() const { return m_bPaired; }
|
||
const CString& SourceName() { return m_csSource; }
|
||
|
||
// Operations- Framework support
|
||
void SetSourceName(LPCTSTR lpstrNew);
|
||
void Load(CByteArray& cbaMap) ; // Load GTT image
|
||
//void Load(CByteArray& cbaMap) const; // Load GTT image
|
||
|
||
// Operations- editor support
|
||
|
||
void AddPoints(CMapWordToDWord& cmw2dNew); // Add points and pages
|
||
void DeleteGlyph(WORD wGlyph);
|
||
BOOL RemovePage(unsigned uPage, unsigned uMapTo, bool bDelete = FALSE); // 118880
|
||
|
||
void SetDefaultCodePage(unsigned u) { CodePage(0).SetPage(u); }
|
||
void ChangeCodePage(CPtrArray& cpaGlyphs, DWORD dwidNewPage);
|
||
void AddCodePage(DWORD dwidNewPage);
|
||
|
||
void UsePredefined(long lidPredefined);
|
||
|
||
void SetInvocation(unsigned u, LPCTSTR lpstrInvoke, BOOL bSelect);
|
||
void ChangeEncoding(WORD wCodePoint, LPCTSTR lpstrInvoke);
|
||
void OverStrike(BOOL bOn) { m_bPaired = bOn; Changed();}
|
||
|
||
int ConvertCTT();
|
||
BOOL Load(LPCTSTR lpstrName = NULL);
|
||
BOOL RLE(CFile& cfTarget);
|
||
|
||
CGlyphHandle* Glyph(unsigned u);
|
||
|
||
// Font editor support operations
|
||
|
||
void Collect(CPtrArray& cpaGlyphs) { // Collect all glyph handles
|
||
cpaGlyphs.RemoveAll();
|
||
m_crr.Collect(cpaGlyphs);
|
||
}
|
||
|
||
virtual CMDIChildWnd* CreateEditor();
|
||
virtual BOOL Generate(CFile& cfGTT);
|
||
|
||
BOOL SetFileName(LPCTSTR lpstrNew) ;
|
||
|
||
virtual void Serialize(CArchive& car);
|
||
private:
|
||
bool m_bChngCodePt;
|
||
};
|
||
|
||
/////////////////////////////////////////////////////////////////////////////
|
||
// CGlyphMapContainer document
|
||
|
||
class CGlyphMapContainer : public CDocument {
|
||
CGlyphMap *m_pcgm;
|
||
BOOL m_bEmbedded; // From driver, or not?
|
||
BOOL m_bSaveSuccessful; // TRUE iff a successful save was performed
|
||
|
||
protected:
|
||
CGlyphMapContainer(); // protected constructor used by dynamic creation
|
||
DECLARE_DYNCREATE(CGlyphMapContainer)
|
||
|
||
// Attributes
|
||
public:
|
||
|
||
CGlyphMap* GlyphMap() { return m_pcgm; }
|
||
|
||
// Operations
|
||
public:
|
||
// Constructor- used to create from driver info editor
|
||
CGlyphMapContainer(CGlyphMap *pcgm, CString csPath);
|
||
// Overrides
|
||
// ClassWizard generated virtual function overrides
|
||
//{{AFX_VIRTUAL(CGlyphMapContainer)
|
||
public:
|
||
virtual void Serialize(CArchive& ar); // overridden for document i/o
|
||
virtual BOOL OnSaveDocument(LPCTSTR lpszPathName);
|
||
virtual BOOL OnOpenDocument(LPCTSTR lpszPathName);
|
||
protected:
|
||
virtual BOOL OnNewDocument();
|
||
virtual BOOL SaveModified();
|
||
//}}AFX_VIRTUAL
|
||
|
||
// Implementation
|
||
public:
|
||
virtual ~CGlyphMapContainer();
|
||
#ifdef _DEBUG
|
||
virtual void AssertValid() const;
|
||
virtual void Dump(CDumpContext& dc) const;
|
||
#endif
|
||
|
||
// Generated message map functions
|
||
protected:
|
||
//{{AFX_MSG(CGlyphMapContainer)
|
||
// NOTE - the ClassWizard will add and remove member functions here.
|
||
//}}AFX_MSG
|
||
DECLARE_MESSAGE_MAP()
|
||
};
|
||
|
||
#endif
|
||
|