Beispiel #1
0
        // --- functions ---
        /// <summary>Gets data associated with the specified codepoint.</summary>
        /// <param name="text">The string containing the codepoint.</param>
        /// <param name="offset">The offset at which to read the codepoint. For surrogate pairs, two characters are read, and one otherwise.</param>
        /// <param name="texture">Receives the texture that contains the codepoint.</param>
        /// <param name="data">Receives the data that describes the codepoint.</param>
        /// <returns>The number of characters read.</returns>
        public int GetCharacterData(string text, int offset, out Texture texture, out OpenGlFontChar data)
        {
            int value = char.ConvertToUtf32(text, offset);
            int hi    = value >> 8;
            int lo    = value & 0xFF;

            if (Tables[hi] == null || Tables[hi].Texture == null)
            {
                lock (BaseRenderer.GdiPlusLock)
                {
                    Tables[hi] = new OpenGlFontTable(Font, hi << 8);
                }
            }

            texture = Tables[hi].Texture;
            data    = Tables[hi].Characters[lo];
            return(value >= 0x10000 ? 2 : 1);
        }
Beispiel #2
0
        // --- constructors ---
        /// <summary>Creates a new table of characters.</summary>
        /// <param name="font">The font.</param>
        /// <param name="offset">The offset from codepoint U+0000.</param>
        public OpenGlFontTable(Font font, int offset)
        {
            /*
             * Measure characters.
             * */
            Vector2[] physicalSizes    = new Vector2[256];
            Vector2[] typographicSizes = new Vector2[256];
            bitmap = new Bitmap(1, 1, PixelFormat.Format32bppArgb);
            Graphics graphics = Graphics.FromImage(bitmap);

            graphics.TextRenderingHint = TextRenderingHint.ClearTypeGridFit;

            for (int i = 0; i < 256; i++)
            {
                string character       = char.ConvertFromUtf32(offset + i);
                SizeF  physicalSize    = graphics.MeasureString(character, font, int.MaxValue, StringFormat.GenericDefault);
                SizeF  typographicSize = graphics.MeasureString(character, font, int.MaxValue, StringFormat.GenericTypographic);
                physicalSizes[i]    = new Vector2((int)Math.Ceiling(physicalSize.Width), (int)Math.Ceiling(physicalSize.Height));
                typographicSizes[i] = new Vector2((int)Math.Ceiling(typographicSize.Width == 0.0f ? physicalSize.Width : typographicSize.Width), (int)Math.Ceiling(typographicSize.Height == 0.0f ? physicalSize.Height : typographicSize.Height));
            }

            graphics.Dispose();
            bitmap.Dispose();

            /*
             * Find suitable bitmap dimensions.
             * */
            const int border     = 1;
            double    width      = border;
            double    height     = border;
            double    lineWidth  = 0;
            double    lineHeight = 0;

            Vector2[] coordinates = new Vector2[256];

            for (int i = 0; i < 256; i++)
            {
                if (i % 16 == 0)
                {
                    // new line
                    if (lineWidth > width)
                    {
                        width = lineWidth;
                    }
                    lineWidth = border;

                    height    += lineHeight;
                    lineHeight = 0;
                }

                coordinates[i] = new Vector2(lineWidth, height);

                lineWidth += physicalSizes[i].X + border;

                if (physicalSizes[i].Y + border > lineHeight)
                {
                    lineHeight = physicalSizes[i].Y + border;
                }
            }

            if (lineWidth > width)
            {
                width = lineWidth;
            }
            height += lineHeight;
            width   = (int)RoundToPowerOfTwo((uint)width);
            height  = (int)RoundToPowerOfTwo((uint)height);

            /*
             * Draw character to bitmap.
             * */
            bitmap   = new Bitmap((int)width, (int)height, PixelFormat.Format32bppArgb);
            graphics = Graphics.FromImage(bitmap);
            graphics.TextRenderingHint = TextRenderingHint.ClearTypeGridFit;
            graphics.Clear(Color.Black);
            Characters = new OpenGlFontChar[256];

            for (int i = 0; i < 256; i++)
            {
                graphics.DrawString(char.ConvertFromUtf32(offset + i), font, Brushes.White, new PointF((float)coordinates[i].X, (float)coordinates[i].Y));
                double x0 = (coordinates[i].X - border) / width;
                double x1 = (coordinates[i].X + physicalSizes[i].X + border) / width;
                double y0 = (coordinates[i].Y - border) / height;
                double y1 = (coordinates[i].Y + physicalSizes[i].Y + border) / height;
                Characters[i] = new OpenGlFontChar(new Vector4(x0, y0, x1 - x0, y1 - y0), new Vector2(physicalSizes[i].X + 2 * border, physicalSizes[i].Y + 2 * border), typographicSizes[i]);
            }

            graphics.Dispose();
            Texture = new Texture(bitmap);
        }