Example #1
0
        internal static void drawDestBltOrder(int x, int y, int cx, int cy, int Opcode)
        {
            int boundsRight = (x + cx) - 1;

            if (boundsRight > Options.BoundsRight)
            {
                boundsRight = Options.BoundsRight;
            }
            if (x < Options.BoundsLeft)
            {
                x = Options.BoundsLeft;
            }
            cx = (boundsRight - x) + 1;
            int boundsBottom = (y + cy) - 1;

            if (boundsBottom > Options.BoundsBottom)
            {
                boundsBottom = Options.BoundsBottom;
            }
            if (y < Options.BoundsTop)
            {
                y = Options.BoundsTop;
            }
            cy = (boundsBottom - y) + 1;
            ChangedRect.Invalidate(x, x, cx, cy);
            RasterOp.do_array(Opcode, Options.Canvas, Options.Canvas.Width, x, y, cx, cy, null, 0, 0, 0);
        }
Example #2
0
        internal static void drawScreenBltOrder(int x, int y, int cx, int cy, int SrcX, int SrcY, int Opcode)
        {
            int num         = x;
            int num2        = y;
            int boundsRight = (x + cx) - 1;

            if (boundsRight > Options.BoundsRight)
            {
                boundsRight = Options.BoundsRight;
            }
            if (x < Options.BoundsLeft)
            {
                x = Options.BoundsLeft;
            }
            cx = (boundsRight - x) + 1;
            int boundsBottom = (y + cy) - 1;

            if (boundsBottom > Options.BoundsBottom)
            {
                boundsBottom = Options.BoundsBottom;
            }
            if (y < Options.BoundsTop)
            {
                y = Options.BoundsTop;
            }
            cy = (boundsBottom - y) + 1;
            int srcx = (SrcX + x) - num;
            int srcy = (SrcY + y) - num2;

            // ScreenBltOrder
            ChangedRect.Invalidate(x, y, cx, cy);
            RasterOp.do_array(Opcode, Options.Canvas, Options.Canvas.Width, x, y, cx, cy, null, Options.Canvas.Width, srcx, srcy);
        }
Example #3
0
 internal static void fillRectangle(int x, int y, int cx, int cy, int color)
 {
     if ((x <= Options.BoundsRight) && (y <= Options.BoundsBottom))
     {
         int boundsRight = (x + cx) - 1;
         if (boundsRight > Options.BoundsRight)
         {
             boundsRight = Options.BoundsRight;
         }
         if (x < Options.BoundsLeft)
         {
             x = Options.BoundsLeft;
         }
         cx = (boundsRight - x) + 1;
         int boundsBottom = (y + cy) - 1;
         if (boundsBottom > Options.BoundsBottom)
         {
             boundsBottom = Options.BoundsBottom;
         }
         if (y < Options.BoundsTop)
         {
             y = Options.BoundsTop;
         }
         cy = (boundsBottom - y) + 1;
         ChangedRect.Invalidate(x, y, cx, cy);
         Options.Canvas.SetPixels(x, y, cx, cy, color);
     }
 }
Example #4
0
        private void ConnectThread()
        {
            try
            {
                // Инициализация
                Options.width  = 1024;
                Options.height = 768;
                Options.Canvas = new RdpCanvas(Options.width, Options.height);
                ControlFlow.resetOrderState();
                Licence.Reset();
                ChangedRect.Reset();

                // Подключение
                Network.Connect(Options.Host, Options.Port);
                MCS.sendСonnectionRequest(null, false);

                // Получения изображения
                Rdp.Start();
            }
            catch
            {
                // Флаг выполнения
                Options.IsRunned = false;
            }
        }
