summaryrefslogtreecommitdiff
path: root/Build/source/libs/graphite/src/segment/GrGlyphTable.h
diff options
context:
space:
mode:
Diffstat (limited to 'Build/source/libs/graphite/src/segment/GrGlyphTable.h')
-rw-r--r--Build/source/libs/graphite/src/segment/GrGlyphTable.h429
1 files changed, 429 insertions, 0 deletions
diff --git a/Build/source/libs/graphite/src/segment/GrGlyphTable.h b/Build/source/libs/graphite/src/segment/GrGlyphTable.h
new file mode 100644
index 00000000000..bec0e518dee
--- /dev/null
+++ b/Build/source/libs/graphite/src/segment/GrGlyphTable.h
@@ -0,0 +1,429 @@
+/*--------------------------------------------------------------------*//*:Ignore this sentence.
+Copyright (C) 1999, 2001 SIL International. All rights reserved.
+
+Distributable under the terms of either the Common Public License or the
+GNU Lesser General Public License, as specified in the LICENSING.txt file.
+
+File: GrGlyphTable.h
+Responsibility: Sharon Correll
+Last reviewed: 10Aug99, JT, quick look over
+
+Description:
+ The GrGlyphTable and related classes that store the values of glyph attributes.
+
+ For each glyph in a TrueType font, Graphite has a list of glyph attributes (which
+ are defined in the GDL script file). Since most of the values will be zero, we save space
+ by only storing the non-zero values.
+
+ Eventually it may be possible to have more than one TrueType font compiled into a single
+ glyph table, hence the need for multiple sub-tables. For now we assume that there is only
+ one font file and only one sub-table.
+
+ Note that BIG in a variable name means that the data is in big-endian format, or is a range
+ of bytes that must be interpreted as a run of wide chars or ints in big-endian format.
+-------------------------------------------------------------------------------*//*:End Ignore*/
+
+//:Ignore
+#ifdef _MSC_VER
+#pragma once
+#endif
+#ifndef GR_GTABLE_INCLUDED
+#define GR_GTABLE_INCLUDED
+//:End Ignore
+
+namespace gr
+{
+
+class Font;
+
+/*----------------------------------------------------------------------------------------------
+ A run of non-zero attribute values for a single glyph, where the attribute IDs
+ are contiguous.
+
+ NOTE: it is assumed that the format of this class matches the byte order of the data as it
+ is read directly from the TTF/ECF file--that is, it is big-endian.
+
+ Hungarian: gatrun
+----------------------------------------------------------------------------------------------*/
+
+class GrGlyphAttrRun
+{
+ friend class GrGlyphTable;
+ friend class GrGlyphSubTable;
+ friend class GrGlyphAttrTable;
+
+ enum {
+ kMaxAttrsPerRun = 255
+ };
+
+ /*------------------------------------------------------------------------------------------
+ Copy the raw memory (starting at the given byte) into the instance. This method must
+ reflect the format of the "Glat_entry" as it is stored in the file and slurped into
+ memory.
+ ------------------------------------------------------------------------------------------*/
+ void CopyFrom(byte * pbBIGEnt)
+ {
+ m_bMinAttrID = *pbBIGEnt;
+ m_cAttrs = *(pbBIGEnt + 1);
+ if (m_cAttrs >= kMaxAttrsPerRun)
+ {
+ gAssert(false);
+ m_cAttrs = kMaxAttrsPerRun;
+ }
+ #ifdef _DEBUG
+ // Probably not strictly necessary to zero the array, but convenient for debugging.
+ // Removed from release build for optimization
+ std::fill(m_rgchwBIGValues, m_rgchwBIGValues + kMaxAttrsPerRun, 0);
+ #endif
+ // this is mixing types of data16 and byte pointers!
+ const data16 * prgchw = reinterpret_cast<const data16*>(pbBIGEnt + 2);
+ std::copy(prgchw, prgchw + m_cAttrs, m_rgchwBIGValues);
+ }
+
+ int ByteCount()
+ {
+ return (2 + (m_cAttrs * isizeof(data16)));
+ }
+
+protected:
+ byte m_bMinAttrID; // ID of first attribute in the run
+ byte m_cAttrs; // number of attributes in the run
+ data16 m_rgchwBIGValues[kMaxAttrsPerRun];
+};
+
+/*----------------------------------------------------------------------------------------------
+ Contains runs of attribute values for all the glyphs in the font; corresponds to
+ the "Glat" table in the font.
+
+ Hungarian: gatbl
+----------------------------------------------------------------------------------------------*/
+
+class GrGlyphAttrTable
+{
+ friend class GrGlyphTable;
+ friend class GrGlyphSubTable;
+ friend class FontMemoryUsage;
+
+protected:
+ // Constructor:
+ GrGlyphAttrTable()
+ {
+ m_prgbBIGEntries = NULL;
+ }
+
+ // Destructor:
+ ~GrGlyphAttrTable()
+ {
+ delete[] m_prgbBIGEntries;
+ }
+
+ // Initialization:
+ void Initialize(int fxdSilfVersion, int cbBufLen)
+ {
+ m_fxdSilfVersion = fxdSilfVersion;
+ m_cbEntryBufLen = cbBufLen;
+ m_prgbBIGEntries = new byte[cbBufLen];
+ // Now the instance is ready to have all the glyph attr entries slurped into
+ // the byte array from the file.
+ }
+
+ int GlyphAttr16BitValue(int ibMin, int ibLim, byte bAttrID);
+
+protected:
+ int m_fxdSilfVersion; // version number of the Silf table, which is used
+ // to interpret the attribute values
+
+ // Block of variable-length glyph attribute runs, matching the format of
+ // GrGlyphAttrRun. We don't store instances of that class here because they
+ // are variable length, and it would be too slow to read them individually from the
+ // font. Instead, we set up a single instance in the method that accesses the values;
+ // having this instance will help debugging. Eventually we may want to do without it,
+ // if it would help efficiency.
+ int m_cbEntryBufLen; // needed only for memory instrumentation
+ byte * m_prgbBIGEntries;
+
+//:Ignore
+#ifdef OLD_TEST_STUFF
+public:
+ // For test procedures:
+ void SetUpTestData();
+ void SetUpLigatureTest();
+ void SetUpLigature2Test();
+#endif // OLD_TEST_STUFF
+
+//:End Ignore
+
+};
+
+/*----------------------------------------------------------------------------------------------
+ One glyph table per font (style) file; corresponds to the "Gloc" table in the font.
+ Currently there is only considered to be one style per file, so there is only one of
+ these. It holds the (non-zero) glyph attribute values for every glyph in the font.
+
+ Hungarian: gstbl
+
+ Review: Eventually we may need to make a subclass that uses 32-bit values for the offsets,
+ or just use a separate array pointer in this class. Which would be preferable?
+----------------------------------------------------------------------------------------------*/
+
+class GrGlyphSubTable
+{
+ friend class GrGlyphTable;
+ friend class FontMemoryUsage;
+
+public:
+ // Constructor:
+ GrGlyphSubTable() :
+ m_pgatbl(NULL),
+ m_prgibBIGAttrValues(NULL),
+ m_prgibBIGGlyphAttrDebug(NULL),
+ m_prgnDefinedComponents(NULL)
+ {
+ }
+ // Destructor:
+ ~GrGlyphSubTable()
+ {
+ delete m_pgatbl;
+ delete[] m_prgibBIGAttrValues;
+ if (m_fHasDebugStrings)
+ delete[] m_prgibBIGGlyphAttrDebug;
+ delete[] m_prgnDefinedComponents;
+ }
+
+ // Initialization:
+ bool ReadFromFont(GrIStream & gloc_strm, int cGlyphs,
+ GrIStream & glat_strm, long lGlatStart);
+ void Initialize(int fxdSilfVersion, data16 chwFlags,
+ data16 chwBWAttr, data16 chwJStrAttr, data16 chwJStrHWAttr,
+ int cGlyphs, int cAttrs, int cnCompPerLig);
+
+ void CreateEmpty();
+
+ void SetNumberOfComponents(int c)
+ {
+ m_cComponents = c;
+ }
+
+ // General:
+ int NumberOfGlyphAttrs() { return m_nAttrIDLim; } // 0..(m_nAttrIDLim-1)
+
+ int GlyphAttrValue(gid16 chwGlyphID, int nAttrID);
+
+ // Ligatures:
+ int ComponentContainingPoint(gid16 chwGlyphID, int x, int y);
+ bool ComponentBoxLogUnits(float xysEmSquare, gid16 chwGlyphID, int icomp,
+ int mFontEmUnits, float dysAscent,
+ float * pxsLeft, float * pysTop, float * pxsRight, float * pysBottom,
+ bool fTopOrigin = true);
+protected:
+ int CalculateDefinedComponents(gid16 chwGlyphID);
+ bool ComponentIsDefined(gid16 chwGlyphID, int nAttrID);
+ int ComponentIndexForGlyph(gid16 chwGlyphID, int nCompID);
+// int NthComponentID(gid16 chwGlyphID, int n);
+ int ConvertValueForVersion(int nRet, int nAttrID);
+
+public:
+ static int ConvertValueForVersion(int nRet, int nAttrID, int nBWAttr, int fxdVersion);
+
+ // Flags:
+ bool LongFormat(data16 chwFlags) // 32-bit values?
+ {
+ return ((chwFlags & 0x01) == 0x01); // bit 0
+ }
+ bool HasAttrNames(data16 chwFlags)
+ {
+ return ((chwFlags & 0x02) == 0x02); // bit 1
+ }
+ int GlocLookup(data16 chwGlyphId)
+ {
+ if (m_fGlocShort)
+ {
+ unsigned short su = ((unsigned short *)m_prgibBIGAttrValues)[chwGlyphId];
+ return lsbf(su);
+ }
+ else
+ { unsigned int u = ((unsigned int *)m_prgibBIGAttrValues)[chwGlyphId];
+ return lsbf((int)u);
+ }
+ }
+
+protected:
+ int m_fxdSilfVersion; // version number of the Silf table, which is used
+ // to interpret the attribute values
+ bool m_fHasDebugStrings; // are debugging strings loaded into memory?
+
+ int m_nAttrIDLim; // number of glyph attributes
+ int m_cComponents; // number of initial glyph attributes that
+ // represent ligature components
+ int m_cnCompPerLig;
+
+ GrGlyphAttrTable * m_pgatbl;
+ byte * m_prgibBIGAttrValues; // byte offsets for glyph attr values - BIG endian
+ bool m_fGlocShort; // flag for Gloc table format
+ data16 * m_prgibBIGGlyphAttrDebug; // byte offsets for glyph attr debug strings - BIG endian
+
+ data16 m_chwBWAttr; // breakweight attr ID; needed for converting
+ // between versions
+
+ // Attr IDs for justify.0.stretch and justify.0.stretchHW; these must always be looked
+ // up in tandem.
+ data16 m_chwJStrAttr;
+ data16 m_chwJStrHWAttr;
+
+ int * m_prgnDefinedComponents; // for each glyph, cache list of component attributes that
+ // are defined
+
+//:Ignore
+#ifdef OLD_TEST_STUFF
+public:
+ // For test procedures:
+ void SetUpTestData();
+ void SetUpLigatureTest();
+ void SetUpLigature2Test();
+#endif // OLD_TEST_STUFF
+
+//:End Ignore
+};
+
+/*----------------------------------------------------------------------------------------------
+ Holds all the information about glyph attributes.
+
+ Hungarian: gtbl
+----------------------------------------------------------------------------------------------*/
+
+class GrGlyphTable
+{
+ friend class GrGlyphSubTable;
+ friend class FontMemoryUsage;
+
+public:
+ // Constructor:
+ GrGlyphTable()
+ {
+ m_cglf = 0;
+ m_cComponents = 0;
+ m_cgstbl = 0;
+ m_vpgstbl.clear();
+ }
+
+ // Destructor:
+ ~GrGlyphTable()
+ {
+ for (int i = 0; i < m_cgstbl; ++i)
+ delete m_vpgstbl[i];
+ }
+
+ bool ReadFromFont(GrIStream & gloc_strm, long lGlocStart,
+ GrIStream & glat_strm, long lGlatStart,
+ data16 chwBWAttr, data16 chwJStrAttr, int cJLevels, int cnCompPerLig,
+ int fxdSilfVersion);
+
+ void CreateEmpty();
+
+ // Setters:
+ void SetNumberOfGlyphs(int c)
+ {
+ m_cglf = c;
+ }
+ void SetNumberOfStyles(int c)
+ {
+ m_cgstbl = c;
+ m_vpgstbl.resize(c);
+ }
+ void SetNumberOfComponents(int c)
+ {
+ m_cComponents = c;
+ for (unsigned int ipgstbl = 0; ipgstbl < m_vpgstbl.size(); ipgstbl++)
+ m_vpgstbl[ipgstbl]->SetNumberOfComponents(c);
+ }
+ void SetSubTable(int i, GrGlyphSubTable * pgstbl)
+ {
+ if (signed(m_vpgstbl.size()) <= i)
+ {
+ gAssert(false);
+ m_vpgstbl.resize(i+1);
+ }
+ m_vpgstbl[i] = pgstbl;
+ m_vpgstbl[i]->SetNumberOfComponents(m_cComponents);
+ }
+
+ // Getters:
+ int NumberOfGlyphs() { return m_cglf; }
+ int NumberOfStyles() { return m_cgstbl; }
+
+ int NumberOfGlyphAttrs()
+ {
+ // All of the sub-tables should have the same number of glyph attributes,
+ // so just ask the first.
+ return m_vpgstbl[0]->NumberOfGlyphAttrs();
+ }
+
+ int GlyphAttrValue(gid16 chwGlyphID, int nAttrID)
+ {
+ gAssert(m_cgstbl == 1);
+ return m_vpgstbl[0]->GlyphAttrValue(chwGlyphID, nAttrID);
+ }
+ // Eventually:
+ //int GlyphAttrValue(gid16 chwGlyphID, int nAttrID, int nStyleIndex)
+ //{
+ // return m_vpgstbl[nStyleIndex]->GlyphAttrValue(chwGlyphID, nAttrID);
+ //}
+
+ int ComponentContainingPoint(gid16 chwGlyphID, int x, int y)
+ {
+ gAssert(m_cgstbl == 1);
+ return m_vpgstbl[0]->ComponentContainingPoint(chwGlyphID, x, y);
+ }
+ // Eventually:
+ //int ComponentContainingPoint(gid16 chwGlyphID, int nStyleIndex, int x, int y)
+ //{
+ // gAssert(m_cgstbl == 1);
+ // return m_vpgstbl[nStyleIndex]->ComponentContainingPoint(chwGlyphID, nAttrID);
+ //}
+
+ bool ComponentBoxLogUnits(float xysEmSquare, gid16 chwGlyphID, int icomp,
+ int mFontEmUnits, float dysAscent,
+ float * pxsLeft, float * pysTop, float * pxsRight, float * pysBottom,
+ bool fTopOrigin = true)
+ {
+ gAssert(m_cgstbl == 1);
+ return m_vpgstbl[0]->ComponentBoxLogUnits(xysEmSquare,
+ chwGlyphID, icomp, mFontEmUnits, dysAscent,
+ pxsLeft, pysTop, pxsRight, pysBottom,
+ fTopOrigin);
+ }
+
+ int ComponentIndexForGlyph(gid16 chwGlyphID, int nCompID)
+ {
+ gAssert(m_cgstbl == 1);
+ return m_vpgstbl[0]->ComponentIndexForGlyph(chwGlyphID, nCompID);
+ }
+
+ bool IsEmpty()
+ {
+ return (m_cglf == 0);
+ }
+
+protected:
+ int m_cglf; // number of glyphs
+ int m_cComponents; // number of defined components
+ int m_cgstbl; // number of sub-tables, corresponding to font files;
+ // for now there is only one
+
+ std::vector<GrGlyphSubTable *> m_vpgstbl;
+
+//:Ignore
+#ifdef OLD_TEST_STUFF
+public:
+ // For test procedures:
+ void SetUpTestData();
+ void SetUpLigatureTest();
+ void SetUpLigature2Test();
+#endif // OLD_TEST_STUFF
+//:End Ignore
+
+};
+
+} // namespace gr
+
+#endif // !GR_GTABLE_INCLUDED