📄 pdblock.cpp
字号:
/********************************************************************** * File: pdblock.c (Formerly pdblk.c) * Description: PDBLK member functions and iterator functions. * Author: Ray Smith * Created: Fri Mar 15 09:41:28 GMT 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 <stdlib.h>#include "blckerr.h"#include "pdblock.h"#include "showim.h"#include "hpddef.h" //must be last (handpd.dll)#define BLOCK_LABEL_HEIGHT 150 //char height of block idCLISTIZE (PDBLK)/********************************************************************** * PDBLK::PDBLK * * Constructor for a simple rectangular block. **********************************************************************/PDBLK::PDBLK ( //rectangular blockINT16 xmin, //bottom leftINT16 ymin, INT16 xmax, //top rightINT16 ymax): box (ICOORD (xmin, ymin), ICOORD (xmax, ymax)) { //boundaries ICOORDELT_IT left_it = &leftside; ICOORDELT_IT right_it = &rightside; hand_block = NULL; hand_poly = NULL; left_it.set_to_list (&leftside); right_it.set_to_list (&rightside); //make default box left_it.add_to_end (new ICOORDELT (xmin, ymin)); left_it.add_to_end (new ICOORDELT (xmin, ymax)); right_it.add_to_end (new ICOORDELT (xmax, ymin)); right_it.add_to_end (new ICOORDELT (xmax, ymax));}/********************************************************************** * PDBLK::set_sides * * Sets left and right vertex lists **********************************************************************/void PDBLK::set_sides( //set vertex lists ICOORDELT_LIST *left, //left vertices ICOORDELT_LIST *right //right vertices ) { //boundaries ICOORDELT_IT left_it = &leftside; ICOORDELT_IT right_it = &rightside; leftside.clear (); left_it.move_to_first (); left_it.add_list_before (left); rightside.clear (); right_it.move_to_first (); right_it.add_list_before (right);}/********************************************************************** * PDBLK::contains * * Return TRUE if the given point is within the block. **********************************************************************/BOOL8 PDBLK::contains( //test containment ICOORD pt //point to test ) { BLOCK_RECT_IT it = this; //rectangle iterator ICOORD bleft, tright; //corners of rectangle for (it.start_block (); !it.cycled_rects (); it.forward ()) { //get rectangle it.bounding_box (bleft, tright); //inside rect if (pt.x () >= bleft.x () && pt.x () <= tright.x () && pt.y () >= bleft.y () && pt.y () <= tright.y ()) return TRUE; //is inside } return FALSE; //not inside}/********************************************************************** * PDBLK::move * * Reposition block **********************************************************************/void PDBLK::move( // reposition block const ICOORD vec // by vector ) { ICOORDELT_IT it(&leftside); for (it.mark_cycle_pt (); !it.cycled_list (); it.forward ()) *(it.data ()) += vec; it.set_to_list (&rightside); for (it.mark_cycle_pt (); !it.cycled_list (); it.forward ()) *(it.data ()) += vec; box.move (vec);}/********************************************************************** * PDBLK::plot * * Plot the outline of a block in the given colour. **********************************************************************/#ifndef GRAPHICS_DISABLEDvoid PDBLK::plot( //draw outline WINDOW window, //window to draw in INT32 serial, //serial number COLOUR colour //colour to draw in ) { ICOORD startpt; //start of outline ICOORD endpt; //end of outline ICOORD prevpt; //previous point ICOORDELT_IT it = &leftside; //iterator //set the colour line_color_index(window, colour); text_color_index(window, colour); character_height (window, (float) BLOCK_LABEL_HEIGHT); text_font_index (window, 6); if (!leftside.empty ()) { startpt = *(it.data ()); //bottom left corner // tprintf("Block %d bottom left is (%d,%d)\n", // serial,startpt.x(),startpt.y()); char temp_buff[34]; #ifdef __UNIX__ sprintf(temp_buff, INT32FORMAT, serial); #else ultoa (serial, temp_buff, 10); #endif text2d (window, startpt.x (), startpt.y (), temp_buff, 0, FALSE); move2d (window, startpt.x (), startpt.y ()); do { prevpt = *(it.data ()); //previous point it.forward (); //move to next point //draw round corner draw2d (window, prevpt.x (), it.data ()->y ()); draw2d (window, it.data ()->x (), it.data ()->y ()); } while (!it.at_last ()); //until end of list endpt = *(it.data ()); //end point //other side of boundary move2d (window, startpt.x (), startpt.y ()); it.set_to_list (&rightside); prevpt = startpt; for (it.mark_cycle_pt (); !it.cycled_list (); it.forward ()) { //draw round corner draw2d (window, prevpt.x (), it.data ()->y ()); draw2d (window, it.data ()->x (), it.data ()->y ()); prevpt = *(it.data ()); //previous point } //close boundary draw2d (window, endpt.x (), endpt.y ()); if (hand_block != NULL) hand_block->plot (window, colour, serial); }}#endif/********************************************************************** * PDBLK::show * * Show the image corresponding to a block as its set of rectangles. **********************************************************************/#ifndef GRAPHICS_DISABLEDvoid PDBLK::show( //show image block IMAGE *image, //image to show WINDOW window //window to show in ) { BLOCK_RECT_IT it = this; //rectangle iterator ICOORD bleft, tright; //corners of rectangle for (it.start_block (); !it.cycled_rects (); it.forward ()) { //get rectangle it.bounding_box (bleft, tright); // tprintf("Drawing a block with a bottom left of (%d,%d)\n", // bleft.x(),bleft.y()); //show it show_sub_image (image, bleft.x (), bleft.y (), tright.x () - bleft.x (), tright.y () - bleft.y (), window, bleft.x (), bleft.y ()); }}#endif/********************************************************************** * PDBLK::operator= * * Assignment - duplicate the block structure, but with an EMPTY row list. **********************************************************************/PDBLK & PDBLK::operator= ( //assignmentconst PDBLK & source //from this) { // this->ELIST_LINK::operator=(source); if (!leftside.empty ()) leftside.clear (); if (!rightside.empty ()) rightside.clear (); leftside.deep_copy (&source.leftside); rightside.deep_copy (&source.rightside); box = source.box; return *this;}/********************************************************************** * BLOCK_RECT_IT::BLOCK_RECT_IT * * Construct a block rectangle iterator. **********************************************************************/BLOCK_RECT_IT::BLOCK_RECT_IT (//iterate rectanglesPDBLK * blkptr //from block):left_it (&blkptr->leftside), right_it (&blkptr->rightside) { block = blkptr; //remember block //non empty list if (!blkptr->leftside.empty ()) { start_block(); //ready for iteration }}/********************************************************************** * BLOCK_RECT_IT::set_to_block * * Start a new block. **********************************************************************/void BLOCK_RECT_IT::set_to_block( //start (new) block PDBLK *blkptr) { //block to start block = blkptr; //remember block //set iterators left_it.set_to_list (&blkptr->leftside); right_it.set_to_list (&blkptr->rightside); if (!blkptr->leftside.empty ()) start_block(); //ready for iteration}/********************************************************************** * BLOCK_RECT_IT::start_block * * Restart a block. **********************************************************************/void BLOCK_RECT_IT::start_block() { //start (new) block left_it.move_to_first (); right_it.move_to_first (); left_it.mark_cycle_pt (); right_it.mark_cycle_pt (); ymin = left_it.data ()->y (); //bottom of first box ymax = left_it.data_relative (1)->y (); if (right_it.data_relative (1)->y () < ymax) //smallest step ymax = right_it.data_relative (1)->y ();}/********************************************************************** * BLOCK_RECT_IT::forward * * Move to the next rectangle in the block. **********************************************************************/void BLOCK_RECT_IT::forward() { //next rectangle if (!left_it.empty ()) { //non-empty list if (left_it.data_relative (1)->y () == ymax) left_it.forward (); //move to meet top if (right_it.data_relative (1)->y () == ymax) right_it.forward (); //last is special if (left_it.at_last () || right_it.at_last ()) { left_it.move_to_first (); //restart right_it.move_to_first (); //now at bottom ymin = left_it.data ()->y (); } else { ymin = ymax; //new bottom } //next point ymax = left_it.data_relative (1)->y (); if (right_it.data_relative (1)->y () < ymax) //least step forward ymax = right_it.data_relative (1)->y (); }}/********************************************************************** * BLOCK_LINE_IT::get_line * * Get the the start and width of a line in the block. **********************************************************************/INT16 BLOCK_LINE_IT::get_line( //get a line INT16 y, //line to get INT16 &xext //output extent ) { ICOORD bleft; //bounding box ICOORD tright; //of block & rect //get block box block->bounding_box (bleft, tright); if (y < bleft.y () || y >= tright.y ()) { // block->print(stderr,FALSE); BADBLOCKLINE.error ("BLOCK_LINE_IT::get_line", ABORT, "Y=%d", y); } //get rectangle box rect_it.bounding_box (bleft, tright); //inside rectangle if (y >= bleft.y () && y < tright.y ()) { //width of line xext = tright.x () - bleft.x (); return bleft.x (); //start of line } for (rect_it.start_block (); !rect_it.cycled_rects (); rect_it.forward ()) { //get rectangle box rect_it.bounding_box (bleft, tright); //inside rectangle if (y >= bleft.y () && y < tright.y ()) { //width of line xext = tright.x () - bleft.x (); return bleft.x (); //start of line } } LOSTBLOCKLINE.error ("BLOCK_LINE_IT::get_line", ABORT, "Y=%d", y); return 0; //dummy to stop warning}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -