📄 coutln.cpp
字号:
/********************************************************************** * 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 //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 BOX 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 = BOX (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 ) { BOX 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 = BOX (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 = BOX (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 (); 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; looking_for_min_x = TRUE;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -