void AddHintMaskToList(BinaryReader reader, ref int hintStemCount) { if (foundSomeStem && current_int_count > 0) { //type2 5177.pdf //... //If hstem and vstem hints are both declared at the beginning of //a charstring, and this sequence is followed directly by the //hintmask or cntrmask operators, ... //the vstem hint operator need not be included *** #if DEBUG if ((current_int_count % 2) != 0) { throw new NotSupportedException(); } else { } #endif switch (_latestOpName) { case OperatorName.hstem: //add vstem ***( from reason above) hintStemCount += (current_int_count / 2); //save a snapshot of stem count insts.AddOp(OperatorName.vstem); _latestOpName = OperatorName.vstem; current_int_count = 0; //clear break; case OperatorName.hstemhm: //add vstem ***( from reason above) ?? hintStemCount += (current_int_count / 2); //save a snapshot of stem count insts.AddOp(OperatorName.vstem); _latestOpName = OperatorName.vstem; current_int_count = 0; //clear break; case OperatorName.vstemhm: //------- //TODO: review here? //found this in xits.otf hintStemCount += (current_int_count / 2); //save a snapshot of stem count insts.AddOp(OperatorName.vstem); _latestOpName = OperatorName.vstem; current_int_count = 0; //clear break; default: throw new NotSupportedException(); } } if (hintStemCount == 0) { if (!foundSomeStem) { hintStemCount = (current_int_count / 2); foundSomeStem = true;//? } else { throw new NotSupportedException(); } } //---------------------- //this is my hintmask extension, => to fit with our Evaluation stack int properNumberOfMaskBytes = (hintStemCount + 7) / 8; if (_reader.BaseStream.Position + properNumberOfMaskBytes >= _reader.BaseStream.Length) { throw new NotSupportedException(); } if (properNumberOfMaskBytes > 4) { int remaining = properNumberOfMaskBytes; for (; remaining > 3;) { insts.AddInt(( (_reader.ReadByte() << 24) | (_reader.ReadByte() << 16) | (_reader.ReadByte() << 8) | (_reader.ReadByte()) )); remaining -= 4; //*** } switch (remaining) { case 0: //do nothing break; case 1: insts.AddInt(_reader.ReadByte() << 24); break; case 2: insts.AddInt( (_reader.ReadByte() << 24) | (_reader.ReadByte() << 16)); break; case 3: insts.AddInt( (_reader.ReadByte() << 24) | (_reader.ReadByte() << 16) | (_reader.ReadByte() << 8)); break; default: throw new NotSupportedException(); //should not occur ! } insts.AddOp(OperatorName.hintmask_bits, properNumberOfMaskBytes); } else { //last remaining <4 bytes switch (properNumberOfMaskBytes) { case 0: default: throw new NotSupportedException(); //should not occur ! case 1: insts.AddOp(OperatorName.hintmask1, (_reader.ReadByte() << 24)); break; case 2: insts.AddOp(OperatorName.hintmask2, (_reader.ReadByte() << 24) | (_reader.ReadByte() << 16) ); break; case 3: insts.AddOp(OperatorName.hintmask3, (_reader.ReadByte() << 24) | (_reader.ReadByte() << 16) | (_reader.ReadByte() << 8) ); break; case 4: insts.AddOp(OperatorName.hintmask4, (_reader.ReadByte() << 24) | (_reader.ReadByte() << 16) | (_reader.ReadByte() << 8) | (_reader.ReadByte()) ); break; } } }
public Type2GlyphInstructionList ParseType2CharString(byte[] buffer) { //reset current_int_count = 0; foundSomeStem = false; doStemCount = true; _msBuffer.SetLength(0); _msBuffer.Position = 0; _msBuffer.Write(buffer, 0, buffer.Length); _msBuffer.Position = 0; int len = buffer.Length; // insts = new Type2GlyphInstructionList(); #if DEBUG insts.dbugMark = _dbugInstructionListMark; //if (_dbugInstructionListMark == 5) //{ //} _dbugInstructionListMark++; #endif byte b0 = 0; int hintStemCount = 0; bool cont = true; while (cont && _reader.BaseStream.Position < len) { b0 = _reader.ReadByte(); #if DEBUG //easy for debugging here _dbugCount++; if (b0 < 32) { } #endif switch (b0) { default: //else 32 -255 { if (b0 < 32) { Debug.WriteLine("err!:" + b0); return(null); } insts.AddInt(ReadIntegerNumber(b0)); if (doStemCount) { current_int_count++; } } break; case (byte)Type2Operator1.shortint: // 28 //shortint //First byte of a 3-byte sequence specifying a number. //a ShortInt value is specified by using the operator (28) followed by two bytes //which represent numbers between –32768 and + 32767.The //most significant byte follows the(28) byte s_b0 = _reader.ReadByte(); byte s_b1 = _reader.ReadByte(); insts.AddInt((short)((s_b0 << 8) | (s_b1))); // if (doStemCount) { current_int_count++; } break; //--------------------------------------------------- case (byte)Type2Operator1._Reserved0_: //??? case (byte)Type2Operator1._Reserved2_: //??? case (byte)Type2Operator1._Reserved9_: //??? case (byte)Type2Operator1._Reserved13_: //??? case (byte)Type2Operator1._Reserved15_: //??? case (byte)Type2Operator1._Reserved16_: //??? case (byte)Type2Operator1._Reserved17_: //??? //reserved, do nothing ? break; case (byte)Type2Operator1.endchar: insts.AddOp(OperatorName.endchar); cont = false; //when we found end char //stop reading this... break; case (byte)Type2Operator1.escape: //12 { b0 = _reader.ReadByte(); switch ((Type2Operator2)b0) { default: if (b0 <= 38) { Debug.WriteLine("err!:" + b0); return(null); } break; //------------------------- //4.1: Path Construction Operators case Type2Operator2.flex: insts.AddOp(OperatorName.flex); break; case Type2Operator2.hflex: insts.AddOp(OperatorName.hflex); break; case Type2Operator2.hflex1: insts.AddOp(OperatorName.hflex1); break; case Type2Operator2.flex1: insts.AddOp(OperatorName.flex1);; break; //------------------------- //4.4: Arithmetic Operators case Type2Operator2.abs: insts.AddOp(OperatorName.abs); break; case Type2Operator2.add: insts.AddOp(OperatorName.add); break; case Type2Operator2.sub: insts.AddOp(OperatorName.sub); break; case Type2Operator2.div: insts.AddOp(OperatorName.div); break; case Type2Operator2.neg: insts.AddOp(OperatorName.neg); break; case Type2Operator2.random: insts.AddOp(OperatorName.random); break; case Type2Operator2.mul: insts.AddOp(OperatorName.mul); break; case Type2Operator2.sqrt: insts.AddOp(OperatorName.sqrt); break; case Type2Operator2.drop: insts.AddOp(OperatorName.drop); break; case Type2Operator2.exch: insts.AddOp(OperatorName.exch); break; case Type2Operator2.index: insts.AddOp(OperatorName.index); break; case Type2Operator2.roll: insts.AddOp(OperatorName.roll); break; case Type2Operator2.dup: insts.AddOp(OperatorName.dup); break; //------------------------- //4.5: Storage Operators case Type2Operator2.put: insts.AddOp(OperatorName.put); break; case Type2Operator2.get: insts.AddOp(OperatorName.get); break; //------------------------- //4.6: Conditional case Type2Operator2.and: insts.AddOp(OperatorName.and); break; case Type2Operator2.or: insts.AddOp(OperatorName.or); break; case Type2Operator2.not: insts.AddOp(OperatorName.not); break; case Type2Operator2.eq: insts.AddOp(OperatorName.eq); break; case Type2Operator2.ifelse: insts.AddOp(OperatorName.ifelse); break; } StopStemCount(); } break; case (byte)Type2Operator1.rmoveto: insts.AddOp(OperatorName.rmoveto); StopStemCount(); break; case (byte)Type2Operator1.hmoveto: insts.AddOp(OperatorName.hmoveto); StopStemCount(); break; case (byte)Type2Operator1.vmoveto: insts.AddOp(OperatorName.vmoveto); StopStemCount(); break; //--------------------------------------------------------------------------- case (byte)Type2Operator1.rlineto: insts.AddOp(OperatorName.rlineto); StopStemCount(); break; case (byte)Type2Operator1.hlineto: insts.AddOp(OperatorName.hlineto); StopStemCount(); break; case (byte)Type2Operator1.vlineto: insts.AddOp(OperatorName.vlineto); StopStemCount(); break; case (byte)Type2Operator1.rrcurveto: insts.AddOp(OperatorName.rrcurveto); StopStemCount(); break; case (byte)Type2Operator1.hhcurveto: insts.AddOp(OperatorName.hhcurveto); StopStemCount(); break; case (byte)Type2Operator1.hvcurveto: insts.AddOp(OperatorName.hvcurveto); StopStemCount(); break; case (byte)Type2Operator1.rcurveline: insts.AddOp(OperatorName.rcurveline); StopStemCount(); break; case (byte)Type2Operator1.rlinecurve: insts.AddOp(OperatorName.rlinecurve); StopStemCount(); break; case (byte)Type2Operator1.vhcurveto: insts.AddOp(OperatorName.vhcurveto); StopStemCount(); break; case (byte)Type2Operator1.vvcurveto: insts.AddOp(OperatorName.vvcurveto); StopStemCount(); break; //------------------------------------------------------------------- //4.3 Hint Operators case (byte)Type2Operator1.hstem: AddStemToList(OperatorName.hstem, ref hintStemCount); break; case (byte)Type2Operator1.vstem: AddStemToList(OperatorName.vstem, ref hintStemCount); break; case (byte)Type2Operator1.vstemhm: AddStemToList(OperatorName.vstemhm, ref hintStemCount); break; case (byte)Type2Operator1.hstemhm: AddStemToList(OperatorName.hstemhm, ref hintStemCount); break; //------------------------------------------------------------------- case (byte)Type2Operator1.hintmask: AddHintMaskToList(_reader, ref hintStemCount); StopStemCount(); break; case (byte)Type2Operator1.cntrmask: AddCounterMaskToList(_reader, ref hintStemCount); StopStemCount(); break; //------------------------------------------------------------------- //4.7: Subroutine Operators case (byte)Type2Operator1.callsubr: insts.AddOp(OperatorName.callsubr); StopStemCount(); break; case (byte)Type2Operator1.callgsubr: insts.AddOp(OperatorName.callgsubr); StopStemCount(); break; case (byte)Type2Operator1._return: insts.AddOp(OperatorName._return); StopStemCount(); break; } } return(insts); }