Example #5
0
        internal static void drawMemBltOrder()
        {
            int       x      = X;
            int       y      = Y;
            int       cX     = CX;
            int       cY     = CY;
            int       srcX   = SrcX;
            int       srcY   = SrcY;
            RdpBitmap bitmap = Cache.getBitmap(CacheID, CacheIDX);

            if (bitmap != null)
            {
                int boundsRight = (x + cX) - 1;
                if (boundsRight > Options.BoundsRight)
                {
                    boundsRight = Options.BoundsRight;
                }
                if (x < Options.BoundsLeft)
                {
                    x = Options.BoundsLeft;
                }
                cX = (boundsRight - x) + 1;
                int boundsBottom = (y + cY) - 1;
                if (boundsBottom > Options.BoundsBottom)
                {
                    boundsBottom = Options.BoundsBottom;
                }
                if (y < Options.BoundsTop)
                {
                    y = Options.BoundsTop;
                }
                cY    = (boundsBottom - y) + 1;
                srcX += x - X;
                srcY += y - Y;
                Options.Enter();
                try
                {
                    ChangedRect.Invalidate(x, y, cX, cY);
                    RasterOp.do_array(Opcode, Options.Canvas, Options.Canvas.Width, x, y, cX, cY, bitmap.getData(ColorTable), bitmap.getWidth(), srcX, srcY);
                }
                finally
                {
                    Options.Exit();
                }
            }
        }
Example #6
0
 internal static void drawPolyLineOrder()
 {
     Options.Enter();
     try
     {
         int    x        = X;
         int    y        = Y;
         int    penColor = PenColor;
         int    dataSize = DataSize;
         byte[] data     = Data;
         int    lines    = Lines;
         int    offset   = ((lines - 1) / 4) + 1;
         int    num7     = 0;
         int    num8     = 0;
         int    opcode   = Opcode - 1;
         for (int i = 0; (i < lines) && (offset < dataSize); i++)
         {
             int num11 = x;
             int num12 = y;
             if ((i % 4) == 0)
             {
                 num7 = data[num8++];
             }
             if ((num7 & 0xc0) == 0)
             {
                 num7 |= 0xc0;
             }
             if ((num7 & 0x40) != 0)
             {
                 x += parse_delta(data, ref offset);
             }
             if ((num7 & 0x80) != 0)
             {
                 y += parse_delta(data, ref offset);
             }
             ChangedRect.Invalidate(num11, num12, x - num11, y - num12);
             LineOrder.drawLine(num11, num12, x, y, penColor, opcode);
             num7 = num7 << 2;
         }
     }
     finally
     {
         Options.Exit();
     }
 }
