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); }