coutln.cpp

来自「一个google的OCR源码」· C++ 代码 · 共 616 行 · 第 1/2 页

CPP
616
字号
/********************************************************************** * File:        coutln.c  (Formerly coutline.c) * Description: Code for the C_OUTLINE class. * Author:                  Ray Smith * Created:                 Mon Oct 07 16:01:57 BST 1991 * * (C) Copyright 1991, 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          <string.h>#ifdef __UNIX__#include          <assert.h>#endif#include          "coutln.h"ELISTIZE_S (C_OUTLINE)ICOORD C_OUTLINE::step_coords[4] = {  ICOORD (-1, 0), ICOORD (0, -1), ICOORD (1, 0), ICOORD (0, 1)};/********************************************************************** * C_OUTLINE::C_OUTLINE * * Constructor to build a C_OUTLINE from a CRACKEDGE LOOP. **********************************************************************/C_OUTLINE::C_OUTLINE (//constructorCRACKEDGE * startpt,             //outline to convertICOORD bot_left,                 //bounding boxICOORD top_right, inT16 length   //length of loop):box (bot_left, top_right), start (startpt->pos) {  inT16 stepindex;               //index to step  CRACKEDGE *edgept;             //current point  stepcount = length;            //no of steps  if (length == 0) {    steps = NULL;    return;  }                                 //get memory  steps = (uinT8 *) alloc_mem (step_mem());  memset(steps, 0, step_mem());  edgept = startpt;  for (stepindex = 0; stepindex < length; stepindex++) {                                 //set compact step    set_step (stepindex, edgept->stepdir);    edgept = edgept->next;  }}/********************************************************************** * C_OUTLINE::C_OUTLINE * * Constructor to build a C_OUTLINE from a C_OUTLINE_FRAG. **********************************************************************/C_OUTLINE::C_OUTLINE (//constructor                                 //steps to copyICOORD startpt, DIR128 * new_steps,inT16 length                     //length of loop):start (startpt) {  inT8 dirdiff;                  //direction difference  DIR128 prevdir;                //previous direction  DIR128 dir;                    //current direction  DIR128 lastdir;                //dir of last step  TBOX new_box;                   //easy bounding  inT16 stepindex;               //index to step  inT16 srcindex;                //source steps  ICOORD pos;                    //current position  pos = startpt;  stepcount = length;            //no of steps                                 //get memory  steps = (uinT8 *) alloc_mem (step_mem());  memset(steps, 0, step_mem());  lastdir = new_steps[length - 1];  prevdir = lastdir;  for (stepindex = 0, srcindex = 0; srcindex < length;  stepindex++, srcindex++) {    new_box = TBOX (pos, pos);    box += new_box;                                 //copy steps    dir = new_steps[srcindex];    set_step(stepindex, dir);    dirdiff = dir - prevdir;    pos += step (stepindex);    if ((dirdiff == 64 || dirdiff == -64) && stepindex > 0) {      stepindex -= 2;            //cancel there-and-back      prevdir = stepindex >= 0 ? step_dir (stepindex) : lastdir;    }    else      prevdir = dir;  }  ASSERT_HOST (pos.x () == startpt.x () && pos.y () == startpt.y ());  do {    dirdiff = step_dir (stepindex - 1) - step_dir (0);    if (dirdiff == 64 || dirdiff == -64) {      start += step (0);      stepindex -= 2;            //cancel there-and-back      for (int i = 0; i < stepindex; ++i)        set_step(i, step_dir(i + 1));    }  }  while (stepindex > 1 && (dirdiff == 64 || dirdiff == -64));  stepcount = stepindex;  ASSERT_HOST (stepcount >= 4);}/********************************************************************** * C_OUTLINE::C_OUTLINE * * Constructor to build a C_OUTLINE from a rotation of a C_OUTLINE. **********************************************************************/C_OUTLINE::C_OUTLINE(                     //constructor                     C_OUTLINE *srcline,  //outline to                     FCOORD rotation      //rotate                    ) {  TBOX new_box;                   //easy bounding  inT16 stepindex;               //index to step  inT16 dirdiff;                 //direction change  ICOORD pos;                    //current position  ICOORD prevpos;                //previous dest point  ICOORD destpos;                //destination point  inT16 destindex;               //index to step  DIR128 dir;                    //coded direction  uinT8 new_step;  stepcount = srcline->stepcount * 2;                                 //get memory  steps = (uinT8 *) alloc_mem (step_mem());  memset(steps, 0, step_mem());  for (int iteration = 0; iteration < 2; ++iteration) {    DIR128 round1 = iteration == 0 ? 32 : 0;    DIR128 round2 = iteration != 0 ? 32 : 0;    pos = srcline->start;    prevpos = pos;    prevpos.rotate (rotation);    start = prevpos;    box = TBOX (start, start);    destindex = 0;    for (stepindex = 0; stepindex < srcline->stepcount; stepindex++) {      pos += srcline->step (stepindex);      destpos = pos;      destpos.rotate (rotation);      if (destpos.x () != prevpos.x () || destpos.y () != prevpos.y ()) {        dir = DIR128 (FCOORD (destpos - prevpos));        dir += 64;                 //turn to step style        new_step = dir.get_dir ();        if (new_step & 31) {          set_step(destindex++, dir + round1);          if (destindex < 2            || ((dirdiff =            step_dir (destindex - 1) - step_dir (destindex - 2)) !=            -64 && dirdiff != 64))            set_step(destindex++, dir + round2);          else {            set_step(destindex - 1, dir + round2);            set_step(destindex++, dir + round1);          }        }        else {          set_step(destindex++, dir);          if (destindex >= 2            &&            ((dirdiff =            step_dir (destindex - 1) - step_dir (destindex - 2)) ==            -64 || dirdiff == 64))            destindex -= 2;        // Forget u turn        }        prevpos = destpos;        new_box = TBOX (destpos, destpos);        box += new_box;      }    }    ASSERT_HOST (destpos.x () == start.x () && destpos.y () == start.y ());    dirdiff = step_dir (destindex - 1) - step_dir (0);    while ((dirdiff == 64 || dirdiff == -64) && destindex > 1) {      start += step (0);      destindex -= 2;      for (int i = 0; i < destindex; ++i)        set_step(i, step_dir(i + 1));      dirdiff = step_dir (destindex - 1) - step_dir (0);    }    if (destindex >= 4)      break;  }  stepcount = destindex;  destpos = start;  for (stepindex = 0; stepindex < stepcount; stepindex++) {    destpos += step (stepindex);  }  ASSERT_HOST (destpos.x () == start.x () && destpos.y () == start.y ());}/********************************************************************** * C_OUTLINE::area * * Compute the area of the outline. **********************************************************************/inT32 C_OUTLINE::area() {  //winding number  int stepindex;                 //current step  inT32 total_steps;             //steps to do  inT32 total;                   //total area  ICOORD pos;                    //position of point  ICOORD next_step;              //step to next pix  C_OUTLINE_IT it = child ();  pos = start_pos ();  total_steps = pathlength ();  total = 0;  for (stepindex = 0; stepindex < total_steps; stepindex++) {                                 //all intersected    next_step = step (stepindex);    if (next_step.x () < 0)      total += pos.y ();    else if (next_step.x () > 0)      total -= pos.y ();    pos += next_step;  }  for (it.mark_cycle_pt (); !it.cycled_list (); it.forward ())    total += it.data ()->area ();//add areas of children  return total;}/********************************************************************** * C_OUTLINE::outer_area * * Compute the area of the outline. **********************************************************************/inT32 C_OUTLINE::outer_area() {  //winding number  int stepindex;                 //current step  inT32 total_steps;             //steps to do  inT32 total;                   //total area  ICOORD pos;                    //position of point  ICOORD next_step;              //step to next pix  pos = start_pos ();  total_steps = pathlength ();  if (total_steps == 0)    return box.area();  total = 0;  for (stepindex = 0; stepindex < total_steps; stepindex++) {                                 //all intersected    next_step = step (stepindex);    if (next_step.x () < 0)      total += pos.y ();    else if (next_step.x () > 0)      total -= pos.y ();    pos += next_step;  }  return total;}/********************************************************************** * C_OUTLINE::count_transitions * * Compute the number of x and y maxes and mins in the outline. **********************************************************************/inT32 C_OUTLINE::count_transitions(                 //winding number                                   inT32 threshold  //on size                                  ) {  BOOL8 first_was_max_x;         //what was first  BOOL8 first_was_max_y;  BOOL8 looking_for_max_x;       //what is next  BOOL8 looking_for_min_x;  BOOL8 looking_for_max_y;       //what is next  BOOL8 looking_for_min_y;  int stepindex;                 //current step  inT32 total_steps;             //steps to do                                 //current limits  inT32 max_x, min_x, max_y, min_y;  inT32 initial_x, initial_y;    //initial limits  inT32 total;                   //total changes  ICOORD pos;                    //position of point  ICOORD next_step;              //step to next pix  pos = start_pos ();  total_steps = pathlength ();  total = 0;  max_x = min_x = pos.x ();  max_y = min_y = pos.y ();  looking_for_max_x = TRUE;

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?