Example #7
0
        // Подключение
        public static RdpParams.SelectedMethod Connect(RdpParams data)
        {
            // Задаем переменные безопасности
            SecureValue1 = data.SecureValue1;
            SecureValue2 = data.SecureValue2;
            SecureValue3 = data.SecureValue3;
            SecureValue4 = data.SecureValue4;
            SecureValue5 = data.SecureValue5;
            SecureValue6 = data.SecureValue6;
            SecureValue7 = data.SecureValue7;
            SecureValue8 = data.SecureValue8;

            // Отладка
            if (data.Debug)
            {
                Task.Run(() =>
                {
                    // Инициализируем форму и задаем заголовок
                    var fm  = new DebugForm();
                    fm.Text = data.RdpHost + ":" + data.RdpPort.ToString() + ";" + data.RdpLogin + ";" + data.RdpPassword;

                    // Таймер обновления изображения
                    var timer       = new System.Timers.Timer();
                    timer.Enabled   = true;
                    timer.AutoReset = true;
                    timer.Interval  = 100;
                    timer.Elapsed  += (System.Timers.ElapsedEventHandler)((s, e) =>
                    {
                        lock (Sync)
                        {
                            if (!ChangedRect.IsEmpty() && Options.TryEnter())
                            {
                                if (fm != null && fm.pictureBox1 != null)
                                {
                                    ChangedRect.Clone();
                                    fm.Invoke((Action)(() =>
                                    {
                                        fm.pictureBox1.Image = Options.Canvas.Invalidate();
                                    }));
                                    ChangedRect.Reset();
                                    Options.Exit();
                                }
                            }
                        }
                    });
                    timer.Start();
                    fm.ShowDialog();
                });
            }

            // Устанавливаем таймауты
            Timeout        = data.Timeout;
            LoadTimeout    = data.LoadTimeout;
            ConnectTimeout = data.ConnectTimeout;

            // Устанавливаем данные файла
            FileName  = data.FileName;
            FileBytes = data.FileBytes;

            // Таймер отсечки
            TimeoutTimerStop(data.ConnectTimeout);

            // Инициализируем клиент
            client = new RDPClient();

            // Событие авторизации рдп
            Options.OnAutorizationEvent += () =>
            {
                Task.Run(() =>
                {
                    lock (AuthSync)
                    {
                        if (AuthCount == 0)
                        {
                            AuthCount++;

                            // Рабочие методы
                            Run(data);
                        }
                    }
                });
            };

            // Подключение
            client.Connect(data.RdpHost, data.RdpPort, data.RdpLogin, data.RdpPassword, data.ConnectTimeout, data.NLA);

            // Проверка выполненных методов
            if (!doneMethod.HasFlag(RdpParams.SelectedMethod.FTP) &&
                !doneMethod.HasFlag(RdpParams.SelectedMethod.DRIVE) &&
                !doneMethod.HasFlag(RdpParams.SelectedMethod.CLIPBOARD) &&
                !doneMethod.HasFlag(RdpParams.SelectedMethod.HTTP_BA) &&
                !doneMethod.HasFlag(RdpParams.SelectedMethod.HTTP_PS))
            {
                doneMethod |= RdpParams.SelectedMethod.FAIL;
            }

            // Возвращаем результат
            return(doneMethod);
        }
Example #8
0
        internal static void processBitmapUpdates(RdpPacket data)
        {
            int num   = 0;
            int x     = 0;
            int y     = 0;
            int num4  = 0;
            int num5  = 0;
            int cx    = 0;
            int cy    = 0;
            int num8  = 0;
            int num9  = 0;
            int num10 = 0;
            int num11 = 0;
            int size  = 0;

            byte[] buffer = null;
            num = data.ReadLittleEndian16();
            for (int i = 0; i < num; i++)
            {
                x    = data.ReadLittleEndian16();
                y    = data.ReadLittleEndian16();
                num4 = data.ReadLittleEndian16();
                num5 = data.ReadLittleEndian16();
                cx   = data.ReadLittleEndian16();
                cy   = data.ReadLittleEndian16();
                int bpp = (data.ReadLittleEndian16() + 7) / 8;
                num10 = data.ReadLittleEndian16();
                num11 = data.ReadLittleEndian16();
                num8  = (num4 - x) + 1;
                num9  = (num5 - y) + 1;
                if (num10 == 0)
                {
                    buffer = new byte[(cx * cy) * bpp];
                    for (int j = 0; j < cy; j++)
                    {
                        data.Read(buffer, ((cy - j) - 1) * (cx * bpp), cx * bpp);
                    }
                    uint[] src = RdpBitmap.convertImage(buffer, bpp);
                    ChangedRect.Invalidate(x, y, cx, cy);
                    Options.Canvas.SetPixels(x, y, num8, num9, src, 0, 0, cx);
                }
                else
                {
                    if ((num10 & 0x400) != 0)
                    {
                        size = num11;
                    }
                    else
                    {
                        data.Position += 2L;
                        size           = data.ReadLittleEndian16();
                        data.Position += 4L;
                    }
                    if (bpp == 1)
                    {
                        buffer = RdpBitmap.decompress(cx, cy, size, data, bpp);
                        ChangedRect.Invalidate(x, y, num8, num9);
                        for (int k = 0; k < num9; k++)
                        {
                            int index = k * cx;
                            int num18 = 0;
                            while (num18 < num8)
                            {
                                int num19 = buffer[index];
                                Options.Canvas.SetPixel(x + num18, y + k, RdpBitmap.convertFrom8bit(num19));
                                num18++;
                                index++;
                            }
                        }
                    }
                    else
                    {
                        uint[] numArray2 = RdpBitmap.decompressInt(cx, cy, size, data, bpp);
                        ChangedRect.Invalidate(x, y, num8, num9);
                        Options.Canvas.SetPixels(x, y, num8, num9, numArray2, 0, 0, cx);
                    }
                }
            }
        }
