Exemplo n.º 1
0
        void BuildPackedImage()
        {
            _packedImage = null;
            _outputPreview.Invalidate();

            // Remove any duplicates from the character set.
            string characterSet = GetCharacterSetUnion();

            CharacterInfo[] infos = new CharacterInfo[ characterSet.Length ];

            Brush whiteBrush = new SolidBrush( Color.White );
            Brush blackBrush = new SolidBrush( Color.Black );

            // Get all the bitmap data and extents for the characters.
            using ( Bitmap tempBitmap = new Bitmap( 512, 512, PixelFormat.Format32bppArgb ) )
            {
                using ( Graphics g = Graphics.FromImage( tempBitmap ) )
                {
                    // Initialize it to black to start.
                    g.Clear( Color.Black );

                    // Initialize each CharacterInfo.
                    for ( int i=0; i < characterSet.Length; i++ )
                    {
                        CharacterInfo c = new CharacterInfo();
                        infos[i] = c;

                        c.Character = characterSet[i];

                        // Draw this character into tempBitmap.
                        _currentFont.DrawString( g, c.Character.ToString(), whiteBrush, new Point( 0, 0 ) );

                        // Scan to find the extents.
                        Rectangle? startingExtentsNullable = GetMaximumCharacterExtents( g, _currentFont, c.Character );
                        if ( !startingExtentsNullable.HasValue )
                            return;

                        // Make sure we're not accessing outside the bitmap itself. If this letter is larger than 512x512,
                        // then we've got bigger problems elsewhere!
                        Rectangle startingExtents = startingExtentsNullable.Value;
                        startingExtents.Width = Math.Min( startingExtents.Width, tempBitmap.Width );
                        startingExtents.Height = Math.Min( startingExtents.Height, tempBitmap.Height );

                        Rectangle extents;
                        ExtractImageData( tempBitmap, startingExtents, out c.Image, out extents );
                        c.XOffset = extents.X;
                        c.YOffset = extents.Y;
                        c.PackedWidth = extents.Width;
                        c.PackedHeight = extents.Height;

                        // Clear out the previous space used by it.
                        g.FillRectangle( blackBrush, new Rectangle( 0, 0, extents.X + extents.Width + 20, extents.Y + extents.Height + 20 ) );
                    }
                }
            }

            int maxImageDimension = 1024;

            // Now, pack all the characters in the output.
            // First, sort by height.
            CharacterInfo[] sorted = infos.OrderBy( x => -x.PackedHeight ).ToArray();
            _finalCharacterSet = sorted;

            // Now we can write the final index of each character.
            for ( int i=0; i < _finalCharacterSet.Length; i++ )
                _finalCharacterSet[i].SudoFontIndex = i;

            int atomicPixels = ReadAtomicPixelsControl();
            int packedWidth = 16;
            int packedHeight = 0;
            while ( packedWidth < maxImageDimension )
            {
                // We started out with a tiny width, so the height was super likely to be larger than the width.
                // If we finally get it where the width and height are equal, or where width is just one power of
                // two larger, then we're happy.
                packedHeight = PackCharacters( sorted, packedWidth, atomicPixels );
                if ( NextPowerOfTwo( packedWidth ) >= packedHeight )
                    break;

                packedWidth <<= 1;
            }

            // Now render the final bitmap.
            _packedImage = new Bitmap( packedWidth, NextPowerOfTwo( packedHeight ) );
            RenderPackedImage( _packedImage, infos, _alphaOnlyControl.Checked );
        }