public bool LoadComponent(Component component, Outline outl, out ArrayList errsLoadComponent) { isChangedByRound=false; errsLoadComponent=null; int numKnotBeforeLoad=this.NumKnot; int numContBeforeLoad=this.NumCont; if (outl==null) { throw new ExceptionGMath("Outline","LoadComponent",null); //return false; } // validate OTF2Dot14[,] trOTF2Dot14=component.TrOTF2Dot14; if (trOTF2Dot14!=null) { if (Math.Abs((double)trOTF2Dot14[0,0]*(double)trOTF2Dot14[1,1]- (double)trOTF2Dot14[0,1]*(double)trOTF2Dot14[1,0])<MConsts.EPS_COMP) { if (errsLoadComponent==null) errsLoadComponent=new ArrayList(); errsLoadComponent.Add(Component.TypeErrLoadComponent.IncorrectTransform); } } bool isShiftByKnots, isShiftByVec; int indKnotAttGlyph=component.IndexKnotAttGlyph; int indKnotAttComponent=component.IndexKnotAttComponent; isShiftByKnots=((indKnotAttGlyph!=GConsts.IND_UNINITIALIZED)&& (indKnotAttComponent!=GConsts.IND_UNINITIALIZED)); isShiftByVec=(component.Shift!=null); if ((isShiftByKnots&&isShiftByVec)|| ((!isShiftByKnots)&&(!isShiftByVec))) { if (errsLoadComponent==null) errsLoadComponent=new ArrayList(); errsLoadComponent.Add(Component.TypeErrLoadComponent.IncorrectShiftSpecification); } if (isShiftByKnots) { if ((indKnotAttGlyph<0)||(indKnotAttGlyph>=this.NumKnot)) { if (errsLoadComponent==null) errsLoadComponent=new ArrayList(); errsLoadComponent.Add(Component.TypeErrLoadComponent.IncorrectIndexKnotGlyph); } if ((indKnotAttComponent<0)||(indKnotAttComponent>=outl.NumKnot)) { if (errsLoadComponent==null) errsLoadComponent=new ArrayList(); errsLoadComponent.Add(Component.TypeErrLoadComponent.IncorrectIndexKnotComponent); } } if (errsLoadComponent!=null) return true; // load VecD trShift; if (isShiftByKnots) { Knot knAttGlyph=this.KnotByInd(indKnotAttGlyph); Knot knAttComponent=outl.KnotByInd(indKnotAttComponent); if ((knAttGlyph==null)||(knAttComponent==null)) { throw new ExceptionGMath("Outline","LoadComponent",null); } trShift=knAttGlyph.Val-knAttComponent.Val; // TODO: check !!! } else { trShift=component.Shift; } MatrixD trD=new MatrixD(trOTF2Dot14,trShift); component.TrD=trD; component.NumKnot=outl.NumKnot; component.NumCont=outl.NumCont; component.IndKnotStart=numKnotBeforeLoad; component.PozContStart=numContBeforeLoad; this.OutlineAdd(outl,trD); bool isChangedByRoundCur; this.FURound(out isChangedByRoundCur); if (isChangedByRoundCur) { this.isChangedByRound=true; } return true; }
public bool IntersectComponents(Component componentA, Component componentB, ListInfoInters linters) { if ((componentA==null)||(componentB==null)) { throw new ExceptionGMath("Outline","IntersectComponents",null); //return false; } if (componentA==componentB) return true; bool res=true; for (int pozContA=componentA.PozContStart; pozContA<componentA.PozContStart+componentA.NumCont; pozContA++) { Contour contA=this.ContourByPoz(pozContA); for (int pozContB=componentB.PozContStart; pozContB<componentB.PozContStart+componentB.NumCont; pozContB++) { Contour contB=this.ContourByPoz(pozContB); if (!contA.Intersect(contB, linters)) res=false; } } return res; }
public bool AreDuplicatedComponents(Component componentA, Component componentB, out bool areDuplicated) { areDuplicated=false; if ((componentA==null)||(componentB==null)) { throw new ExceptionGMath("Outline","AreDuplicatedComponents",null); //return false; } if (componentA==componentB) return true; for (int pozContA=componentA.PozContStart; pozContA<componentA.PozContStart+componentA.NumCont; pozContA++) { Contour contA=this.ContourByPoz(pozContA); for (int pozContB=componentB.PozContStart; pozContB<componentB.PozContStart+componentB.NumCont; pozContB++) { Contour contB=this.ContourByPoz(pozContB); bool areDuplicatedCont; contA.AreDuplicated(contB, out areDuplicatedCont); if (!areDuplicatedCont) { return true; } } } areDuplicated=true; return true; }
public Component(Component component) { this.indGlyphComponent=component.IndexGlyphComponent; this.indKnotAttGlyph=component.IndexKnotAttGlyph; this.indKnotAttComponent=component.IndexKnotAttComponent; this.shift=component.Shift; this.trOTF2Dot14=component.TrOTF2Dot14; this.trD=component.TrD; this.numKnot=component.NumKnot; this.numCont=component.NumCont; this.indKnotStart=component.IndKnotStart; this.pozContStart=component.PozContStart; }
public void AddComponent(Component component) { if (component==null) return; this.components.Add(component); }
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; } } }