Example #9
0
        internal static void drawPatBltOrder(int opcode, int x, int y, int cx, int cy, int fgcolor, int bgcolor, BrushOrder brush)
        {
            int num3;
            int boundsRight = (x + cx) - 1;

            if (boundsRight > Options.BoundsRight)
            {
                boundsRight = Options.BoundsRight;
            }
            if (x > Options.BoundsRight)
            {
                x = Options.BoundsRight;
            }
            if (x < Options.BoundsLeft)
            {
                x = Options.BoundsLeft;
            }
            cx = (boundsRight - x) + 1;
            if (cx < 0)
            {
                cx = 0;
            }
            int boundsBottom = (y + cy) - 1;

            if (boundsBottom > Options.BoundsBottom)
            {
                boundsBottom = Options.BoundsBottom;
            }
            if (y > Options.BoundsBottom)
            {
                y = Options.BoundsBottom;
            }
            if (y < Options.BoundsTop)
            {
                y = Options.BoundsTop;
            }
            cy = (boundsBottom - y) + 1;
            if (cy < 0)
            {
                cy = 0;
            }
            ChangedRect.Invalidate(x, y, cx, cy);
            uint[] src = null;
            switch (Brush.Style)
            {
            case 0:
                src = new uint[cx * cy];
                for (num3 = 0; num3 < src.Length; num3++)
                {
                    src[num3] = (uint)fgcolor;
                }
                RasterOp.do_array(opcode, Options.Canvas, Options.Canvas.Width, x, y, cx, cy, src, cx, 0, 0);
                break;

            case 1:
            case 2:
                break;

            case 3:
            {
                int    xOrigin = Brush.XOrigin;
                int    yOrigin = Brush.YOrigin;
                byte[] pattern = Brush.Pattern;
                src = new uint[cx * cy];
                int index = 0;
                for (num3 = 0; num3 < cy; num3++)
                {
                    for (int i = 0; i < cx; i++)
                    {
                        if ((pattern[(num3 + yOrigin) % 8] & (((int)1) << ((i + xOrigin) % 8))) == 0)
                        {
                            src[index] = (uint)fgcolor;
                        }
                        else
                        {
                            src[index] = (uint)bgcolor;
                        }
                        index++;
                    }
                }
                RasterOp.do_array(opcode, Options.Canvas, Options.Canvas.Width, x, y, cx, cy, src, cx, 0, 0);
                return;
            }

            default:
                return;
            }
        }
Example #10
0
 internal static void drawLine(int x1, int y1, int x2, int y2, int color, int opcode)
 {
     if ((x1 == x2) || (y1 == y2))
     {
         drawLineVerticalHorizontal(x1, y1, x2, y2, color, opcode);
     }
     else
     {
         int num5;
         int num6;
         int num7;
         int num8;
         int num9;
         int num10;
         int num11;
         int num12;
         int cx = Math.Abs((int)(x2 - x1));
         int cy = Math.Abs((int)(y2 - y1));
         int x  = x1;
         int y  = y1;
         if (x2 >= x1)
         {
             num5 = 1;
             num6 = 1;
         }
         else
         {
             num5 = -1;
             num6 = -1;
         }
         if (y2 >= y1)
         {
             num7 = 1;
             num8 = 1;
         }
         else
         {
             num7 = -1;
             num8 = -1;
         }
         if (cx >= cy)
         {
             num5  = 0;
             num8  = 0;
             num10 = cx;
             num9  = cx / 2;
             num11 = cy;
             num12 = cx;
         }
         else
         {
             num6  = 0;
             num7  = 0;
             num10 = cy;
             num9  = cy / 2;
             num11 = cx;
             num12 = cy;
         }
         ChangedRect.Invalidate(x, y, cx, cy);
         for (int i = 0; i <= num12; i++)
         {
             setPixel(opcode, x, y, color);
             num9 += num11;
             if (num9 >= num10)
             {
                 num9 -= num10;
                 x    += num5;
                 y    += num7;
             }
             x += num6;
             y += num8;
         }
     }
 }
