📄 blobbox.cpp
字号:
/********************************************************************** * File: blobbox.cpp (Formerly blobnbox.c) * Description: Code for the textord blob class. * Author: Ray Smith * Created: Thu Jul 30 09:08:51 BST 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 "blobbox.h"#define PROJECTION_MARGIN 10 //arbitrary#define EXTERNEXTERN double_VAR (textord_error_weight, 3,"Weighting for error in believability");EXTERN BOOL_VAR (pitsync_projection_fix, TRUE,"Fix bug in projection profile");ELISTIZE (BLOBNBOX) ELIST2IZE (TO_ROW) ELISTIZE (TO_BLOCK)/********************************************************************** * BLOBNBOX::merge * * Merge this blob with the given blob, which should be after this. **********************************************************************/void BLOBNBOX::merge( //merge blobs BLOBNBOX *nextblob //blob to join with ) { box += nextblob->box; //merge boxes nextblob->joined = TRUE;}/********************************************************************** * BLOBNBOX::chop * * Chop this blob into equal sized pieces using the x height as a guide. * The blob is not actually chopped. Instead, fake blobs are inserted * with the relevant bounding boxes. **********************************************************************/void BLOBNBOX::chop( //chop blobs BLOBNBOX_IT *start_it, //location of this BLOBNBOX_IT *end_it, //iterator FCOORD rotation, //for landscape float xheight //of line ) { INT16 blobcount; //no of blobs BLOBNBOX *newblob; //fake blob BLOBNBOX *blob; //current blob INT16 blobindex; //number of chop INT16 leftx; //left edge of blob float blobwidth; //width of each float rightx; //right edge to scan float ymin, ymax; //limits of new blob float test_ymin, test_ymax; //limits of part blob ICOORD bl, tr; //corners of box BLOBNBOX_IT blob_it; //blob iterator //get no of chops blobcount = (INT16) floor (box.width () / xheight); if (blobcount > 1 && (blob_ptr != NULL || cblob_ptr != NULL)) { //width of each blobwidth = (float) (box.width () + 1) / blobcount; for (blobindex = blobcount - 1, rightx = box.right (); blobindex >= 0; blobindex--, rightx -= blobwidth) { ymin = (float) MAX_INT32; ymax = (float) -MAX_INT32; blob_it = *start_it; do { blob = blob_it.data (); if (blob->blob_ptr != NULL) find_blob_limits (blob->blob_ptr, rightx - blobwidth, rightx, rotation, test_ymin, test_ymax); else find_cblob_vlimits (blob->cblob_ptr, rightx - blobwidth, rightx, /*rotation, */ test_ymin, test_ymax); blob_it.forward (); if (test_ymin < ymin) ymin = test_ymin; if (test_ymax > ymax) ymax = test_ymax; } while (blob != end_it->data ()); if (ymin < ymax) { leftx = (INT16) floor (rightx - blobwidth); if (leftx < box.left ()) leftx = box.left (); //clip to real box bl = ICOORD (leftx, (INT16) floor (ymin)); tr = ICOORD ((INT16) ceil (rightx), (INT16) ceil (ymax)); if (blobindex == 0) box = BOX (bl, tr); //change box else { newblob = new BLOBNBOX; //box is all it has newblob->box = BOX (bl, tr); //stay on current end_it->add_after_stay_put (newblob); } } } }}/********************************************************************** * find_blob_limits * * Scan the outlines of the blob to locate the y min and max * between the given x limits. **********************************************************************/void find_blob_limits( //get y limits PBLOB *blob, //blob to search float leftx, //x limits float rightx, FCOORD rotation, //for landscape float &ymin, //output y limits float &ymax) { float testy; //y intercept FCOORD pos; //rotated FCOORD vec; POLYPT *polypt; //current point //outlines OUTLINE_IT out_it = blob->out_list (); POLYPT_IT poly_it; //outline pts ymin = (float) MAX_INT32; ymax = (float) -MAX_INT32; for (out_it.mark_cycle_pt (); !out_it.cycled_list (); out_it.forward ()) { //get points poly_it.set_to_list (out_it.data ()->polypts ()); for (poly_it.mark_cycle_pt (); !poly_it.cycled_list (); poly_it.forward ()) { polypt = poly_it.data (); pos = polypt->pos; pos.rotate (rotation); vec = polypt->vec; vec.rotate (rotation); if (pos.x () < leftx && pos.x () + vec.x () > leftx || pos.x () > leftx && pos.x () + vec.x () < leftx) { testy = pos.y () + vec.y () * (leftx - pos.x ()) / vec.x (); //intercept of boundary if (testy < ymin) ymin = testy; if (testy > ymax) ymax = testy; } if (pos.x () >= leftx && pos.x () <= rightx) { if (pos.y () > ymax) ymax = pos.y (); if (pos.y () < ymin) ymin = pos.y (); } if (pos.x () > rightx && pos.x () + vec.x () < rightx || pos.x () < rightx && pos.x () + vec.x () > rightx) { testy = pos.y () + vec.y () * (rightx - pos.x ()) / vec.x (); //intercept of boundary if (testy < ymin) ymin = testy; if (testy > ymax) ymax = testy; } } }}/********************************************************************** * find_cblob_limits * * Scan the outlines of the cblob to locate the y min and max * between the given x limits. **********************************************************************/void find_cblob_limits( //get y limits C_BLOB *blob, //blob to search float leftx, //x limits float rightx, FCOORD rotation, //for landscape float &ymin, //output y limits float &ymax) { INT16 stepindex; //current point ICOORD pos; //current coords ICOORD vec; //rotated step C_OUTLINE *outline; //current outline //outlines C_OUTLINE_IT out_it = blob->out_list (); ymin = (float) MAX_INT32; ymax = (float) -MAX_INT32; for (out_it.mark_cycle_pt (); !out_it.cycled_list (); out_it.forward ()) { outline = out_it.data (); pos = outline->start_pos (); //get coords pos.rotate (rotation); for (stepindex = 0; stepindex < outline->pathlength (); stepindex++) { //inside if (pos.x () >= leftx && pos.x () <= rightx) { if (pos.y () > ymax) ymax = pos.y (); if (pos.y () < ymin) ymin = pos.y (); } vec = outline->step (stepindex); vec.rotate (rotation); pos += vec; //move to next } }}/********************************************************************** * find_cblob_vlimits * * Scan the outlines of the cblob to locate the y min and max * between the given x limits. **********************************************************************/void find_cblob_vlimits( //get y limits C_BLOB *blob, //blob to search float leftx, //x limits float rightx, float &ymin, //output y limits float &ymax) { INT16 stepindex; //current point ICOORD pos; //current coords ICOORD vec; //rotated step C_OUTLINE *outline; //current outline //outlines C_OUTLINE_IT out_it = blob->out_list (); ymin = (float) MAX_INT32; ymax = (float) -MAX_INT32; for (out_it.mark_cycle_pt (); !out_it.cycled_list (); out_it.forward ()) { outline = out_it.data (); pos = outline->start_pos (); //get coords for (stepindex = 0; stepindex < outline->pathlength (); stepindex++) { //inside if (pos.x () >= leftx && pos.x () <= rightx) { if (pos.y () > ymax) ymax = pos.y (); if (pos.y () < ymin) ymin = pos.y (); } vec = outline->step (stepindex); pos += vec; //move to next } }}/********************************************************************** * find_cblob_hlimits * * Scan the outlines of the cblob to locate the x min and max * between the given y limits. **********************************************************************/void find_cblob_hlimits( //get x limits C_BLOB *blob, //blob to search float bottomy, //y limits float topy, float &xmin, //output x limits float &xmax) { INT16 stepindex; //current point ICOORD pos; //current coords ICOORD vec; //rotated step C_OUTLINE *outline; //current outline //outlines C_OUTLINE_IT out_it = blob->out_list (); xmin = (float) MAX_INT32; xmax = (float) -MAX_INT32; for (out_it.mark_cycle_pt (); !out_it.cycled_list (); out_it.forward ()) { outline = out_it.data (); pos = outline->start_pos (); //get coords for (stepindex = 0; stepindex < outline->pathlength (); stepindex++) { //inside if (pos.y () >= bottomy && pos.y () <= topy) { if (pos.x () > xmax) xmax = pos.x (); if (pos.x () < xmin) xmin = pos.x (); } vec = outline->step (stepindex); pos += vec; //move to next } }}/********************************************************************** * rotate_blob * * Poly copy the blob and rotate the copy by the given vector. **********************************************************************/PBLOB *rotate_blob( //get y limits PBLOB *blob, //blob to search FCOORD rotation //vector to rotate by ) { PBLOB *copy; //copy of blob POLYPT *polypt; //current point OUTLINE_IT out_it; POLYPT_IT poly_it; //outline pts copy = new PBLOB; *copy = *blob; //deep copy out_it.set_to_list (copy->out_list ()); for (out_it.mark_cycle_pt (); !out_it.cycled_list (); out_it.forward ()) { //get points poly_it.set_to_list (out_it.data ()->polypts ()); for (poly_it.mark_cycle_pt (); !poly_it.cycled_list (); poly_it.forward ()) { polypt = poly_it.data (); //rotate it polypt->pos.rotate (rotation); polypt->vec.rotate (rotation); } out_it.data ()->compute_bb (); } return copy;}/********************************************************************** * rotate_cblob * * Poly copy the blob and rotate the copy by the given vector. **********************************************************************/PBLOB *rotate_cblob( //rotate it C_BLOB *blob, //blob to search float xheight, //for poly approx FCOORD rotation //for landscape ) { PBLOB *copy; //copy of blob POLYPT *polypt; //current point OUTLINE_IT out_it; POLYPT_IT poly_it; //outline pts copy = new PBLOB (blob, xheight); out_it.set_to_list (copy->out_list ()); for (out_it.mark_cycle_pt (); !out_it.cycled_list (); out_it.forward ()) { //get points poly_it.set_to_list (out_it.data ()->polypts ()); for (poly_it.mark_cycle_pt (); !poly_it.cycled_list (); poly_it.forward ()) { polypt = poly_it.data (); //rotate it polypt->pos.rotate (rotation); polypt->vec.rotate (rotation); } out_it.data ()->compute_bb (); } return copy;}/********************************************************************** * crotate_cblob * * Rotate the copy by the given vector and return a C_BLOB. **********************************************************************/C_BLOB *crotate_cblob( //rotate it C_BLOB *blob, //blob to search FCOORD rotation //for landscape ) { C_OUTLINE_LIST out_list; //output outlines //input outlines C_OUTLINE_IT in_it = blob->out_list (); //output outlines C_OUTLINE_IT out_it = &out_list; for (in_it.mark_cycle_pt (); !in_it.cycled_list (); in_it.forward ()) { out_it.add_after_then_move (new C_OUTLINE (in_it.data (), rotation)); }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -