public void ReadGGC(int indexGlyph, out Composite comp, DIAction dia) { this.m_validator.DIA=dia; comp=null; GConsts.TypeGlyph typeGlyph; this.ReadTypeGlyph(indexGlyph, out typeGlyph, dia); if (typeGlyph!=GConsts.TypeGlyph.Composite) 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; uint offsCur=(uint)(offsStart+Table_glyf.FieldOffsets.nextAfterHeader); bool isLast=false; try { Component component; while (!isLast) { ushort flags=buffer.GetUshort(offsCur); isLast=((flags&(ushort)Table_glyf.MaskFlagComponent.MORE_COMPONENTS)==0); offsCur+=2; ushort indGlyphCur=buffer.GetUshort(offsCur); // TODO: save component=new Component(indGlyphCur); // TODO: validate indGlyph is in right boundaries // TODO: add Relations to FManager offsCur+=2; bool weHaveAScale=((flags&(ushort)Table_glyf.MaskFlagComponent.WE_HAVE_A_SCALE)!=0); bool weHaveAnXAndYScale=((flags&(ushort)Table_glyf.MaskFlagComponent.WE_HAVE_AN_X_AND_Y_SCALE)!=0); bool weHaveATwoByTwo=((flags&(ushort)Table_glyf.MaskFlagComponent.WE_HAVE_A_TWO_BY_TWO)!=0); int cnt=0; if (weHaveAScale) cnt++; if (weHaveAnXAndYScale) cnt++; if (weHaveATwoByTwo) cnt++; if (cnt>1) { this.m_validator.Error(T.T_NULL, E.glyf_E_CompositeAmbigousTransform, (OTTag)"glyf", "Index Component: "+indGlyphCur); return; } if ((flags&(ushort)Table_glyf.MaskFlagComponent.RESERVED)!=0) { this.m_validator.Warning(T.T_NULL, W.glyf_W_CompositeReservedBit, (OTTag)"glyf", "Index Component: "+indGlyphCur); } int arg1, arg2; if ((flags&(ushort)Table_glyf.MaskFlagComponent.ARG_1_AND_2_ARE_WORDS)!=0) { arg1=(int)buffer.GetShort(offsCur); offsCur+=2; arg2=(int)buffer.GetShort(offsCur); offsCur+=2; } else { arg1=(int)buffer.GetSbyte(offsCur); offsCur+=1; arg2=(int)buffer.GetSbyte(offsCur); offsCur+=1; } // TODO: validate bounding boxes // TODO: check that NOT BOTH shift & knots are initialized, but ONE of them IS initialized // TODO: validate that indKnots (both!) are in the right boundaries // TODO: validate that a single-point contour in any glyph is used as attachment point in at least one other glyph if ((flags&(ushort)Table_glyf.MaskFlagComponent.ARGS_ARE_XY_VALUES)!=0) { component.Shift=new VecD(arg1,arg2); } else { component.IndexKnotAttGlyph=arg1; component.IndexKnotAttComponent=arg2; } // TODO: check that matrix is non-degenerated (if not null) if (weHaveAScale) { OTF2Dot14[,] m=new OTF2Dot14[2,2]; m[0,0]=buffer.GetF2Dot14(offsCur); /* // for debug only - begin if (indGlyphCur==272) { m[0,0]=new OTF2Dot14(30390); } // for debug only - end */ offsCur+=2; m[1,1]=m[0,0]; component.TrOTF2Dot14=m; } else if (weHaveAnXAndYScale) { OTF2Dot14[,] m=new OTF2Dot14[2,2]; m[0,0]=buffer.GetF2Dot14(offsCur); offsCur+=2; m[1,1]=buffer.GetF2Dot14(offsCur); offsCur+=2; component.TrOTF2Dot14=m; } else if (weHaveATwoByTwo) { OTF2Dot14[,] m=new OTF2Dot14[2,2]; m[0,0]=buffer.GetF2Dot14(offsCur); offsCur+=2; m[0,1]=buffer.GetF2Dot14(offsCur); offsCur+=2; m[1,0]=buffer.GetF2Dot14(offsCur); offsCur+=2; m[1,1]=buffer.GetF2Dot14(offsCur); offsCur+=2; component.TrOTF2Dot14=m; } if ((flags&(ushort)Table_glyf.MaskFlagComponent.WE_HAVE_INSTRUCTIONS)!=0) { ushort numInstr=buffer.GetUshort(offsCur); offsCur+=2; if (offsCur+numInstr>buffer.GetLength()) { throw new System.IndexOutOfRangeException(); } } if (comp==null) comp=new Composite(); comp.AddComponent(component); } } catch (System.IndexOutOfRangeException) { this.m_validator.Error( E._GEN_E_OffsetExceedsTableLength, (OTTag)"glyf"); if (comp != null) { comp.ClearDestroy(); comp=null; } } }
internal StatusGV.TypeStatusExec ValidateCompSource(GErrList gerrlist) { if (this.bbox!=null) { this.bbox.Clear(); this.bbox=null; } if (this.comp!=null) { this.comp.ClearDestroy(); this.comp=null; } if (this.outl!=null) { this.outl.ClearDestroy(); this.outl=null; } if (this.typeGlyph==GConsts.TypeGlyph.Empty) { return StatusGV.TypeStatusExec.Completed; } if (this.typeGlyph!=GConsts.TypeGlyph.Composite) { //throw new ExceptionGlyph("Glyph","ValidateCompSource",null); return StatusGV.TypeStatusExec.Aborted; } DIAction dia=DIActionBuilder.DIA(gerrlist,"DIAFunc_AddToListUnique"); gerrlist.DIW=new DIWrapperSource(this.index,this.typeGlyph,GScope.TypeGScope._GGB_); I_IOGlyphs i_IOGlyphs=this.fm.IIOGlyphs; if (i_IOGlyphs==null) { //throw new ExceptionGlyph("Glyph","ValidateCompSource",null); return StatusGV.TypeStatusExec.Aborted; } i_IOGlyphs.ReadGGB(this.index, out this.bbox, dia); i_IOGlyphs.ReadGGC(this.index, out this.comp, dia); if (this.comp!=null) { this.fm.OnGComposite(this.index); } gerrlist.DIW=null; return StatusGV.TypeStatusExec.Completed; }
public void ClearRelease() { if (this.bbox!=null) { this.bbox.Clear(); this.bbox=null; } if (this.comp!=null) { this.comp.ClearRelease(); this.comp=null; } if (this.outl!=null) { this.outl.ClearRelease(); this.outl=null; } this.index=GConsts.IND_UNINITIALIZED; this.fm=null; }
public void ClearDestroy() { if (this.bbox!=null) { this.bbox.Clear(); this.bbox=null; } if (this.comp!=null) { this.comp.ClearDestroy(); this.comp=null; } if (this.outl!=null) { this.outl.ClearDestroy(); this.outl=null; } if (this.statusGV!=null) { this.statusGV=null; } this.index=GConsts.IND_UNINITIALIZED; this.fm=null; }
private void CleanUpOnNonCompletedGV(DefsGV.TypeGV typeGV) { /* * TRY/CATCH function */ switch (typeGV) { case DefsGV.TypeGV.ValidateTypeGlyphSource: this.typeGlyph=GConsts.TypeGlyph.Undef; break; case DefsGV.TypeGV.ValidateSimpSource: if (this.bbox!=null) this.bbox=null; if (this.outl!=null) { try { this.outl.ClearDestroy(); } catch(System.Exception) { } this.outl=null; } break; case DefsGV.TypeGV.ValidateCompSource: if (this.bbox!=null) this.bbox=null; if (this.comp!=null) { try { this.comp.ClearDestroy(); } catch(System.Exception) { } this.comp=null; } break; case DefsGV.TypeGV.ValidateCompBind: if (this.outl!=null) { try { this.outl.ClearDestroy(); } catch(System.Exception) { } this.outl=null; } break; } /* private int index; private GConsts.TypeGlyph typeGlyph; BoxD bbox; Outline outl; Composite comp; private FManager fm; private StatusGV[] statusGV; */ }
public Glyph(int indexGlyph, FManager fm) { this.fm=fm; this.index=indexGlyph; this.typeGlyph=GConsts.TypeGlyph.Uninitialized; this.bbox=null; this.outl=null; this.comp=null; this.statusGV=new StatusGV[DefsGV.NumTest]; for (int iTest=0; iTest<DefsGV.NumTest; iTest++) { this.statusGV[iTest]=new StatusGV(); } }