Example #1
0
 public Object3D(Area area, ByteSegment Memory, Object3DCategory Kind)
 {
     this.area            = area;
     this.Kind            = Kind;
     this.memory          = Memory;
     this.trs.scale.Whole = 1;
 }
Example #2
0
 private Runtime(Runtime Source) : this(Source.script, Source.rom)
 {
     this.ended         = Source.ended;
     this.returnCode    = Source.returnCode;
     this.segmentOffset = Source.segmentOffset;
     this.data          = Source.data;
 }
Example #3
0
        public static void Address(
            ByteSegment memory,
            ref string address_cache,
            out ByteSegment segment,
            out ROM_Address address,
            out string address_string)
        {
            if (null == (object)address_cache)
            {
                var address_for_string = memory.ROM_Address();
                address = address_for_string;
                System.Threading.Interlocked.CompareExchange(ref address_cache, address.ToString(), null);
#if DEBUG
                //why not make sure the parser works..
                if (address != ROM_Address.Parse(address_cache))
                {
                    throw new InvalidProgramException("critical failure");
                }
#endif
            }
            else
            {
                address = memory.ROM_Address();
            }
            segment        = memory;
            address_string = address_cache;
        }
Example #4
0
 protected virtual bool RunCommand(
     Runtime rt,
     CommandInfo info,
     ref ByteSegment cmd)
 {
     throw new System.InvalidOperationException("Either implement RunCommand or do not invoke base.RunCommand! Type:" + GetType().Name);
 }
Example #5
0
 public static uint bytesToUInt32(ByteSegment b, int offset = 0)
 {
     return
         (((uint)b[offset + 3]) |
          ((uint)b[offset + 2] << 8) |
          ((uint)b[offset + 1] << 16) |
          ((uint)b[offset] << 24));
 }
Example #6
0
        /// <summary>
        /// creates a raw texture from data. setting its tag to the segment.
        /// if data is empty and or both width and height are zero, other arguments are ignored and NullTexture is returned.
        /// otherwise width or height cannot be zero.
        ///
        /// </summary>
        /// <param name="format"></param>
        /// <param name="data"></param>
        /// <param name="width"></param>
        /// <param name="height"></param>
        /// <returns>never null</returns>
        public static Raw decodeTexture(byte format, ByteSegment data, byte width, byte height)
        {
            if ((width == 0) ^ (height == 0))
            {
                throw new ArgumentException("0", width == 0 ? "width" : "height");
            }

            return(data.Length == 0 || (width == 0 && height == 0) ? NullTexture : new Raw(data.ToArray(), width, height, Once.Formats[format], data));
        }
Example #7
0
        private static int EncodeInternal <BufferT>(ref ByteSegment inputBuffer, ref BufferT outputBuffer, out int inputUsed, out int outputUsed)
        {
            inputUsed = outputUsed = 0;
            var hexChars = HexChars;

            if (inputBuffer.Count == 0 || inputBuffer.Array == null)
            {
                return(0);
            }

            var input = inputBuffer.Array;
            var inputEnd = inputBuffer.Offset + inputBuffer.Count;
            var inputOffset = inputBuffer.Offset;
            int outputOffset, originalOutputOffset, outputCapacity;

            if (outputBuffer is ByteSegment)
            {
                var byteSegment = (ByteSegment)(object)outputBuffer;
                outputOffset   = originalOutputOffset = byteSegment.Offset;
                outputCapacity = byteSegment.Count;
            }
            else if (outputBuffer is CharSegment)
            {
                var charSegment = (CharSegment)(object)outputBuffer;
                outputOffset   = originalOutputOffset = charSegment.Offset;
                outputCapacity = charSegment.Count;
            }
            else
            {
                throw new InvalidOperationException("Unknown type of output buffer: " + typeof(BufferT));
            }

            for (; inputOffset < inputEnd && outputCapacity >= 2; inputOffset++)
            {
                var value = input[inputOffset];

                if (outputBuffer is ByteSegment)
                {
                    var outputSegment = (ByteSegment)(object)outputBuffer;
                    outputSegment.Array[outputOffset++] = (byte)hexChars[(value >> 4) & 15u];
                    outputSegment.Array[outputOffset++] = (byte)hexChars[value & 15u];
                }
                else
                {
                    var outputSegment = (CharSegment)(object)outputBuffer;
                    outputSegment.Array[outputOffset++] = hexChars[(value >> 4) & 15u];
                    outputSegment.Array[outputOffset++] = hexChars[value & 15u];
                }
                outputCapacity -= 2;
            }
            inputUsed  = inputOffset - inputBuffer.Offset;
            outputUsed = outputOffset - originalOutputOffset;

            return(outputUsed);
        }
