Пример #1
0
        unsafe string GetUrl(int index, int mouseX)
        {
            mouseX -= Textures[index].X1;
            DrawTextArgs args = default(DrawTextArgs); args.UseShadow = true;
            string       text = lines[index];

            if (game.ClassicMode)
            {
                return(null);
            }

            char *   chars         = stackalloc char[lines.Length * 96];
            Portion *portions      = stackalloc Portion[(96 / httpLen) * 2];
            int      portionsCount = Reduce(chars, index, portions);

            for (int i = 0, x = 0; i < portionsCount; i++)
            {
                Portion bit = portions[i];
                args.Text = text.Substring(bit.LineBeg, bit.LineLen);
                args.Font = (bit.Len & 0x8000) == 0 ? font : underlineFont;

                int width = game.Drawer2D.MeasureText(ref args).Width;
                if (args.Font != font && mouseX >= x && mouseX < x + width)
                {
                    string url = new string(chars, bit.Beg, bit.Len & 0x7FFF);
                    // replace multiline bits
                    return(Utils.StripColours(url).Replace("> ", ""));
                }
                x += width;
            }
            return(null);
        }
Пример #2
0
        unsafe int Reduce(char *chars, int target, Portion *portions)
        {
            Portion *start    = portions;
            int      charsLen = 0;
            int *    begs     = stackalloc int[lines.Length];
            int *    ends     = stackalloc int[lines.Length];

            for (int i = 0; i < lines.Length; i++)
            {
                string line = lines[i];
                begs[i] = -1; ends[i] = -1;
                if (line == null)
                {
                    continue;
                }

                begs[i] = charsLen;
                for (int j = 0; j < line.Length; j++)
                {
                    chars[charsLen + j] = line[j];
                }
                charsLen += line.Length; ends[i] = charsLen;
            }

            int end = 0; Portion bit = default(Portion);

            for (;;)
            {
                int nextStart = NextUrl(chars, charsLen, end);

                // add normal portion between urls
                bit.Beg = end;
                bit.Len = nextStart - end;
                Output(bit, begs[target], ends[target], ref portions);

                if (nextStart == charsLen)
                {
                    break;
                }
                end = UrlEnd(chars, charsLen, begs, nextStart);

                // add this url portion
                bit.Beg = nextStart;
                bit.Len = (end - nextStart) | 0x8000;
                Output(bit, begs[target], ends[target], ref portions);
            }
            return((int)(portions - start));
        }
Пример #3
0
        unsafe void Output(Portion bit, int lineBeg, int lineEnd, Portion *portions, ref int count)
        {
            if (bit.Beg >= lineEnd || bit.Len == 0)
            {
                return;
            }
            bit.LineBeg = bit.Beg;
            bit.LineLen = bit.Len & 0x7FFF;

            // Adjust this portion to be within this line
            if (bit.Beg >= lineBeg)
            {
            }
            else if (bit.Beg + bit.LineLen > lineBeg)
            {
                // Adjust start of portion to be within this line
                int underBy = lineBeg - bit.Beg;
                bit.LineBeg += underBy; bit.LineLen -= underBy;
            }
            else
            {
                return;
            }

            // Limit length of portion to be within this line
            int overBy = (bit.LineBeg + bit.LineLen) - lineEnd;

            if (overBy > 0)
            {
                bit.LineLen -= overBy;
            }

            bit.LineBeg -= lineBeg;
            if (bit.LineLen == 0)
            {
                return;
            }

            portions[count] = bit; count++;
        }
Пример #4
0
        unsafe Texture DrawAdvanced(ref DrawTextArgs args, int index, string text)
        {
            char *   chars         = stackalloc char[lines.Length * 96];
            Portion *portions      = stackalloc Portion[(96 / httpLen) * 2];
            int      portionsCount = Reduce(chars, index, portions);

            Size  total     = Size.Empty;
            Size *partSizes = stackalloc Size[portionsCount];

            for (int i = 0; i < portionsCount; i++)
            {
                Portion bit = portions[i];
                args.Text = text.Substring(bit.LineBeg, bit.LineLen);
                args.Font = (bit.Len & 0x8000) == 0 ? font : underlineFont;

                partSizes[i] = game.Drawer2D.MeasureText(ref args);
                total.Height = Math.Max(partSizes[i].Height, total.Height);
                total.Width += partSizes[i].Width;
            }

            using (IDrawer2D drawer = game.Drawer2D)
                using (Bitmap bmp = IDrawer2D.CreatePow2Bitmap(total))
                {
                    drawer.SetBitmap(bmp);
                    for (int i = 0, x = 0; i < portionsCount; i++)
                    {
                        Portion bit = portions[i];
                        args.Text = text.Substring(bit.LineBeg, bit.LineLen);
                        args.Font = (bit.Len & 0x8000) == 0 ? font : underlineFont;

                        drawer.DrawText(ref args, x, 0);
                        x += partSizes[i].Width;
                    }
                    return(drawer.Make2DTexture(bmp, total, 0, 0));
                }
        }