📄 charcut.cpp
字号:
/********************************************************************** * File: charcut.cpp (Formerly charclip.c) * Description: Code for character clipping * Author: Phil Cheatle * Created: Wed Nov 11 08:35:15 GMT 1992 * * (C) Copyright 1992, Hewlett-Packard Ltd. ** Licensed under the Apache License, Version 2.0 (the "License"); ** you may not use this file except in compliance with the License. ** You may obtain a copy of the License at ** http://www.apache.org/licenses/LICENSE-2.0 ** Unless required by applicable law or agreed to in writing, software ** distributed under the License is distributed on an "AS IS" BASIS, ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. ** See the License for the specific language governing permissions and ** limitations under the License. * **********************************************************************/#include "mfcpch.h"#include "charcut.h"#include "imgs.h"#include "showim.h"#include "evnts.h"#include "notdll.h"#define LARGEST(a,b) ( (a) > (b) ? (a) : (b) )#define SMALLEST(a,b) ( (a) > (b) ? (b) : (a) )#define BUG_OFFSET 1#define EXTERNEXTERN INT_VAR (pix_word_margin, 3, "How far outside word BB to grow");extern IMAGE page_image;ELISTIZE (PIXROW)/************************************************************************* * PIXROW::PIXROW() * * Constructor for a specified size PIXROW from a blob *************************************************************************/PIXROW::PIXROW(INT16 pos, INT16 count, PBLOB *blob) { OUTLINE_LIST *outline_list; OUTLINE_IT outline_it; POLYPT_LIST *pts_list; POLYPT_IT pts_it; INT16 i; FCOORD pt; FCOORD vec; float y_coord; INT16 x_coord; row_offset = pos; row_count = count; min = (INT16 *) alloc_mem (count * sizeof (INT16)); max = (INT16 *) alloc_mem (count * sizeof (INT16)); outline_list = blob->out_list (); outline_it.set_to_list (outline_list); for (i = 0; i < count; i++) { min[i] = MAX_INT16 - 1; max[i] = -MAX_INT16 + 1; y_coord = row_offset + i + 0.5; for (outline_it.mark_cycle_pt (); !outline_it.cycled_list (); outline_it.forward ()) { pts_list = outline_it.data ()->polypts (); pts_it.set_to_list (pts_list); for (pts_it.mark_cycle_pt (); !pts_it.cycled_list (); pts_it.forward ()) { pt = pts_it.data ()->pos; vec = pts_it.data ()->vec; if ((vec.y () != 0) && (((pt.y () <= y_coord) && (pt.y () + vec.y () >= y_coord)) || ((pt.y () >= y_coord) && (pt.y () + vec.y () <= y_coord)))) { /* The segment crosses y_coord so find x-point and check for min/max. */ x_coord = (INT16) floor ((y_coord - pt.y ()) * vec.x () / vec.y () + pt.x () + 0.5); if (x_coord < min[i]) min[i] = x_coord; x_coord--; //to get pix to left of line if (x_coord > max[i]) max[i] = x_coord; } } } }}/************************************************************************* * PIXROW::plot() * * Draw the PIXROW *************************************************************************/#ifndef GRAPHICS_DISABLEDvoid PIXROW::plot(WINDOW fd //where to paint ) const { INT16 i; INT16 y_coord; for (i = 0; i < row_count; i++) { y_coord = row_offset + i; if (min[i] <= max[i]) { rectangle (fd, min[i], y_coord, max[i] + 1, y_coord + 1); } }}#endif/************************************************************************* * PIXROW::bounding_box() * * Generate bounding box for blob image *************************************************************************/bool PIXROW::bad_box( //return true if box exceeds image int xsize, int ysize) const { BOX bbox = bounding_box (); if (bbox.left () < 0 || bbox.right () > xsize || bbox.top () > ysize || bbox.bottom () < 0) { tprintf("Box (%d,%d)->(%d,%d) bad compared to %d,%d\n", bbox.left(),bbox.bottom(), bbox.right(), bbox.top(), xsize, ysize); return true; } return false;}/************************************************************************* * PIXROW::bounding_box() * * Generate bounding box for blob image *************************************************************************/BOX PIXROW::bounding_box() const { INT16 i; INT16 y_coord; INT16 min_x = MAX_INT16 - 1; INT16 min_y = MAX_INT16 - 1; INT16 max_x = -MAX_INT16 + 1; INT16 max_y = -MAX_INT16 + 1; for (i = 0; i < row_count; i++) { y_coord = row_offset + i; if (min[i] <= max[i]) { if (y_coord < min_y) min_y = y_coord; if (y_coord + 1 > max_y) max_y = y_coord + 1; if (min[i] < min_x) min_x = min[i]; if (max[i] + 1 > max_x) max_x = max[i] + 1; } } if (min_x > max_x || min_y > max_y) return BOX (); else return BOX (ICOORD (min_x, min_y), ICOORD (max_x, max_y));}/************************************************************************* * PIXROW::contract() * * Reduce the mins and maxs so that they end on black pixels *************************************************************************/void PIXROW::contract( //image array IMAGELINE *imlines, INT16 x_offset, //of pixels[0] INT16 foreground_colour //0 or 1 ) { INT16 i; UINT8 *line_pixels; for (i = 0; i < row_count; i++) { if (min[i] > max[i]) continue; line_pixels = imlines[i].pixels; while (line_pixels[min[i] - x_offset] != foreground_colour) { if (min[i] == max[i]) { min[i] = MAX_INT16 - 1; max[i] = -MAX_INT16 + 1; goto nextline; } else min[i]++; } while (line_pixels[max[i] - x_offset] != foreground_colour) { if (min[i] == max[i]) { min[i] = MAX_INT16 - 1; max[i] = -MAX_INT16 + 1; goto nextline; } else max[i]--; } nextline:; //goto label! }}/************************************************************************* * PIXROW::extend() * * 1 pixel extension in each direction to cover extra black area *************************************************************************/BOOL8 PIXROW::extend( //image array IMAGELINE *imlines, BOX &imbox, PIXROW *prev, //for prev blob PIXROW *next, //for next blob INT16 foreground_colour) { INT16 i; INT16 x_offset = imbox.left (); INT16 limit; INT16 left_limit; INT16 right_limit; UINT8 *pixels = NULL; UINT8 *pixels_below = NULL; //row below current UINT8 *pixels_above = NULL; //row above current BOOL8 changed = FALSE; pixels_above = imlines[0].pixels; for (i = 0; i < row_count; i++) { pixels_below = pixels; pixels = pixels_above; if (i < (row_count - 1)) pixels_above = imlines[i + 1].pixels; else pixels_above = NULL; /* Extend Left by one pixel*/ if (prev == NULL || prev->max[i] < prev->min[i]) limit = imbox.left (); else limit = prev->max[i] + 1; if ((min[i] <= max[i]) && (min[i] > limit) && (pixels[min[i] - 1 - x_offset] == foreground_colour)) { min[i]--; changed = TRUE; } /* Extend Right by one pixel*/ if (next == NULL || next->min[i] > next->max[i]) limit = imbox.right () - 1;//-1 to index inside pix else limit = next->min[i] - 1; if ((min[i] <= max[i]) && (max[i] < limit) && (pixels[max[i] + 1 - x_offset] == foreground_colour)) { max[i]++; changed = TRUE; } /* Extend down by one row */ if (pixels_below != NULL) { if (min[i] < min[i - 1]) { //row goes left of row below if (prev == NULL || prev->max[i - 1] < prev->min[i - 1]) left_limit = min[i]; else left_limit = LARGEST (min[i], prev->max[i - 1] + 1); } else left_limit = min[i - 1]; if (max[i] > max[i - 1]) { //row goes right of row below if (next == NULL || next->min[i - 1] > next->max[i - 1]) right_limit = max[i]; else right_limit = SMALLEST (max[i], next->min[i - 1] - 1); } else right_limit = max[i - 1]; while ((left_limit <= right_limit) && (pixels_below[left_limit - x_offset] != foreground_colour)) left_limit++; //find black extremity if ((left_limit <= right_limit) && (left_limit < min[i - 1])) { min[i - 1] = left_limit; //widen left if poss changed = TRUE; } while ((left_limit <= right_limit) && (pixels_below[right_limit - x_offset] != foreground_colour)) right_limit--; //find black extremity if ((left_limit <= right_limit) && (right_limit > max[i - 1])) { max[i - 1] = right_limit;//widen right if poss changed = TRUE; } } /* Extend up by one row */ if (pixels_above != NULL) { if (min[i] < min[i + 1]) { //row goes left of row above if (prev == NULL || prev->min[i + 1] > prev->max[i + 1]) left_limit = min[i]; else left_limit = LARGEST (min[i], prev->max[i + 1] + 1); } else left_limit = min[i + 1]; if (max[i] > max[i + 1]) { //row goes right of row above if (next == NULL || next->min[i + 1] > next->max[i + 1]) right_limit = max[i]; else right_limit = SMALLEST (max[i], next->min[i + 1] - 1); } else right_limit = max[i + 1]; while ((left_limit <= right_limit) && (pixels_above[left_limit - x_offset] != foreground_colour)) left_limit++; //find black extremity if ((left_limit <= right_limit) && (left_limit < min[i + 1])) { min[i + 1] = left_limit; //widen left if poss changed = TRUE; } while ((left_limit <= right_limit) && (pixels_above[right_limit - x_offset] != foreground_colour)) right_limit--; //find black extremity if ((left_limit <= right_limit) && (right_limit > max[i + 1])) { max[i + 1] = right_limit;//widen right if poss changed = TRUE; } } } return changed;}/************************************************************************* * PIXROW::char_clip_image() * Cut out a sub image for a character *************************************************************************/void PIXROW::char_clip_image( //box of imlines extnt IMAGELINE *imlines, BOX &im_box, ROW *row, //row containing word
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -