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;
                }
            }
        }
Beispiel #2
0
        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;        
        }
Beispiel #3
0
 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;
 }
Beispiel #4
0
        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;

        }
Beispiel #5
0
        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;
            */



        }
Beispiel #6
0
        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();
            }
        }