You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@openoffice.apache.org by ms...@apache.org on 2021/03/30 14:21:13 UTC

[openoffice] 05/06: use std::vector instead of fixed-size array of cffLocal objects (#89)

This is an automated email from the ASF dual-hosted git repository.

mseidel pushed a commit to branch AOO41X
in repository https://gitbox.apache.org/repos/asf/openoffice.git

commit 25e830b3af9370ce4c6f67ce14efa5a08dac831c
Author: Arrigo Marchiori <ar...@yahoo.it>
AuthorDate: Mon Feb 8 17:44:32 2021 +0100

    use std::vector instead of fixed-size array of cffLocal objects (#89)
    
    Also cleanup (compilation warnings, data types used only once) and add
    some comments
    (cherry picked from commit 28337f97741b07126276d340a03620ea61fffcac)
---
 main/vcl/source/fontsubset/cff.cxx | 117 ++++++++++++++++++++++++-------------
 1 file changed, 76 insertions(+), 41 deletions(-)

diff --git a/main/vcl/source/fontsubset/cff.cxx b/main/vcl/source/fontsubset/cff.cxx
index 8cdb160..56b695a 100644
--- a/main/vcl/source/fontsubset/cff.cxx
+++ b/main/vcl/source/fontsubset/cff.cxx
@@ -158,7 +158,14 @@ static const char* pStdEncNames[] = {
 
 // --------------------------------------------------------------------
 
-// TOP DICT keywords (also covers PRIV DICT keywords)
+/** TOP DICT keywords (also covers PRIV DICT keywords)
+ *
+ * Refer to the CFF Specification, tables 9 and 23.
+ *
+ * This array is indexed by operand.
+ *
+ * The first character tells the type of operand ('s': SID, 'b': boolean etc.).
+ */
 static const char* pDictOps[] = {
 	"sVersion",			"sNotice",				"sFullName",		"sFamilyName",
 	"sWeight",			"aFontBBox",			"dBlueValues",		"dOtherBlues",
@@ -172,7 +179,16 @@ static const char* pDictOps[] = {
 
 // --------------------------------------------------------------------
 
-// TOP DICT escapes (also covers PRIV DICT escapes)
+/** TOP DICT escapes (also covers PRIV DICT escapes)
+ *
+ * Refer to the CFF Specification, tables 9 and 23.
+ *
+ * These operators come after the escape operator (no. 12).
+ *
+ * This array is indexed by operand.
+ *
+ * The first character tells the type of operand ('s': SID, 'b': boolean etc.).
+ */
 static const char* pDictEscs[] = {
 	"sCopyright",			"bIsFixedPitch",	"nItalicAngle",		"nUnderlinePosition",
 	"nUnderlineThickness",	"nPaintType",		"tCharstringType",	"aFontMatrix",
@@ -290,11 +306,17 @@ struct TYPE2OP
 
 // ====================================================================
 
+/** Data layout of a CFF FontSet
+ *
+ * Refer to the CFF specification, chapter 2
+ */
 struct CffGlobal
 {
 	explicit CffGlobal();
 
+	// Offset of the Name INDEX inside the CFF data
 	int		mnNameIdxBase;
+	// Number of objects stored in the Name INDEX
 	int		mnNameIdxCount;
 	int		mnStringIdxBase;
 	int		mnStringIdxCount;
@@ -353,34 +375,19 @@ struct CffLocal
 
 // ====================================================================
 
-class SubsetterContext
-{
-public:
-	virtual ~SubsetterContext( void);
-	virtual bool emitAsType1( class Type1Emitter&,
-				const sal_GlyphId* pGlyphIds, const U8* pEncoding,
-				GlyphWidth* pGlyphWidths, int nGlyphCount, FontSubsetInfo& ) = 0;
-};
-
-// --------------------------------------------------------------------
-
-SubsetterContext::~SubsetterContext( void)
-{}
-
-// ====================================================================
-
 class CffSubsetterContext
-:	public SubsetterContext
-,	private CffGlobal
+:	private CffGlobal
 {
 public:
-	static const int NMAXSTACK = 48;	// see CFF.appendixB
-	static const int NMAXHINTS = 2*96;	// see CFF.appendixB
-	static const int NMAXTRANS = 32;	// see CFF.appendixB
+	// Refer to Type 2 charstring format appendix B, "Type 2 Charstring Implementation Limits"
+	static const int NMAXSTACK = 48;	// argument stack
+	static const int NMAXHINTS = 2*96;	// number of stem hints (H/V total)
+	static const int NMAXTRANS = 32;	// TransientArray elements
 public:
 	explicit CffSubsetterContext( const U8* pBasePtr, int nBaseLen);
 	virtual	~CffSubsetterContext( void);
 
+	// Begin parsing the CFF data
 	void	initialCffRead( void);
 	bool	emitAsType1( class Type1Emitter&,
 				const sal_GlyphId* pGlyphIds, const U8* pEncoding,
@@ -397,9 +404,12 @@ private:
 	void	callType2Subr( bool bGlobal, int nSubrNumber);
 	long	getReadOfs( void) const { return (long)(mpReadPtr - mpBasePtr);}
 
+	// First byte of CFF font data
 	const U8* mpBasePtr;
+	// Last byte of CFF font data
 	const U8* mpBaseEnd;
 
+	// Moving cursors inside CFF font data
 	const U8* mpReadPtr;
 	const U8* mpReadEnd;
 
@@ -410,14 +420,29 @@ private:
 	long	mnCntrMask;
 
 private:
+	/** Prepare to access an element inside a CFF/CID index table
+	 *
+	 * nIndexBase: offset of the INDEX structure inside the CFF font data.
+	 * nDataIndex: offset of the element inside the INDEX structure.
+	 *
+	 * Sets mpReadPtr to the beginning of the element and mpReadEnd to the end of the element.
+	 *
+	 * Returns the size of the element, or -1 if the data is not valid (e.g. indices are too big).
+	 */
 	int		seekIndexData( int nIndexBase, int nDataIndex);
+	/** Seek to the end of an INDEX structure
+	 *
+	 * nIndexBase: offset of the INDEX structure inside the CFF font data.
+	 *
+	 * Sets mpReadPtr to the first byte after the indicated structure.
+	 */
 	void	seekIndexEnd( int nIndexBase);
 
 private:
 	const char**	mpCharStringOps;
 	const char**	mpCharStringEscs;
 
-	CffLocal	maCffLocal[256];
+	std::vector<CffLocal>	maCffLocal;
 	CffLocal*	mpCffLocal;
 
 	void		readDictOp( void);
@@ -427,6 +452,12 @@ private:
 	int			getGlyphSID( int nGlyphIndex) const;
 	const char* getGlyphName( int nGlyphIndex);
 
+	/** Decode an integer DICT Data Operand and push it.
+	 *
+	 * Refer to the CFF Specification, table 3.
+	 *
+	 * Advances mpReadPtr.
+	 */
 	void	read2push( void);
 	void	pop2write( void);
 	void	writeType1Val( ValType);
@@ -465,8 +496,12 @@ public: // TODO: is public really needed?
 
 private:
 	// typeop exceution context
+
+	// Count of mnValStack elements 
 	int	mnStackIdx;
+	// Stack for holding CFF DICT operands
 	ValType	mnValStack[ NMAXSTACK+4];
+	// Transient array for Type 2 storage operators (PUT, GET)
 	ValType	mnTransVals[ NMAXTRANS];
 
 	int	mnHintSize;
@@ -487,7 +522,7 @@ CffSubsetterContext::CffSubsetterContext( const U8* pBasePtr, int nBaseLen)
 ,	maCharWidth(-1)
 {
 //	setCharStringType( 1);
-	// TODO: new CffLocal[ mnFDAryCount];
+	maCffLocal.resize(1);
 	mpCffLocal = &maCffLocal[0];
 }
 
@@ -495,7 +530,6 @@ CffSubsetterContext::CffSubsetterContext( const U8* pBasePtr, int nBaseLen)
 
 CffSubsetterContext::~CffSubsetterContext( void)
 {
-	// TODO: delete[] maCffLocal;
 }
 
 // --------------------------------------------------------------------
@@ -606,23 +640,28 @@ void CffSubsetterContext::setCharStringType( int nVal)
 
 // --------------------------------------------------------------------
 
+/** Read DICT operator at mpReadPtr.
+ *
+ * Sets the attributes of CffSubsetterContext::mpCffLocal
+ */
 void CffSubsetterContext::readDictOp( void)
 {
 	ValType nVal = 0;
-    int nInt = 0;
+	int nInt = 0;
 	const U8 c = *mpReadPtr;
-	if( c <= 21 ) {
+	if( c <= 21 ) { // we are looking at an operator
 		int nOpId = *(mpReadPtr++);
 		const char* pCmdName;
 		if( nOpId != 12)
 			pCmdName = pDictOps[ nOpId];
-		else {
+		else { // escape: the operator is indicated in the following byte
 			const U8 nExtId = *(mpReadPtr++);
 			pCmdName = pDictEscs[ nExtId];
 			nOpId = 900 + nExtId;
 		}
 
 		//TODO: if( nStackIdx > 0)
+		// The first byte of pCmdName indicates the type of operand
 		switch( *pCmdName) {
 		default: fprintf( stderr, "unsupported DictOp.type=\'%c\'\n", *pCmdName); break;
 		case 'b':	// bool
@@ -714,12 +753,10 @@ void CffSubsetterContext::readDictOp( void)
 		}
 
 		return; 
-	}
-
-	if( (c >= 32) || (c == 28) ) {
+	} else if( (c >= 32) || (c == 28) ) {
 //		--mpReadPtr;
 		read2push();
-	} else if( c == 29 ) {		// longint
+	} else if( c == 29 ) { // we are looking at a 32-bit operand
 		++mpReadPtr;			// skip 29
 		int nS32 = mpReadPtr[0] << 24;
 		nS32 += mpReadPtr[1] << 16;
@@ -730,7 +767,7 @@ void CffSubsetterContext::readDictOp( void)
 		mpReadPtr += 4;
 		nVal = static_cast<ValType>(nS32);
 		push( nVal );
-	} else if( c == 30) {		// real number
+	} else if( c == 30) { // we are looking at a real number operand
 		++mpReadPtr; // skip 30
 		const RealType fReal = readRealVal();
 		// push value onto stack
@@ -747,7 +784,7 @@ void CffSubsetterContext::read2push()
 
 	const U8*& p = mpReadPtr;
 	const U8 c = *p;
-	if( c == 28 ) {
+	if( c == 28 ) {			// -32767..+32767
 		short nS16 = (p[1] << 8) + p[2];
 		if( (sizeof(nS16) != 2) && (nS16 & (1<<15)))
 			nS16 |= (~0U) << 15;	// assuming 2s complement
@@ -1313,13 +1350,12 @@ void CffSubsetterContext::callType2Subr( bool bGlobal, int nSubrNumber)
 	const U8* const pOldReadPtr = mpReadPtr;
 	const U8* const pOldReadEnd = mpReadEnd;
 
-	int nLen = 0;
 	if( bGlobal ) {
 		nSubrNumber += mnGlobalSubrBias;
-		nLen = seekIndexData( mnGlobalSubrBase, nSubrNumber);
+		seekIndexData( mnGlobalSubrBase, nSubrNumber);
 	} else {
 		nSubrNumber += mpCffLocal->mnLocalSubrBias;
-		nLen = seekIndexData( mpCffLocal->mnLocalSubrBase, nSubrNumber);
+		seekIndexData( mpCffLocal->mnLocalSubrBase, nSubrNumber);
 	}
 
 	while( mpReadPtr < mpReadEnd)
@@ -1486,7 +1522,6 @@ RealType CffSubsetterContext::readRealVal()
 
 // --------------------------------------------------------------------
 
-// prepare to access an element inside a CFF/CID index table
 int CffSubsetterContext::seekIndexData( int nIndexBase, int nDataIndex)
 {
 	assert( (nIndexBase > 0) && (mpBasePtr + nIndexBase + 3 <= mpBaseEnd));
@@ -1527,7 +1562,6 @@ int CffSubsetterContext::seekIndexData( int nIndexBase, int nDataIndex)
 
 // --------------------------------------------------------------------
 
-// skip over a CFF/CID index table
 void CffSubsetterContext::seekIndexEnd( int nIndexBase)
 {
 	assert( (nIndexBase > 0) && (mpBasePtr + nIndexBase + 3 <= mpBaseEnd));
@@ -1666,7 +1700,8 @@ void CffSubsetterContext::initialCffRead( void)
 //		assert( mnFontDictBase == tellRel());
 		mpReadPtr = mpBasePtr + mnFontDictBase;
 		mnFDAryCount = (mpReadPtr[0]<<8) + mpReadPtr[1];
-		assert( mnFDAryCount < (int)(sizeof(maCffLocal)/sizeof(*maCffLocal)));
+		if (maCffLocal.size() < static_cast<size_t>(mnFDAryCount))
+			maCffLocal.resize(mnFDAryCount);
 
 		// read FDArray details to get access to the PRIVDICTs
 		for( int i = 0; i < mnFDAryCount; ++i) {