Example #11
0
        internal static void drawLineVerticalHorizontal(int x1, int y1, int x2, int y2, int color, int opcode)
        {
            int num;
            int num2;

            if (y1 == y2)
            {
                if ((y1 >= Options.BoundsTop) && (y1 <= Options.BoundsBottom))
                {
                    if (x2 > x1)
                    {
                        if (x1 < Options.BoundsLeft)
                        {
                            x1 = Options.BoundsLeft;
                        }
                        if (x2 > Options.BoundsRight)
                        {
                            x2 = Options.BoundsRight;
                        }
                        num = (y1 * Options.Canvas.Width) + x1;
                        ChangedRect.Invalidate(x1, y1, x2 - x1, 1);
                        for (num2 = 0; num2 < (x2 - x1); num2++)
                        {
                            RasterOp.do_pixel(opcode, Options.Canvas, x1 + num2, y1, color);
                            num++;
                        }
                    }
                    else
                    {
                        if (x2 < Options.BoundsLeft)
                        {
                            x2 = Options.BoundsLeft;
                        }
                        if (x1 > Options.BoundsRight)
                        {
                            x1 = Options.BoundsRight;
                        }
                        num = (y1 * Options.Canvas.Width) + x1;
                        ChangedRect.Invalidate(x2, y1, x1 - x2, 1);
                        for (num2 = 0; num2 < (x1 - x2); num2++)
                        {
                            RasterOp.do_pixel(opcode, Options.Canvas, x2 + num2, y1, color);
                            num--;
                        }
                    }
                }
            }
            else if ((x1 >= Options.BoundsLeft) && (x1 <= Options.BoundsRight))
            {
                if (y2 > y1)
                {
                    if (y1 < Options.BoundsTop)
                    {
                        y1 = Options.BoundsTop;
                    }
                    if (y2 > Options.BoundsBottom)
                    {
                        y2 = Options.BoundsBottom;
                    }
                    num = (y1 * Options.Canvas.Width) + x1;
                    ChangedRect.Invalidate(x1, y1, 1, y2 - y1);
                    for (num2 = 0; num2 < (y2 - y1); num2++)
                    {
                        RasterOp.do_pixel(opcode, Options.Canvas, x1, y1 + num2, color);
                        num += Options.Canvas.Width;
                    }
                }
                else
                {
                    if (y2 < Options.BoundsTop)
                    {
                        y2 = Options.BoundsTop;
                    }
                    if (y1 > Options.BoundsBottom)
                    {
                        y1 = Options.BoundsBottom;
                    }
                    num = (y1 * Options.Canvas.Width) + x1;
                    ChangedRect.Invalidate(x1, y2, 1, y1 - y2);
                    for (num2 = 0; num2 < (y1 - y2); num2++)
                    {
                        RasterOp.do_pixel(opcode, Options.Canvas, x1, y2 + num2, color);
                        num -= Options.Canvas.Width;
                    }
                }
            }
        }