Example #8
0
 public static Vector3s bytesToVector3s(ByteSegment b, int offset = 0)
 {
     unchecked
     {
         return(new Vector3s
         {
             Z = bytesToInt16(b, offset + 4),
             Y = bytesToInt16(b, offset + 2),
             X = bytesToInt16(b, offset),
         });
     }
 }
Example #9
0
 public static Vector3c bytesToVector3c(ByteSegment b, int offset = 0)
 {
     unchecked
     {
         return(new Vector3c
         {
             Z = (sbyte)b[offset + 2],
             Y = (sbyte)b[offset + 1],
             X = (sbyte)b[offset],
         });
     }
 }
Example #10
0
 public Warp(Area area, ByteSegment memory, bool isPaintingWarp)
 {
     if (null == (object)area)
     {
         throw new ArgumentNullException("area");
     }
     if (0 == memory.Length)
     {
         throw new ArgumentException("length is zero", "memory");
     }
     this.area           = area;
     this.memory         = memory;
     this.isPaintingWarp = isPaintingWarp;
 }
Example #11
0
            static public bool GetCommand(
                Runtime rt,
                out ByteSegment cmd,
                out CommandInfo info)
            {
                byte Length;

                if (rt.ended || rt.segmentOffset.Offset >= rt.data.Length)
                {
                    cmd      = default(ByteSegment);
                    rt.ended = true;
                    info     = null;
                }
                else
                {
                    info = rt.script.Commands[rt.data[rt.segmentOffset.Offset]];
                    if (null == info)
                    {
                        rt.ended = true;
                        cmd      = default(ByteSegment);
                    }
                    else
                    {
                        if (0 != (info.Traits & (CommandInfoTraits.HasNonZeroBB | CommandInfoTraits.SecondByteHoldsLength)) &&
                            1 < (rt.data.Length - rt.segmentOffset.Offset) &&
                            rt.data[rt.segmentOffset.Offset + 1] != 0 &&
                            0 != (CommandInfoTraits.SecondByteHoldsLength & (info = info.Next).Traits))
                        {
                            Length = rt.data[rt.segmentOffset.Offset + 1];
                        }
                        else
                        {
                            Length = info.Length;
                        }

                        if (0 == Length || (Length > (rt.data.Length - rt.segmentOffset.Offset)))
                        {
                            rt.ended = true;
                            cmd      = default(ByteSegment);
                        }
                        else
                        {
                            rt.data.Segment((uint)rt.segmentOffset.Offset, Length, out cmd);
                            rt.ended = 0 == cmd.Length;
                        }
                    }
                }
                return(!rt.ended);
            }
Example #12
0
 public Level(ROM rom, ByteSegment memory, ushort levelID, ushort startArea)
 {
     if (null == (object)rom)
     {
         throw new ArgumentNullException("rom");
     }
     if (memory.Length == 0)
     {
         throw new ArgumentException("zero in size", "memory");
     }
     this.rom            = rom;
     this.memory         = memory;
     this.levelID        = levelID;
     this._currentAreaID = (-1) - startArea;
     LevelObjectCombos.Clear();
     AddMacroObjectEntries();
 }
