public Outline(Outline outl): this() { if (outl==null) { throw new ExceptionGMath("Outline","Outline",null); } Contour contCopy; foreach (Contour cont in this.conts) { contCopy=new Contour(cont); this.conts.Add(contCopy); } this.isChangedByRound=outl.IsChangedByRound; }
public bool IsMisoriented(Outline outl, out bool isMisoriented) { isMisoriented=true; if (this.NumKnot<=2) { isMisoriented=false; return true; } MConsts.TypeInnerOuter typeBySelfOrientation, typeByOutline; this.InnerOuterBySelfOrientation(out typeBySelfOrientation); this.InnerOuterByOutline(outl, out typeByOutline); if ((typeBySelfOrientation==MConsts.TypeInnerOuter.Undef)|| (typeByOutline==MConsts.TypeInnerOuter.Undef)) { //Debug.Assert(false, "Contour: Misoriented"); return false; } isMisoriented=(typeBySelfOrientation!=typeByOutline); return true; }
public void InnerOuterByOutline(Outline outl, out MConsts.TypeInnerOuter typeInnerOuter) { typeInnerOuter=MConsts.TypeInnerOuter.Undef; RayD ray; CParam parStartRay; MConsts.TypeParity typeParityContour, typeParityAll=MConsts.TypeParity.Even; int iTrial; for (iTrial=0; iTrial<MConsts.MAX_RAY_INTERS_TRIAL; iTrial++) { try { typeParityAll=MConsts.TypeParity.Even; if (!this.RayAlmostNormal(out ray, out parStartRay)) { continue; } int pozCont; for (pozCont=0; pozCont<outl.NumCont; pozCont++) { Contour cont=outl.ContourByPoz(pozCont); if (cont==this) continue; if (!cont.RayParity(ray,null,out typeParityContour)) break; if (typeParityContour==MConsts.TypeParity.Undef) break; typeParityAll=(typeParityAll==typeParityContour)? MConsts.TypeParity.Even: MConsts.TypeParity.Odd; } if (pozCont!=outl.NumCont) continue; // parity failed for one of contours } catch (ExceptionGMath) { continue; } break; // the result is clear, stop trials } if (iTrial==MConsts.MAX_RAY_INTERS_TRIAL) { return; // typeInnerOuter is undefined } typeInnerOuter=(typeParityAll==MConsts.TypeParity.Even)? MConsts.TypeInnerOuter.Outer: MConsts.TypeInnerOuter.Inner; }
public bool OutlineAdd(Outline outl, MatrixD trD) { if ((outl==null)||(trD==null)) { throw new ExceptionGMath("Outline","OutlineAdd",null); //return false; } for (int pozCont=0; pozCont<outl.NumCont; pozCont++) { Contour cont=new Contour(outl.ContourByPoz(pozCont)); cont.Transform(trD); this.ContourAdd(cont); } this.ReNumber(); return true; }
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; }
internal StatusGV.TypeStatusExec ValidateCompBind(GErrList gerrlist) { /* * ASSUMPTION: - the glyph is composite and Comp is already * read * - clears outline that is already * built in case of failure to load one * of components */ if (this.outl!=null) { this.outl.ClearDestroy(); this.outl=null; } GErr gerr; bool isCircular=this.fm.PathCompBind.Contains(this.index); if (isCircular) { int numGlyph=this.fm.PathCompBind.Count; int[] pathCompBind=new int[numGlyph+1]; for (int iGlyph=0; iGlyph<numGlyph; iGlyph++) { pathCompBind[iGlyph]=(int)this.fm.PathCompBind[iGlyph]; } pathCompBind[numGlyph]=this.index; gerr=new GErrComponentCircularDependency(this.index, this.index, pathCompBind); gerrlist.Add(gerr); this.fm.PathCompBind.Clear(); return StatusGV.TypeStatusExec.Completed; } if (this.outl!=null) { this.outl.ClearReset(); this.outl=null; } if (this.comp==null) { //throw new ExceptionGlyph("Glyph","ValidateCompBind",null); return StatusGV.TypeStatusExec.Aborted; } this.fm.PathCompBind.Add(this.index); //throw new ArgumentOutOfRangeException(); if (this.comp.NumComponent==0) { this.outl=new Outline(); gerr=new GErrComponentEmpty(this.index,GConsts.IND_UNDEFINED); gerrlist.Add(gerr); return StatusGV.TypeStatusExec.Completed; } foreach (Component component in this.comp) { int indGlyphComponent=component.IndexGlyphComponent; if ((indGlyphComponent<0)||(indGlyphComponent>=this.fm.FNumGlyph)) { gerr=new GErrComponentIndexGlyph(this.index,indGlyphComponent); gerrlist.Add(gerr); this.fm.PathCompBind.Clear(); if (this.outl!=null) { this.outl.ClearDestroy(); this.outl=null; } return StatusGV.TypeStatusExec.Completed; } Glyph glyphComponent=this.fm.GGet(indGlyphComponent); if (glyphComponent==null) { gerr=new GErrComponentLoadFailure(this.index,indGlyphComponent); gerrlist.Add(gerr); this.fm.PathCompBind.Clear(); if (this.outl!=null) { this.outl.ClearDestroy(); this.outl=null; } return StatusGV.TypeStatusExec.Completed; } if (glyphComponent.typeGlyph==GConsts.TypeGlyph.Empty) { gerr=new GErrComponentEmpty(this.index,indGlyphComponent); gerrlist.Add(gerr); continue; } else { if (glyphComponent.Outl==null) { gerr=new GErrComponentLoadFailure(this.index,indGlyphComponent); gerrlist.Add(gerr); this.fm.PathCompBind.Clear(); if (this.outl!=null) { this.outl.ClearDestroy(); this.outl=null; } return StatusGV.TypeStatusExec.Completed; } } if (this.outl==null) { this.outl=new Outline(); } ArrayList errsLoadComponent; if (!this.outl.LoadComponent(component, glyphComponent.outl, out errsLoadComponent)) { this.fm.PathCompBind.Clear(); if (this.outl!=null) { this.outl.ClearDestroy(); this.outl=null; } //throw new ExceptionGlyph("Glyph","ValidateCompBind",null); return StatusGV.TypeStatusExec.Aborted; } if (errsLoadComponent!=null) { foreach (Component.TypeErrLoadComponent errLoadComponent in errsLoadComponent) { gerr=null; switch (errLoadComponent) { case Component.TypeErrLoadComponent.IncorrectShiftSpecification: gerr=new GErrComponentIncorrectShift(this.index, component.IndexGlyphComponent); break; case Component.TypeErrLoadComponent.IncorrectIndexKnotGlyph: gerr=new GErrComponentIndexKnot(this.index, component.IndexGlyphComponent, component.IndexKnotAttGlyph, true); break; case Component.TypeErrLoadComponent.IncorrectIndexKnotComponent: gerr=new GErrComponentIndexKnot(this.index, component.IndexGlyphComponent, component.IndexKnotAttComponent, false); break; case Component.TypeErrLoadComponent.IncorrectTransform: gerr=new GErrComponentIncorrectTransform(this.index, component.IndexGlyphComponent, component.TrOTF2Dot14); break; } gerrlist.Add(gerr); } if (this.outl!=null) { this.outl.ClearDestroy(); this.outl=null; } this.fm.PathCompBind.Clear(); return StatusGV.TypeStatusExec.Completed; } } this.fm.PathCompBind.RemoveAt(this.fm.PathCompBind.Count-1); return StatusGV.TypeStatusExec.Completed; }
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; } }
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(); } }