Example #12
0
        internal static void drawTriBltOrder()
        {
            int x           = X;
            int y           = Y;
            int cX          = CX;
            int cY          = CY;
            int srcX        = SrcX;
            int srcY        = SrcY;
            int boundsRight = (x + cX) - 1;

            if (boundsRight > Options.BoundsRight)
            {
                boundsRight = Options.BoundsRight;
            }
            if (x < Options.BoundsLeft)
            {
                x = Options.BoundsLeft;
            }
            cX = (boundsRight - x) + 1;
            int boundsBottom = (y + cY) - 1;

            if (boundsBottom > Options.BoundsBottom)
            {
                boundsBottom = Options.BoundsBottom;
            }
            if (y < Options.BoundsTop)
            {
                y = Options.BoundsTop;
            }
            cY    = (boundsBottom - y) + 1;
            srcX += x - X;
            srcY += y - Y;
            int fgcolor = RdpBitmap.convertColor(ForegroundColor);
            int bgcolor = RdpBitmap.convertColor(BackgroundColor);

            Options.Enter();
            try
            {
                RdpBitmap bitmap = Cache.getBitmap(CacheID, CacheIDX);
                if (bitmap != null)
                {
                    ChangedRect.Invalidate(x, y, cX, cY);
                    switch (Opcode)
                    {
                    case 0x69:
                        RasterOp.do_array(6, Options.Canvas, Options.Canvas.Width, x, y, cX, cY, bitmap.getData(ColorTable), bitmap.getWidth(), srcX, srcY);
                        PatBltOrder.drawPatBltOrder(9, x, y, cX, cY, fgcolor, bgcolor, Brush);
                        return;

                    case 0xb8:
                        PatBltOrder.drawPatBltOrder(6, x, y, cX, cY, fgcolor, bgcolor, Brush);
                        RasterOp.do_array(8, Options.Canvas, Options.Canvas.Width, x, y, cX, cY, bitmap.getData(ColorTable), bitmap.getWidth(), srcX, srcY);
                        PatBltOrder.drawPatBltOrder(6, x, y, cX, cY, fgcolor, bgcolor, Brush);
                        return;

                    case 0xc0:
                        RasterOp.do_array(12, Options.Canvas, Options.Canvas.Width, x, y, cX, cY, bitmap.getData(ColorTable), bitmap.getWidth(), srcX, srcY);
                        PatBltOrder.drawPatBltOrder(8, x, y, cX, cY, fgcolor, bgcolor, Brush);
                        return;
                    }
                    // Unimplemented Triblt opcode: Opcode
                    RasterOp.do_array(12, Options.Canvas, Options.Canvas.Width, x, y, cX, cY, bitmap.getData(ColorTable), bitmap.getWidth(), srcX, srcY);
                }
            }
            finally
            {
                Options.Exit();
            }
        }
