Example #1
0
        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;
            }
        }