public void ReadGGO(int indexGlyph, out Outline outl, DIAction dia) { this.m_validator.DIA = dia; outl = null; GConsts.TypeGlyph typeGlyph; this.ReadTypeGlyph(indexGlyph, out typeGlyph, dia); if (typeGlyph != GConsts.TypeGlyph.Simple) { return; } int offsStart, length; if (!this.m_tableLoca.GetValidateEntryGlyf(indexGlyph, out offsStart, out length, this.m_validator, this.m_font)) { return; } MBOBuffer buffer = this.m_tableGlyf.Buffer; int iKnot; ushort[] arrIndKnotEnd; short[] arrXRel, arrYRel; byte[] arrFlag; int numCont; try { numCont = buffer.GetShort((uint)(offsStart + (int)Table_glyf.FieldOffsets.numCont)); arrIndKnotEnd = new ushort [numCont]; for (short iCont = 0; iCont < numCont; iCont++) { arrIndKnotEnd[iCont] = buffer.GetUshort((uint)(offsStart + Table_glyf.FieldOffsets.nextAfterHeader + iCont * 2)); } int numKnot = arrIndKnotEnd[numCont - 1] + 1; uint offsInstrLength = (uint)(offsStart + Table_glyf.FieldOffsets.nextAfterHeader + 2 * numCont); ushort lengthInstr = buffer.GetUshort(offsInstrLength); uint offsInstr = offsInstrLength + 2; uint offsFlag = offsInstr + lengthInstr; arrFlag = new byte [numKnot]; iKnot = 0; // index of flag in array flags uint offsCur = offsFlag; // counter of flag in the file while (iKnot < numKnot) { byte flag = buffer.GetByte(offsCur++); arrFlag[iKnot++] = flag; bool toRepeat = ((flag & (byte)(Table_glyf.MaskFlagKnot.toRepeat)) != 0); if (toRepeat) { byte numRepeat = buffer.GetByte(offsCur++); for (byte iRepeat = 0; iRepeat < numRepeat; iRepeat++) { arrFlag[iKnot++] = flag; } } } arrXRel = new short [numKnot]; arrYRel = new short [numKnot]; // read data for x-coordinates for (iKnot = 0; iKnot < numKnot; iKnot++) { if ((arrFlag[iKnot] & (byte)(Table_glyf.MaskFlagKnot.isXByte)) != 0) { byte xRel = buffer.GetByte(offsCur++); if ((arrFlag[iKnot] & (byte)(Table_glyf.MaskFlagKnot.isXSameOrPozitive)) != 0) { arrXRel[iKnot] = xRel; } else { arrXRel[iKnot] = (short)(-xRel); } } else { if ((arrFlag[iKnot] & (byte)(Table_glyf.MaskFlagKnot.isXSameOrPozitive)) != 0) { arrXRel[iKnot] = 0; } else { arrXRel[iKnot] = buffer.GetShort(offsCur); offsCur += 2; } } } // read data for y-coordinates for (iKnot = 0; iKnot < numKnot; iKnot++) { if ((arrFlag[iKnot] & (byte)(Table_glyf.MaskFlagKnot.isYByte)) != 0) { byte yRel = buffer.GetByte(offsCur++); if ((arrFlag[iKnot] & (byte)(Table_glyf.MaskFlagKnot.isYSameOrPozitive)) != 0) { arrYRel[iKnot] = yRel; } else { arrYRel[iKnot] = (short)(-yRel); } } else { if ((arrFlag[iKnot] & (byte)(Table_glyf.MaskFlagKnot.isYSameOrPozitive)) != 0) { arrYRel[iKnot] = 0; } else { arrYRel[iKnot] = buffer.GetShort(offsCur); offsCur += 2; } } } if (offsCur - 2 >= offsStart + length) { throw new System.IndexOutOfRangeException(); } } catch (System.IndexOutOfRangeException) { this.m_validator.Error( E._GEN_E_OffsetExceedsTableLength, (OTTag)"glyf"); return; } try { short xAbs = 0; short yAbs = 0; int indKnotStart, indKnotEnd = -1; outl = new Outline(); for (ushort iCont = 0; iCont < numCont; iCont++) { indKnotStart = indKnotEnd + 1; indKnotEnd = arrIndKnotEnd[iCont]; Contour cont = null; cont = new Contour(); for (iKnot = indKnotStart; iKnot <= indKnotEnd; iKnot++) { xAbs += arrXRel[iKnot]; yAbs += arrYRel[iKnot]; bool isOn = ((arrFlag[iKnot] & ((byte)(Table_glyf.MaskFlagKnot.isOnCurve))) != 0); Knot knot = new Knot(iKnot, xAbs, yAbs, isOn); cont.KnotAdd(knot); } outl.ContourAdd(cont); } } catch { outl.ClearDestroy(); outl = null; } }