Example #13
0
        unsafe private static ByteSegment getSpecialObjectEntry(ROM rom, byte presetID)
        {
            ByteSegment o = default(ByteSegment);
            //ROM rom = ROM.Instance;
            uint offset = Globals.special_preset_table;
            byte got    = rom.Bytes[(int)offset];

            while (got != 0xFF)
            {
                if (got == presetID)
                {
                    rom.Bytes.Segment(offset, 8u, out o);
                    break;
                }
                offset += 8;
                got     = rom.Bytes[(int)offset];
            }

            return(o);
        }
Example #14
0
 public static sbyte bytesToSByte(ByteSegment b, int offset = 0)
 {
     return(unchecked ((sbyte)b[offset]));
 }
Example #15
0
 void IMemoryProperty.Address(out ByteSegment segment, out ROM_Address address, out string address_string)
 {
     IMemoryPropertyUtility.Address(memory, ref mem_adr, out segment, out address, out address_string);
 }
Example #16
0
 public static void Load(out F3D_Vertex v, ref ByteSegment vData, int offset)
 {
     vData.Segment((uint)offset, 0x10, out v.p);
 }
Example #17
0
 public void Load(ref ByteSegment vData, int offset)
 {
     vData.Segment((uint)offset, 0x10, out this.p);
 }
Example #18
0
        // always takes over.
        protected sealed override bool RunCommand(Script.Runtime _rt, CommandInfo info, ref ByteSegment cmd)
        {
            Runtime   rt = (Runtime)_rt;
            GeoParent switcher;

#if DEBUG
            rt.counter[cmd[0]]++;
            int put_pos = 1;
            if (rt.rootNode.JumpCall == 0)
            {
                rt.log.Append(" >");
            }
            else
            {
                rt.log.Append(">>");
            }
            if (null != (object)rt.nodeCurrent)
            {
                for (uint depth = rt.nodeCurrent.Depth; depth != 0; --depth)
                {
                    switcher = rt.nodeCurrent;
                    for (uint back = depth; back != 0; --back)
                    {
                        switcher = ((GeoNode)switcher).Outer;
                    }
                    rt.log.Append(0 == switcher.JumpCall ? "| ":"|>");
                }

                rt.log.Append(0 == rt.nodeCurrent.JumpCall ? "| " : "|:");

                put_pos += 1 + (int)rt.nodeCurrent.Depth;
            }
            if (cmd[0] == 0x05)
            {
                rt.log.Append('\'');
            }
            else if (cmd[0] == 0x04)
            {
                rt.log.Append('+');
            }
            else
            {
                rt.log.Append('|');
            }
            if (rt.currentParent.JumpCall == 0)
            {
                rt.log.Append('-');
            }
            else
            {
                rt.log.Append('~');
            }
            put_pos++;
            put_pos <<= 1;

            rt.log.Append(bytesToUInt16(cmd).ToString("X4"));
            //System.Console.Write('+');
            //System.Console.Write(cmd.Length.ToString("00"));
            put_pos += 4;
            while (put_pos++ < 40)
            {
                rt.log.Append(' ');
            }

            for (int b = 2; b < cmd.Length; b++)
            {
                if (b != 2)
                {
                    rt.log.Append(' ');
                }
                rt.log.Append(cmd[b].ToString("X2"));
            }
            rt.log.AppendLine();
#endif
            if (cmd[0] != 0x05 &&
                (switcher = rt.currentParent).isSwitch &&
                switcher.switchPos != 1)
            {
                if (switcher.switchFunc == 0x8029DB48)
                {
                    //rom.printArray(cmd, cmdLen);
                    //Console.WriteLine(nodeCurrent.switchPos);

                    cmd = default(ByteSegment);
                }
            }
            else if (0 != (info.Traits & CommandInfoTraits.HasDelegate))
            {
                ((Runtime.Command)info.Delegate)(rt, ref cmd);
            }

            if ((switcher = rt.currentParent).isSwitch)
            {
                switcher.switchPos++;
            }

            // we did (or decided not to do) the command so don't have the base do it.
            return(false);
        }