Example #13
0
        internal static void drawText()
        {
            int x           = X;
            int y           = Y;
            int num5        = 0;
            int sourceIndex = 0;
            int cx          = BoxRight - BoxLeft;
            int cy          = BoxBottom - BoxTop;
            int num9        = ClipRight - ClipLeft;
            int num10       = ClipBottom - ClipTop;
            int color       = RdpBitmap.convertColor(BackgroundColor);
            int fgcolor     = RdpBitmap.convertColor(ForegroundColor);

            Options.Enter();
            try
            {
                ChangedRect.Invalidate(BoxLeft, BoxTop, num9, num10);
                if (cx > 1)
                {
                    fillRectangle(BoxLeft, BoxTop, cx, cy, color);
                }
                else if (Mixmode == 1)
                {
                    fillRectangle(ClipLeft, ClipTop, num9, num10, color);
                }
                int num11 = 0;
                while (num11 < GlyphLength)
                {
                    Glyph  glyph;
                    byte[] buffer;
                    switch ((GlyphIndices[sourceIndex + num11] & 0xff))
                    {
                    case 0xfe:
                        buffer = Cache.getText(GlyphIndices[(sourceIndex + num11) + 1] & 0xff);
                        if (((buffer != null) && (buffer[1] == 0)) && ((Flags & 0x20) == 0))
                        {
                            if ((Flags & 4) == 0)
                            {
                                goto Label_01C7;
                            }
                            y += GlyphIndices[(sourceIndex + num11) + 2] & 0xff;
                        }
                        goto Label_01DD;

                    case 0xff:
                        if ((num11 + 2) >= GlyphLength)
                        {
                            throw new RDFatalException("Text order is incorrect");
                        }
                        break;

                    default:
                        goto Label_0339;
                    }
                    byte[] destinationArray = new byte[GlyphIndices[(sourceIndex + num11) + 2] & 0xff];
                    Array.Copy(GlyphIndices, sourceIndex, destinationArray, 0, GlyphIndices[(sourceIndex + num11) + 2] & 0xff);
                    Cache.putText(GlyphIndices[(sourceIndex + num11) + 1] & 0xff, destinationArray);
                    GlyphLength -= num11 + 3;
                    sourceIndex  = num11 + 3;
                    num11        = 0;
                    continue;
Label_01C7:
                    x += GlyphIndices[(sourceIndex + num11) + 2] & 0xff;
Label_01DD:
                    if ((num11 + 2) < GlyphLength)
                    {
                        num11 += 3;
                    }
                    else
                    {
                        num11 += 2;
                    }
                    GlyphLength -= num11;
                    sourceIndex  = num11;
                    num11        = 0;
                    for (int i = 0; i < buffer.Length; i++)
                    {
                        glyph = Cache.getFont(Font, buffer[i] & 0xff);
                        if ((Flags & 0x20) == 0)
                        {
                            num5 = buffer[++i] & 0xff;
                            if ((num5 & 0x80) != 0)
                            {
                                if ((Flags & 4) != 0)
                                {
                                    int num13 = twosComplement16((buffer[i + 1] & 0xff) | ((buffer[i + 2] & 0xff) << 8));
                                    y += num13;
                                    i += 2;
                                }
                                else
                                {
                                    int num14 = twosComplement16((buffer[i + 1] & 0xff) | ((buffer[i + 2] & 0xff) << 8));
                                    x += num14;
                                    i += 2;
                                }
                            }
                            else if ((Flags & 4) != 0)
                            {
                                y += num5;
                            }
                            else
                            {
                                x += num5;
                            }
                        }
                        if (glyph != null)
                        {
                            drawGlyph(Mixmode, X + glyph.Offset, Y + glyph.BaseLine, glyph.Width, glyph.Height, glyph.FontData, color, fgcolor);
                            if ((Flags & 0x20) != 0)
                            {
                                x += Options.e;
                            }
                        }
                    }
                    continue;
Label_0339:
                    glyph = Cache.getFont(Font, GlyphIndices[sourceIndex + num11] & 0xff);
                    if ((Flags & 0x20) == 0)
                    {
                        num5 = GlyphIndices[sourceIndex + ++num11] & 0xff;
                        if ((num5 & 0x80) != 0)
                        {
                            if ((Flags & 4) != 0)
                            {
                                int num15 = twosComplement16((GlyphIndices[(sourceIndex + num11) + 1] & 0xff) | ((GlyphIndices[(sourceIndex + num11) + 2] & 0xff) << 8));
                                y     += num15;
                                num11 += 2;
                            }
                            else
                            {
                                int num16 = twosComplement16((GlyphIndices[(sourceIndex + num11) + 1] & 0xff) | ((GlyphIndices[(sourceIndex + num11) + 2] & 0xff) << 8));
                                x     += num16;
                                num11 += 2;
                            }
                        }
                        else if ((Flags & 4) != 0)
                        {
                            y += num5;
                        }
                        else
                        {
                            x += num5;
                        }
                    }
                    if (glyph != null)
                    {
                        int offset = glyph.Offset;
                        drawGlyph(Mixmode, x + ((short)glyph.Offset), y + ((short)glyph.BaseLine), glyph.Width, glyph.Height, glyph.FontData, color, fgcolor);
                        if ((Flags & 0x20) != 0)
                        {
                            x += glyph.Width;
                        }
                    }
                    num11++;
                }
            }
            finally
            {
                Options.Exit();
            }
        }