private Multistring RecognizeSingleLine(FastBitmap dest_bitmap, Rectangle dest_bounds, int font_color, out int max_height)
        {
            match_offsets.Clear();


            max_height = 0;

            int[]  y_offsets = new int[dest_bounds.Width];
            bool[] empty     = new bool[dest_bounds.Width];

            for (int x = 0; x < dest_bounds.Width; x++)
            {
                y_offsets[x] = -1;

                for (int y = 0; y < dest_bounds.Height; y++)
                {
                    if (dest_bitmap[dest_bounds.X + x, dest_bounds.Y + y] == font_color)
                    {
                        y_offsets[x] = y;
                        break;
                    }
                }

                if (y_offsets[x] < 0)
                {
                    empty[x] = true;
                }
            }

            int space_width = TextRenderer.MeasureText("   ", possible_fonts[0].Font).Width - TextRenderer.MeasureText("  ", possible_fonts[0].Font).Width;

            if (space_width < 1)
            {
                space_width = 1;
            }

            //Console.WriteLine(space_width);

            int current_x  = 0;
            int empty_cols = 0;

            int wanted_match_offset = int.MinValue;

            Multistring line_str = new Multistring();

            while (current_x < dest_bounds.Width)
            {
                if (y_offsets[current_x] >= 0)
                {
                    empty_cols = 0;

                    Rectangle bounds = dest_bounds;
                    bounds.X     = dest_bounds.X + current_x;
                    bounds.Width = dest_bounds.Width - current_x;

                    List <FontChar> matches = GetMatches(dest_bitmap, bounds, font_color, wanted_match_offset, y_offsets, current_x);

                    if (matches.Count > 0)
                    {
                        // Remove the recognized character from the destination bitmap
                        dest_bitmap.BlitSingleColor(matches[0].Bitmap,
                                                    new Point(bounds.X, bounds.Y + match_offsets[matches[0].FontChars] + matches[0].CropRect.Y), matches[0].FontColor, (int)0x00FFFFFF);

                        // Update y-offsets after removing the recognized character
                        for (int x = 0; x < matches[0].Bitmap.Width; x++)
                        {
                            y_offsets[current_x + x] = -1;

                            for (int y = 0; y < dest_bounds.Height; y++)
                            {
                                if (dest_bitmap[bounds.X + x, dest_bounds.Y + y] == font_color)
                                {
                                    y_offsets[current_x + x] = y;
                                    break;
                                }
                            }
                        }

                        if (possible_fonts.Count > 1)
                        {
                            possible_fonts_lookup.Clear();
                            possible_fonts.Clear();

                            foreach (FontChar fc in matches)
                            {
                                possible_fonts_lookup[fc.FontChars] = true;
                            }

                            foreach (FontCharCollection font in possible_fonts_lookup.Keys)
                            {
                                possible_fonts.Add(font);
                            }

                            space_width = TextRenderer.MeasureText("   ", possible_fonts[0].Font).Width - TextRenderer.MeasureText("  ", possible_fonts[0].Font).Width;
                            if (space_width < 1)
                            {
                                space_width = 1;
                            }
                        }

                        List <char> possible_chars = new List <char>();

                        foreach (FontChar fc in matches)
                        {
                            if (match_offsets[fc.FontChars] + matches[0].RealHeight > max_height)
                            {
                                max_height = match_offsets[fc.FontChars] + matches[0].RealHeight;
                            }

                            if (!possible_chars.Contains(fc.Character))
                            {
                                possible_chars.Add(fc.Character);
                            }
                        }

                        line_str.Append(possible_chars);
                    }
                }
                else if (empty[current_x])
                {
                    //Console.WriteLine("{0} empty", current_x);

                    empty_cols++;

                    if (empty_cols >= space_width)
                    {
                        line_str.Append(' ');
                        //Console.WriteLine("SPACE");
                        empty_cols = 0;
                    }
                }

                current_x++;
            }

            return(line_str);
        }