Example #19
0
        private static int DecodeInternal <BufferT>(ref BufferT inputBuffer, ref ByteSegment outputBuffer, out int inputUsed, out int outputUsed)
        {
            inputUsed = outputUsed = 0;

            if (outputBuffer.Count == 0 || outputBuffer.Array == null)
            {
                return(0);
            }

            var originalInputOffset = 0;
            var inputOffset         = 0;
            var inputEnd            = 0;
            var outputOffset        = outputBuffer.Offset;
            var outputCapacity      = outputBuffer.Count;
            var output = outputBuffer.Array;

            if (inputBuffer is ByteSegment)
            {
                var byteSegment = (ByteSegment)(object)inputBuffer;
                if (byteSegment.Count == 0 || byteSegment.Array == null)
                {
                    return(0);
                }
                inputOffset = originalInputOffset = byteSegment.Offset;
                inputEnd    = byteSegment.Offset + byteSegment.Count;
            }
            else if (inputBuffer is CharSegment)
            {
                var charSegment = (CharSegment)(object)inputBuffer;
                if (charSegment.Count == 0 || charSegment.Array == null)
                {
                    return(0);
                }
                inputOffset = originalInputOffset = charSegment.Offset;
                inputEnd    = charSegment.Offset + charSegment.Count;
            }
            else if (inputBuffer is StringSegment)
            {
                var stringSegment = (StringSegment)(object)inputBuffer;
                if (stringSegment.Count == 0 || stringSegment.Array == null)
                {
                    return(0);
                }
                inputOffset = originalInputOffset = stringSegment.Offset;
                inputEnd    = stringSegment.Offset + stringSegment.Count;
            }
            else
            {
                throw new InvalidOperationException("Unknown input buffer type: " + typeof(BufferT));
            }

            inputEnd = inputEnd - (inputEnd % 2);             // only read by two letters

            for (; inputOffset < inputEnd && outputCapacity > 0; inputOffset += 2)
            {
                var hexHalfByte1 = default(uint);
                var hexHalfByte2 = default(uint);

                if (inputBuffer is ByteSegment)
                {
                    var inputSegment = (ByteSegment)(object)inputBuffer;

                    hexHalfByte1 = ToNumber((char)inputSegment.Array[inputOffset]);
                    hexHalfByte2 = ToNumber((char)inputSegment.Array[inputOffset + 1]);
                }
                else if (inputBuffer is CharSegment)
                {
                    var inputSegment = (CharSegment)(object)inputBuffer;
                    hexHalfByte1 = ToNumber(inputSegment.Array[inputOffset]);
                    hexHalfByte2 = ToNumber(inputSegment.Array[inputOffset + 1]);
                }
                else
                {
                    var inputSegment = (StringSegment)(object)inputBuffer;
                    hexHalfByte1 = ToNumber(inputSegment.Array[inputOffset]);
                    hexHalfByte2 = ToNumber(inputSegment.Array[inputOffset + 1]);
                }

                output[outputOffset++] = checked ((byte)((hexHalfByte1 << 4) | hexHalfByte2));
                outputCapacity--;
            }

            outputUsed = outputOffset - outputBuffer.Offset;
            inputUsed  = inputOffset - originalInputOffset;

            return(outputUsed);
        }
Example #20
0
 public static SegmentOffset bytesToSegmentOffset(ByteSegment b, int offset = 0)
 {
     return(new SegmentOffset {
         Value = bytesToUInt32(b, offset),
     });
 }
Example #21
0
        /// <summary>
        /// Encode <paramref name="inputBuffer"/> bytes and store hex-encoded bytes into <paramref name="outputBuffer"/>.
        /// </summary>
        /// <param name="inputBuffer">Bytes to encode.</param>
        /// <param name="outputBuffer">Char array to store encoded bytes. Minimum length is 4.</param>
        /// <returns>Number of characters encoded into <paramref name="outputBuffer"/>.</returns>
        public static int Encode(ByteSegment inputBuffer, ByteSegment outputBuffer)
        {
            int inputUsed, outputUsed;

            return(EncodeInternal(ref inputBuffer, ref outputBuffer, out inputUsed, out outputUsed));
        }
