1 /*
2    Source File : Type1ToType2Converter.h
3 
4 
5    Copyright 2011 Gal Kahana PDFWriter
6 
7    Licensed under the Apache License, Version 2.0 (the "License");
8    you may not use this file except in compliance with the License.
9    You may obtain a copy of the License at
10 
11        http://www.apache.org/licenses/LICENSE-2.0
12 
13    Unless required by applicable law or agreed to in writing, software
14    distributed under the License is distributed on an "AS IS" BASIS,
15    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16    See the License for the specific language governing permissions and
17    limitations under the License.
18 
19 
20 */
21 #pragma once
22 
23 #include "EStatusCode.h"
24 #include "IType1InterpreterImplementation.h"
25 
26 #include <vector>
27 #include <map>
28 #include <set>
29 #include <string>
30 
31 
32 
33 class IByteWriter;
34 class Type1Input;
35 
36 struct ConversionNode
37 {
38 	unsigned short mMarkerType;
39 	LongList mOperands;
40 };
41 
42 typedef std::list<ConversionNode> ConversionNodeList;
43 
44 struct Stem
45 {
StemStem46 	Stem() {mOrigin = 0; mExtent = 0;}
StemStem47 	Stem(const Stem& inStem){mOrigin = inStem.mOrigin;mExtent = inStem.mExtent;}
StemStem48 	Stem(long inOrigin,long inExtent){mOrigin = inOrigin; mExtent = inExtent;}
49 
50 	long mOrigin;
51 	long mExtent;
52 };
53 
54 class StemLess : public std::binary_function<const Stem,const Stem,bool>
55 {
56 public:
operator()57 	bool operator( ) (const Stem& inLeft,
58 						const Stem& inRight ) const
59 	{
60 		if(inLeft.mOrigin == inRight.mOrigin)
61 			return inLeft.mExtent < inRight.mExtent;
62 		else
63 			return inLeft.mOrigin < inRight.mOrigin;
64 	}
65 };
66 
67 typedef std::vector<const Stem*> StemVector;
68 typedef std::set<Stem,StemLess> StemSet;
69 typedef std::set<size_t> SizeTSet;
70 typedef std::map<Stem,size_t,StemLess> StemToSizeTMap;
71 
72 class Type1ToType2Converter : IType1InterpreterImplementation
73 {
74 public:
75 	Type1ToType2Converter(void);
76 	~Type1ToType2Converter(void);
77 
78 	PDFHummus::EStatusCode WriteConvertedFontProgram(const std::string& inGlyphName,
79 										  Type1Input* inType1Input,
80 										  IByteWriter* inByteWriter);
81 
82 	// IType1InterpreterImplementation
83 	virtual PDFHummus::EStatusCode Type1Hstem(const LongList& inOperandList);
84 	virtual PDFHummus::EStatusCode Type1Vstem(const LongList& inOperandList);
85 	virtual PDFHummus::EStatusCode Type1VMoveto(const LongList& inOperandList);
86 	virtual PDFHummus::EStatusCode Type1RLineto(const LongList& inOperandList);
87 	virtual PDFHummus::EStatusCode Type1HLineto(const LongList& inOperandList);
88 	virtual PDFHummus::EStatusCode Type1VLineto(const LongList& inOperandList);
89 	virtual PDFHummus::EStatusCode Type1RRCurveto(const LongList& inOperandList);
90 	virtual PDFHummus::EStatusCode Type1ClosePath(const LongList& inOperandList);
91 	virtual Type1CharString* GetSubr(long inSubrIndex);
92 	virtual PDFHummus::EStatusCode Type1Return(const LongList& inOperandList);
93 	virtual PDFHummus::EStatusCode Type1Hsbw(const LongList& inOperandList);
94 	virtual PDFHummus::EStatusCode Type1Endchar(const LongList& inOperandList);
95 	virtual PDFHummus::EStatusCode Type1RMoveto(const LongList& inOperandList);
96 	virtual PDFHummus::EStatusCode Type1HMoveto(const LongList& inOperandList);
97 	virtual PDFHummus::EStatusCode Type1VHCurveto(const LongList& inOperandList);
98 	virtual PDFHummus::EStatusCode Type1HVCurveto(const LongList& inOperandList);
99 	virtual PDFHummus::EStatusCode Type1DotSection(const LongList& inOperandList);
100 	virtual PDFHummus::EStatusCode Type1VStem3(const LongList& inOperandList);
101 	virtual PDFHummus::EStatusCode Type1HStem3(const LongList& inOperandList);
102 	virtual PDFHummus::EStatusCode Type1Seac(const LongList& inOperandList);
103 	virtual PDFHummus::EStatusCode Type1Sbw(const LongList& inOperandList);
104 	virtual PDFHummus::EStatusCode Type1Div(const LongList& inOperandList);
105 	virtual bool IsOtherSubrSupported(long inOtherSubrsIndex);
106 	virtual PDFHummus::EStatusCode CallOtherSubr(const LongList& inOperandList,LongList& outPostScriptOperandStack);
107 	virtual PDFHummus::EStatusCode Type1Pop(const LongList& inOperandList,const LongList& inPostScriptOperandStack);
108 	virtual PDFHummus::EStatusCode Type1SetCurrentPoint(const LongList& inOperandList);
109 	virtual PDFHummus::EStatusCode Type1InterpretNumber(long inOperand);
110 	virtual unsigned long GetLenIV();
111 
112 
113 private:
114 	Type1Input* mHelper;
115 	ConversionNodeList mConversionProgram;
116 	bool mHintReplacementEncountered;
117 	bool mHintAdditionEncountered;
118 	bool mFirstPathConstructionEncountered;
119     bool mIsFirst2Coordinates;
120 	long mSideBearing[2];
121 	long mWidth[2];
122 
123 	// hints handling
124 	StemToSizeTMap mHStems;
125 	StemToSizeTMap mVStems;
126 	SizeTSet mCurrentHints;
127 
128 	// flex handling
129 	bool mInFlexCollectionMode;
130 	LongList mFlexParameters;
131 
132 
133 	PDFHummus::EStatusCode RecordOperatorWithParameters(unsigned short inMarkerType,const LongList& inOperandList);
134 	void RecordOperatorMarker(unsigned short inMarkerType);
135 	PDFHummus::EStatusCode AddHStem(long inOrigin,long inExtent);
136 	PDFHummus::EStatusCode AddVStem(long inOrigin,long inExtent);
137 	void ConvertStems();
138 	ConversionNodeList::iterator CollectHintIndexesFromHere(ConversionNodeList::iterator inFirstStemHint);
139 	ConversionNodeList::iterator InsertOperatorMarker(unsigned short inMarkerType,ConversionNodeList::iterator inInsertPosition);
140 	void SetupStemHintsInNode(const StemVector& inStems,long inOffsetCoordinate,ConversionNode& refNode);
141 	bool IsStemHint(unsigned short inMarkerType);
142 	long GenerateHintMaskFromCollectedHints();
143 	void ConvertPathConsturction();
144 	ConversionNodeList::iterator MergeSameOperators(ConversionNodeList::iterator inStartingNode);
145 	ConversionNodeList::iterator MergeSameOperators(ConversionNodeList::iterator inStartingNode, unsigned short inOpCode);
146 	ConversionNodeList::iterator MergeAltenratingOperators(ConversionNodeList::iterator inStartingNode,
147 														   unsigned short inAlternatingOpcode);
148 	void AddInitialWidthParameter();
149 	PDFHummus::EStatusCode WriteProgramToStream(IByteWriter* inByteWriter);
150 };
151