Example #22
0
        /// <summary>
        /// Decode hex-encoded <paramref name="inputBuffer"/> and store decoded bytes into <paramref name="outputBuffer"/>.
        /// </summary>
        /// <param name="inputBuffer">String contains hex encoded bytes.</param>
        /// <param name="inputOffset">Decode start index in <paramref name="inputBuffer"/>.</param>
        /// <param name="inputCount">Number of chars to decode in <paramref name="inputBuffer"/>.</param>
        /// <param name="outputBuffer">Byte array to store decoded bytes from <paramref name="inputBuffer"/>.</param>
        /// <param name="inputUsed">Number of bytes read from <paramref name="inputBuffer"/> during decoding.</param>
        /// <param name="outputUsed">Number of bytes written in <paramref name="outputBuffer"/> during decoding.</param>
        /// <returns>Number of bytes decoded into <paramref name="outputBuffer"/>.</returns>
        public static int Decode(string inputBuffer, int inputOffset, int inputCount, ByteSegment outputBuffer, out int inputUsed, out int outputUsed)
        {
            if (inputBuffer == null)
            {
                throw new ArgumentNullException("inputBuffer");
            }

            var stringSegment = new StringSegment(inputBuffer, inputOffset, inputCount);

            return(DecodeInternal(ref stringSegment, ref outputBuffer, out inputUsed, out outputUsed));
        }
Example #23
0
 public static UInt24 bytesToUInt24(ByteSegment b, int offset = 0)
 {
     return(new UInt24 {
         B0 = b[offset + 2], B1 = b[offset + 1], B2 = b[offset]
     });
 }
Example #24
0
 public static byte bytesToByte(ByteSegment b, int offset = 0)
 {
     return(b[offset]);
 }
Example #25
0
 public static ushort bytesToUInt16(ByteSegment b, int offset = 0)
 {
     return((ushort)(((ushort)b[offset] << 8) | b[offset + 1]));
 }
Example #26
0
 /// <summary>
 /// identical to .ByteSegment.ReadFrom(...)
 /// </summary>
 public void ReadFrom(System.IO.BinaryReader Reader, int offset, int count)
 {
     ByteSegment.ReadFrom(Reader, offset, count);
 }
Example #27
0
 public static short bytesToInt16(ByteSegment b, int offset = 0)
 {
     return((short)((((int)b[offset] << 24) | ((int)b[offset + 1] << 16)) >> 16));
 }
Example #28
0
 /// <summary>
 /// Decode hex-encoded <paramref name="inputBuffer"/> and store decoded bytes into <paramref name="outputBuffer"/>.
 /// </summary>
 /// <param name="inputBuffer">Buffer contains hex encoded bytes.</param>
 /// <param name="outputBuffer">Byte array to store decoded bytes from <paramref name="inputBuffer"/>. </param>
 /// <param name="inputUsed">Number of bytes read from <paramref name="inputBuffer"/> during decoding.</param>
 /// <param name="outputUsed">Number of bytes written in <paramref name="outputBuffer"/> during decoding.</param>
 /// <returns>Number of bytes decoded into <paramref name="outputBuffer"/>.</returns>
 public static int Decode(ByteSegment inputBuffer, ByteSegment outputBuffer, out int inputUsed, out int outputUsed)
 {
     return(DecodeInternal(ref inputBuffer, ref outputBuffer, out inputUsed, out outputUsed));
 }
Example #29
0
        private void Load(ByteSegment segment, byte[] fontSource)
        {
            var i = 0;

            while (i < segment.Count)
            {
                var b0 = fontSource[segment.Offset + i];
                i++;

                if (b0 == 12)
                {
                    var b1 = fontSource[segment.Offset + i++];

                    switch (b1)
                    {
                    case 34:
                    {
                        // |- dx1 dx2 dy2 dx3 dx4 dx5 dx6 hflex (12 34) |-
                        _path.Add(_vs.Shift(), 0);
                        _path.Add(_vs.Shift(), _vs.Shift());
                        _path.Add(_vs.Shift(), 0);
                        _path.Add(_vs.Shift(), 0);
                        _path.Add(_vs.Shift(), 0);
                        _path.Add(_vs.Shift(), 0);
                        break;
                    }

                    case 35:
                    {
                        // |- dx1 dy1 dx2 dy2 dx3 dy3 dx4 dy4 dx5 dy5 dx6 dy6 fd flex (12 35) |-
                        _path.Add(_vs.Shift(), _vs.Shift());
                        _path.Add(_vs.Shift(), _vs.Shift());
                        _path.Add(_vs.Shift(), _vs.Shift());
                        _path.Add(_vs.Shift(), _vs.Shift());
                        _path.Add(_vs.Shift(), _vs.Shift());
                        _path.Add(_vs.Shift(), _vs.Shift());
                        break;
                    }

                    case 36:
                    {
                        // |- dx1 dy1 dx2 dy2 dx3 dx4 dx5 dy5 dx6 hflex1 (12 36) |-
                        _path.Add(_vs.Shift(), _vs.Shift());
                        _path.Add(_vs.Shift(), _vs.Shift());
                        _path.Add(_vs.Shift(), 0);
                        _path.Add(_vs.Shift(), 0);
                        _path.Add(_vs.Shift(), _vs.Shift());
                        _path.Add(_vs.Shift(), 0);
                        break;
                    }

                    case 37:
                    {
                        // |- dx1 dy1 dx2 dy2 dx3 dy3 dx4 dy4 dx5 dy5 dx6 flex1 (12 37) |-
                        _path.Add(_vs.Shift(), _vs.Shift());
                        _path.Add(_vs.Shift(), _vs.Shift());
                        _path.Add(_vs.Shift(), _vs.Shift());
                        _path.Add(_vs.Shift(), _vs.Shift());
                        _path.Add(_vs.Shift(), _vs.Shift());
                        _path.Add(_vs.Shift(), 0);
                        break;
                    }

                    default:
                        throw new ArgumentOutOfRangeException();
                    }
                }
                else if (b0 <= 27 || 29 <= b0 && b0 <= 31)
                {
                    switch (b0)
                    {
                    case 1:
                        // |- y dy {dya dyb}* hstem (1) |-
                        LoadStems();
                        break;

                    case 3:
                        // |- x dx {dxa dxb}* vstem (3) |-
                        LoadStems();
                        break;

                    case 4:
                        // |- dy1 vmoveto (4) |-
                        if (_vs.Count > 1 && !_haveWidth)
                        {
                            _width     = (int)_vs.Shift() + _normalWidthX;
                            _haveWidth = true;
                        }

                        _path.NewContour(0, _vs.Shift());
                        //_lastPoint.y += _vs.Pop();
                        //NewContour(_lastPoint);
                        break;

                    case 5:
                    {
                        // |- {dxa dya}+ rlineto (5) |-
                        while (_vs.Count > 0)
                        {
                            _path.Add(_vs.Shift(), _vs.Shift());
                        }

                        break;
                    }

                    case 6:
                    {
                        // |- dx1 {dya dxb}* hlineto (6) |-
                        // |- {dxa dyb}+ hlineto (6) |-
                        while (_vs.Count > 0)
                        {
                            _path.Add(_vs.Shift(), 0);
                            if (_vs.Count == 0)
                            {
                                break;
                            }

                            _path.Add(0, _vs.Shift());
                        }

                        break;
                    }

                    case 7:
                    {
                        // |- dy1 {dxa dyb}* vlineto (7) |-
                        // |- {dya dxb}+ vlineto (7) |-
                        while (_vs.Count > 0)
                        {
                            _path.Add(0, _vs.Shift());
                            if (_vs.Count == 0)
                            {
                                break;
                            }

                            _path.Add(_vs.Shift(), 0);
                        }

                        break;
                    }

                    case 8:
                    {
                        // |- {dxa dya dxb dyb dxc dyc}+ rrcurveto (8) |-
                        while (_vs.Count > 0)
                        {
                            _path.Add(_vs.Shift(), _vs.Shift(), true);
                            _path.Add(_vs.Shift(), _vs.Shift(), true);
                            _path.Add(_vs.Shift(), _vs.Shift());
                        }

                        break;
                    }

                    case 10:
                        // callsubr
                        var lIndex = (int)_vs.Pop() + _lsubrsBias;
                        Load(_lsubrs[lIndex], fontSource);
                        break;

                    case 11:
                        // return
                        break;

                    case 12:
                        // escape
                        break;

                    case 14:
                        // End of charstring
                        if (_vs.Count > 0 && !_haveWidth)
                        {
                            _width     = (int)_vs.Shift() + _normalWidthX;
                            _haveWidth = true;
                        }

                        break;

                    case 18:
                        LoadStems();
                        break;

                    case 19:
                    case 20:
                        // hintmask, cntrmask
                        LoadStems();
                        i += (_nStems + 7) >> 3;
                        break;

                    case 21:
                        // |- dx1 dy1 rmoveto (21) |-
                        if (_vs.Count > 2 && !_haveWidth)
                        {
                            _width     = (int)_vs.Shift() + _normalWidthX;
                            _haveWidth = true;
                        }

                        _path.NewContour(_vs.Shift(), _vs.Shift());
                        break;

                    case 22:
                        // |- dx1 hmoveto (22) |-
                        if (_vs.Count > 1 && !_haveWidth)
                        {
                            _width     = (int)_vs.Shift() + _normalWidthX;
                            _haveWidth = true;
                        }

                        _path.NewContour(_vs.Shift(), 0);
                        break;

                    case 23:
                        LoadStems();
                        break;

                    case 24:
                    {
                        // |- {dxa dya dxb dyb dxc dyc}+ dxd dyd rcurveline (24) |-

                        // Curve
                        while (_vs.Count > 4)
                        {
                            _path.Add(_vs.Shift(), _vs.Shift(), true);
                            _path.Add(_vs.Shift(), _vs.Shift(), true);
                            _path.Add(_vs.Shift(), _vs.Shift());
                        }

                        // Line
                        _path.Add(_vs.Shift(), _vs.Shift());
                        break;
                    }

                    case 25:
                    {
                        // |- {dxa dya}+ dxb dyb dxc dyc dxd dyd rlinecurve (25) |-

                        // Lines
                        while (_vs.Count > 6)
                        {
                            _path.Add(_vs.Shift(), _vs.Shift());
                        }

                        // Curves
                        _path.Add(_vs.Shift(), _vs.Shift(), true);
                        _path.Add(_vs.Shift(), _vs.Shift(), true);
                        _path.Add(_vs.Shift(), _vs.Shift());
                        break;
                    }

                    case 26:
                    {
                        // |- dx1? {dya dxb dyb dyc}+ vvcurveto (26) |-
                        var dx = 0f;
                        if (_vs.Count % 2 == 1)
                        {
                            dx = _vs.Shift();
                        }
                        while (_vs.Count > 0)
                        {
                            _path.Add(dx, _vs.Shift(), true);
                            _path.Add(_vs.Shift(), _vs.Shift(), true);
                            _path.Add(0, _vs.Shift());
                            dx = 0;
                        }

                        break;
                    }

                    case 27:
                    {
                        // |- dy1? {dxa dxb dyb dxc}+ hhcurveto (27) |-
                        var dy1 = 0f;
                        if (_vs.Count % 2 == 1)
                        {
                            dy1 = _vs.Shift();
                        }
                        while (_vs.Count != 0)
                        {
                            _path.Add(_vs.Shift(), dy1, true);
                            _path.Add(_vs.Shift(), _vs.Shift(), true);
                            _path.Add(_vs.Shift(), 0);
                            dy1 = 0;
                        }

                        break;
                    }

                    case 28:
                        break;

                    case 29:
                        // callgsubr
                        var gIndex = (int)_vs.Pop() + _gsubrsBias;
                        Load(_gsubrs[gIndex], fontSource);
                        break;

                    case 30:
                    {
                        // |- dy1 dx2 dy2 dx3 {dxa dxb dyb dyc dyd dxe dye dxf}* dyf? vhcurveto (30) |-
                        // |- {dya dxb dyb dxc dxd dxe dye dyf}+ dxf? vhcurveto (30) |-
                        var even = true;
                        while (_vs.Count >= 4)
                        {
                            if (even)
                            {
                                _path.Add(0, _vs.Shift(), true);
                                _path.Add(_vs.Shift(), _vs.Shift(), true);
                                _path.Add(_vs.Shift(), 0);
                            }
                            else
                            {
                                _path.Add(_vs.Shift(), 0, true);
                                _path.Add(_vs.Shift(), _vs.Shift(), true);
                                _path.Add(0, _vs.Shift());
                            }

                            even = !even;
                        }

                        if (_vs.Count == 1)
                        {
                            _path.ReplaceLastPoint(
                                _path.LastPoint.x + (even ? _vs.Shift() : 0),
                                _path.LastPoint.y + (even ? 0 : _vs.Shift())
                                );
                        }

                        break;
                    }

                    case 31:
                    {
                        // |- dx1 dx2 dy2 dy3 {dya dxb dyb dxc dxd dxe dye dyf}* dxf? hvcurveto (31) |-
                        // |- {dxa dxb dyb dyc dyd dxe dye dxf}+ dyf? hvcurveto (31) |-
                        var even = true;
                        while (_vs.Count >= 4)
                        {
                            if (even)
                            {
                                _path.Add(_vs.Shift(), 0, true);
                                _path.Add(_vs.Shift(), _vs.Shift(), true);
                                _path.Add(0, _vs.Shift());
                            }
                            else
                            {
                                _path.Add(0, _vs.Shift(), true);
                                _path.Add(_vs.Shift(), _vs.Shift(), true);
                                _path.Add(_vs.Shift(), 0);
                            }

                            even = !even;
                        }

                        if (_vs.Count == 1)
                        {
                            _path.ReplaceLastPoint(
                                _path.LastPoint.x + (even ? 0 : _vs.Shift()),
                                _path.LastPoint.y + (even ? _vs.Shift() : 0)
                                );
                        }

                        break;
                    }

                    default:
                        throw new ArgumentOutOfRangeException($"Invalid operator: {b0}");
                    }
                }
                // Operands
                else if (32 <= b0 && b0 <= 246)
                {
                    var val = b0 - 139;
                    _vs.Push(val);
                }
                else if (247 <= b0 && b0 <= 250)
                {
                    var b1  = fontSource[segment.Offset + i++];
                    var val = (b0 - 247) * 256 + b1 + 108;
                    _vs.Push(val);
                }
                else if (251 <= b0 && b0 <= 254)
                {
                    var b1  = fontSource[segment.Offset + i++];
                    var val = -(b0 - 251) * 256 - b1 - 108;
                    _vs.Push(val);
                }
                else if (b0 == 28)
                {
                    var b1  = fontSource[segment.Offset + i++];
                    var b2  = fontSource[segment.Offset + i++];
                    var val = CffDictParser.TwosComp((b1 << 8) | b2, 16);
                    _vs.Push(val);
                }
                else if (b0 == 255)
                {
                    var b1  = fontSource[segment.Offset + i++];
                    var b2  = fontSource[segment.Offset + i++];
                    var b3  = fontSource[segment.Offset + i++];
                    var b4  = fontSource[segment.Offset + i++];
                    var val = CffDictParser.TwosComp((b1 << 24) | (b2 << 16) | (b3 << 8) | b4, 32) /
                              (float)Math.Pow(2, 16);
                    _vs.Push(val);
                }
                else
                {
                    throw new FontException(string.Format("Invalid data: {0}(0x{0:X2})", b0));
                }
            }
        }
Example #30
0
 /// <summary>
 /// identical to .ByteSegment.ReadFrom(...)
 /// </summary>
 public void ReadFrom(System.IO.BinaryReader Reader)
 {
     ByteSegment.ReadFrom(Reader);
 }