Beispiel #1
0
void trend::TrendBase::wirem(int4b* pdata, unsigned psize, WireWidth width, const SGBitSet* psel)
{
    // first check whether to draw only the center line
    DBbox wsquare = DBbox(TP(0,0),TP(width,width));
    bool center_line_only = !wsquare.visible(topCTM() * scrCTM(), visualLimit());
    _clayer->wire(pdata, psize, width, center_line_only,psel,*_rmm);
}
/*! Build a new quadTree structure for the tdtdata in the inlist. The method is
using the existing _overlap variable. For every layout shape fitinsubtree()
method is called in a try to put the data in the child quadTree. At the end
the method is called for every of the child structures.
*/
void laydata::quadTree::sort(dataList& inlist)
{
   // if the input list is empty - nothing to do!
   if (0 == inlist.size()) return;
   dataList::iterator DI = inlist.begin();
   // if the list contains only one component - link it and run away
   if (1 == inlist.size())
   {
      DI->first->nextis(NULL); _first = DI->first;
      return;
   }
   byte i;
   // the overlapping box of the currnet shape 
//   DBbox shovl(TP(0,0));
   DBbox shovl = DEFAULT_OVL_BOX;
   // the maximum possible overlapping boxes of the 4 children
   DBbox maxsubbox[4] = {DEFAULT_OVL_BOX, DEFAULT_OVL_BOX, 
                         DEFAULT_OVL_BOX, DEFAULT_OVL_BOX};
   for (i = 0; i < 4; i++) maxsubbox[i] = _overlap.getcorner(i);
   // the sub-lists data will be sorted in
   dataList sublist[4];
   // which is the child where current shape fits 
   int fitinsubbox;
   // initialize the iterator
   float sharea, totalarea = _overlap.area();
   while (inlist.end() != DI)
   {
      // get the overlap of the current shape
      shovl = DI->first->overlap();shovl.normalize();
      sharea = shovl.area();
      // Check it fits in some of the children
      if (totalarea <= 4 * sharea || 
                        (-1 == (fitinsubbox = fitsubtree(shovl, maxsubbox))))
      {
         // no fit. The shape is sorted in the current tree
         DI->first->nextis(_first); _first = DI->first;
      }
      else
      {
         // fits in sub-tree fitinsubbox
         sublist[fitinsubbox].push_back(*DI);
         // check this child already exists
         if (_quads[fitinsubbox])  // yes ?
            _quads[fitinsubbox]->_overlap.overlap(shovl);
         else
         {
            // create the child, initialize the overlapping box
            _quads[fitinsubbox] = DEBUG_NEW quadTree();
            _quads[fitinsubbox]->_overlap = shovl;
         }
      }
      // in all cases get rid of the current shape pointer. It is already sorted
      DI = inlist.erase(DI);
   }
   // at this point inlist MUST be empty - split over max 4+this quadTrees
   // now go and sort the children - if any
   for(i = 0; i < 4; i++)
      if (_quads[i]) _quads[i]->sort(sublist[i]);

}
Beispiel #3
0
void trend::TrendBase::grcwire (int4b* pdata, unsigned psize, WireWidth width)
{
    // first check whether to draw only the center line
    DBbox wsquare = DBbox(TP(0,0),TP(width,width));
    bool center_line_only = !wsquare.visible(topCTM() * scrCTM(), visualLimit());
    _grcLayer->wire(pdata, psize, width, center_line_only);
}
/*! Checks whether a single layout object shape will fit into one of the 
childrens quadTree. It calls add() and returns success if the new layout object 
fits entirely into one of the possible subtrees or if it blows up its 
overlaping area not more than 10%. Returns false if the shape does not fit
anywhere - means it should be placed higher into the quadTree structure.\n
The method might be called recursively via the add() method.
*/
bool laydata::quadTree::fitintree(tdtdata* shape) {
   DBbox shovl = shape->overlap();
   float clipedarea[4];
   // check the clipping to see in witch region to place the shape
   for (byte i = 0; i < 4 ; i++) {
      DBbox subbox = _overlap.getcorner(i);
      clipedarea[i] = subbox.cliparea(shovl,true);
      if (-1 == clipedarea[i]) {//entirely inside the area
         if (!_quads[i]) _quads[i] = DEBUG_NEW quadTree();
         _quads[i]->add(shape);
         return true;
      }
   }
   // if we got to this point - means that the shape does not fit
   // entirely inside neither of the four sub-areas. 
   // It is a decision time then
   byte candidate = biggest(clipedarea);
   // now calculate the eventual new overlaping box
   DBbox newovl = _overlap.getcorner(candidate);
   newovl.overlap(shovl);
   // if the max area of the candidate does not blow more than 10% - 
   // then seems to be OK to get it
   if (newovl.area() < 1.1 * (_overlap.area() / 4)) {
      if (!_quads[candidate]) _quads[candidate] = DEBUG_NEW quadTree();
      _quads[candidate]->add(shape);
      return true;
   }
   return false; // shape can not be fit into any subtree
}
Beispiel #5
0
void trend::TrendBase::wiret(const PointVector& pdata, WireWidth width)
{
    // first check whether to draw only the center line
    DBbox wsquare = DBbox(TP(0,0),TP(width,width));
    bool center_line_only = !wsquare.visible(topCTM() * scrCTM(), visualLimit());
    _clayer->wire(pdata, width, center_line_only, *_rmm);
}
/*!*/
laydata::tdtdata* laydata::quadTree::merge_selected(tdtdata*& shapeRef) {
   laydata::tdtdata* mergeres = NULL;
   DBbox overlapRef = shapeRef->overlap();
   // check the entire holder for clipping...
   if (overlapRef.cliparea(_overlap) == 0) return NULL;
   // now start traversing the shapes in the current horlder one by one
   tdtdata* wdt = _first;
   while(wdt) {
      // for fully selected shapes if they overlap with the reference
      // and this is not the same shape as the reference
      if ((wdt != shapeRef) && 
          ((sh_selected == wdt->status()) || (sh_merged == wdt->status())) && 
          (overlapRef.cliparea(wdt->overlap()) != 0)) {
         // go and merge it
         mergeres = polymerge(wdt->shape2poly(), shapeRef->shape2poly());
         if (NULL != mergeres) {
            // If the merge produce a result - return the result and
            // substitute the shapeRef with its merged counterpart
            shapeRef = wdt;
            return mergeres;
         }
      }
      wdt = wdt->next();
   }
   // if we've got to this point - means that no more shapes to merge
   // in this area
   for(byte i = 0; i < 4; i++) 
      if (_quads[i]) {
         mergeres = _quads[i]->merge_selected(shapeRef);
         if (NULL != mergeres) return mergeres;
      }
   //at this point there is nothing more to traverse, so return NULL
   return NULL;
}
/*! Add a single layout object shape into the quadTree. 
It first checks whether or not another layout object is already placed into this
quadTree. If not it simply links the shape and exits. If another object is already
here, then the new overlap area is calculated. \n In case the new area is the same as 
the existing one, then the object might be (possibly) fited into one of the childrens 
quadTree. To check this fitintree() method is called. If this is unsuccessfull, just 
then the layout object is linked to this quadTree. \n If the new overlapping area is 
bigger that the existing one, then the layout object is linked to the current quadTree 
after what the current quadTree as well as its successors has to be rebuild using 
resort().\n The method might be called recursively via fitintree() method.
*/
void laydata::quadTree::add(tdtdata* shape) {
   DBbox shovl = shape->overlap();shovl.normalize();
   if (empty()) {
   // first shape in the container
      _overlap = shovl;
      _first = shape;shape->nextis(NULL);
   }
   else {
      // save the old overlap
      DBbox oldovl = _overlap;
      // calculate the new container overlap
      _overlap.overlap(shovl);
      float areaold = oldovl.area();
      float areanew = _overlap.area();
// The equation below produce problems with severe consequences.
// It seems to be because of the type of the conversion
//      if (oldovl.area() == _overlap->area()) {
      if (areaold == areanew) {
         // if the overlapping box hasn't changed,
         // try to fit the shape into subtree
         if ((areanew <= 4 * shovl.area()) || !fitintree(shape)) {
            // shape doesn't fit into the subtree, so place it here
            shape->nextis(_first); _first = shape;
         }
      }
      else { // the overlapping box has had blown-up
         shape->nextis(_first); _first = shape;
         resort(); // re-sort the entire tree
      }   
   }
}
Beispiel #8
0
void trend::TrendBase::genRulerMarks(const CTM& LayCTM, DBline& long_mark, DBline& short_mark, DBline& text_bp, double& scaledpix)
{
    // Side ticks (segments) of the rulers has to be with constant size. The next
    // lines are generating a segment with the size 7/3 screen pixels centred in
    // the {0,0} point of the canvas (logical coordinates)
    // The coefficients 1e3/1e-3 are picked arbitrary in an attempt to reduce the
    // error
    const double ico = 1e3;
    const double dco = 1/ico;
    DBline tick_sample = DBline(TP(0,0),TP(0,7,ico)) * LayCTM;
    double tick_size = ((double)(tick_sample.p2().y()-tick_sample.p1().y()));
    long_mark = DBline(TP(0,-tick_size, dco),TP(0,tick_size, dco));

    tick_sample = DBline(TP(0,0),TP(0,3,ico)) * LayCTM;
    tick_size = ((double)(tick_sample.p2().y()-tick_sample.p1().y()));
    short_mark = DBline(TP(0,-tick_size, dco),TP(0,tick_size, dco));

    tick_sample = DBline(TP(0,0),TP(0,20,ico)) * LayCTM;
    tick_size = ((double)(tick_sample.p1().y()-tick_sample.p2().y()));
    text_bp = DBline(TP(0,0),TP(0,tick_size, dco));

    // now prepare to draw the size
    DBbox pixelbox = DBbox(TP(),TP(15,15)) * LayCTM;
    scaledpix = ((double)(pixelbox.p2().x()-pixelbox.p1().x()));
}
void layprop::SupplementaryData::getConsts(const CTM& LayCTM, DBline& long_mark, DBline& short_mark, DBline& text_bp, double& scaledpix)
{
   // Side ticks (segments) of the rulers has to be with constant size. The next lines
   // are generating a segment with the size 7/3 screen pixels centered in
   // the {0,0} point of the canvas (logical coords)
   // the coeffitients 1e3/1e-3 are picked ramdomly attempting to reduce the
   // error
   const double ico = 1e3;
   const double dco = 1/ico;
   DBline tick_sample = DBline(TP(0,0),TP(0,7,ico)) * LayCTM;
   double tick_size = ((double)(tick_sample.p2().y()-tick_sample.p1().y()));
   long_mark = DBline(TP(0,-tick_size, dco),TP(0,tick_size, dco));
   
   tick_sample = DBline(TP(0,0),TP(0,3,ico)) * LayCTM;
   tick_size = ((double)(tick_sample.p2().y()-tick_sample.p1().y()));
   short_mark = DBline(TP(0,-tick_size, dco),TP(0,tick_size, dco));
   
   tick_sample = DBline(TP(0,0),TP(0,20,ico)) * LayCTM;
   tick_size = ((double)(tick_sample.p1().y()-tick_sample.p2().y()));
   text_bp = DBline(TP(0,0),TP(0,tick_size, dco));
   
   // now prepare to draw the size
   DBbox pixelbox = DBbox(TP(),TP(15,15)) * LayCTM;
   scaledpix = ((double)(pixelbox.p2().x()-pixelbox.p1().x()));
   
}
Beispiel #10
0
/*! A temporary Draw (during move/copy operations) of the container contents
 on the screen using the virtual quadTree::tmp_draw() method of the 
 parent object. */
void laydata::tdtlayer::motion_draw(const layprop::DrawProperties& drawprop,
                                                 ctmqueue& transtack) const {
   // check the entire layer for clipping...
   DBbox clip = drawprop.clipRegion();
   if (empty()) return;
   DBbox areal = overlap().overlap(transtack.front());
   if      ( clip.cliparea(areal) == 0       ) return;
   else if (!areal.visible(drawprop.ScrCTM())) return;
   quadTree::motion_draw(drawprop, transtack);
}
Beispiel #11
0
/*! Removes marked shapes from the quadtree without deleting them. The removed
    shapes are still listed in the _shapesel container of the current cell.
    The new overlapping box is calculated during this process and the method
    returns true to notify its parent that the overlapping box has changed and
    resort has to be initiated on the upper levels of the tree. The tree is 
    processed bottom-up, i.e. the method is recursively called first for child 
    quadTree structures.\n
    On the top level the method is called by two tdtcell methods:
    delete_selected and move selected. The difference is that for delete, 
    partially selected shapes are ignored and not processed.\n
    Fully selected shapes are always marked as sh_deleted. When move operation is
    going on they will be re-marked afterwards to sh_selected by the move(copy) 
    virtual methods of tdtdata.
 */
bool laydata::quadTree::delete_marked(SH_STATUS stat, bool partselect) {
   assert(!((stat != sh_selected) && (partselect == true)));
   // Create and initialize a variable "to be sorted"
   bool _2B_sorted = false;
   // save the old overlap, and initialize the new one
   DBbox oldovl = _overlap;
   _overlap = DEFAULT_OVL_BOX;
   // deleteing sequence is bottom-up, so start from the children
   for (byte i = 0; i < 4; i++) 
      if (_quads[i]) {
         _2B_sorted |= _quads[i]->delete_marked(stat, partselect);
         // check that there is still something left in the child quadTree
         if (_quads[i]->empty()) {
            delete _quads[i]; _quads[i] = NULL;
         }   
         else update_overlap(_quads[i]->overlap());
      }
   // prepare a pair of pointers to tdtdata
   tdtdata* wds = _first;
   tdtdata* wdsP = NULL;
   // loop all tdtdata in the current tree and check they are selected
   while (wds)
      // if selected ...
      if ((stat == wds->status()) || 
                                (partselect && (sh_partsel == wds->status()))) {
         // mark the fully selected shapes as deleted
         if (stat == wds->status()) wds->set_status(sh_deleted);
         // Unlink the marked shape from the list
         if (wdsP) { // if this is not the first shape
            wdsP->nextis(wds->next()); wds->nextis(NULL);
            wds = wdsP->next();
         }
         else { // Special attention when this is the first shape
            _first = wds->next(); wds->nextis(NULL);
            wds = _first;
         }
      }
      // If not selected, or partially selected but partselect == false,
      // update the overlapping box, and move further
      else {
         update_overlap(wds->overlap());
         wdsP = wds; wds = wds->next();
      }
   // If _overlap is still NULL here -> means the placeholder is empty. Will
   // be deleted by the parent
   if (empty()) _invalid = true;
   else {
      //Now if the overlapping rectangles differ, then invalidate 
      //the current quadTree
      float areaold = oldovl.area();
      float areanew = _overlap.area();
      if (areaold != areanew) _invalid = true;
   }
   return _2B_sorted |= _invalid;
}
Beispiel #12
0
short laydata::quadTree::clip_type(tenderer::TopRend& rend) const
{
   if (empty()) return 0;
   // check the entire holder for clipping...
   DBbox clip = rend.clipRegion();
   DBbox areal = _overlap.overlap(rend.topCTM());
   float clip_area = clip.cliparea(areal);
   if ( ( 0.0 == clip_area ) || (!areal.visible(rend.ScrCTM())) ) return 0;
   if (0.0 < clip_area) return 1;
   else return -1;
}
Beispiel #13
0
int tellstdfunc::stdGETOVERLAP::execute()
{
   telldata::TtLayout* layObject = static_cast<telldata::TtLayout*>(OPstack.top());OPstack.pop();
   assert(layObject);
   real DBscale = PROPC->DBscale();
   DBbox ovlBox = layObject->data()->overlap();
   telldata::TtPnt p1DB(ovlBox.p1().x()/DBscale, ovlBox.p1().y()/DBscale );
   telldata::TtPnt p2DB(ovlBox.p2().x()/DBscale, ovlBox.p2().y()/DBscale);

   OPstack.push(DEBUG_NEW telldata::TtBox( p1DB, p2DB ));
   delete layObject;
   return EXEC_NEXT;
}
Beispiel #14
0
bool laydata::DrawIterator<DataT>::secureNonEmptyDown()
{
   assert(_drawprop);
   DBbox clip = _drawprop->clipRegion();
   DBbox areal = Iterator<DataT>::_cQuad->_overlap.overlap(_ctm);
   if      (0ll == clip.cliparea(areal)      ) return false;
   else if (!areal.visible(_drawprop->scrCtm(), _drawprop->visualLimit())) return false;
   while (0 == Iterator<DataT>::_cQuad->_props._numObjects)
   {
      return this->nextSubQuad(0,Iterator<DataT>::_cQuad->_props.numSubQuads());
   }
   Iterator<DataT>::_cData = 0;
   return true;
}
Beispiel #15
0
/*! A temporary Draw (during move/copy operations) of the container contents
 on the screen using the virtual quadTree::tmp_draw() method of the 
 parent object. */
void laydata::tdtlayer::tmp_draw(const layprop::DrawProperties& drawprop,
                                                 ctmqueue& transtack) const {
   // check the entire layer for clipping...
   DBbox clip = drawprop.clipRegion();
   if (empty()) return;
   DBbox areal = overlap() * transtack.front();
   areal.normalize();
   if (clip.cliparea(areal) == 0) return;
   else {
      areal = areal * drawprop.ScrCTM();
      if (areal.area() < MIN_VISUAL_AREA) return;
   }   
   quadTree::tmp_draw(drawprop, transtack);
}
Beispiel #16
0
void trend::TrendBase::pushCell(std::string cname, const CTM& trans, const DBbox& overlap, bool active, bool selected)
{
    TrxCellRef* cRefBox = DEBUG_NEW TrxCellRef(cname,
                          trans * _cellStack.top()->ctm(),
                          overlap,
                          _cellStack.size()
                                              );
    if (selected || (!_drawprop->cellBoxHidden()))
        _refLayer->addCellOBox(cRefBox, _cellStack.size(), selected);
    else
        // This list is to keep track of the hidden cRefBox - so we can clean
        // them up. Don't get confused - we need cRefBox during the collecting
        // and drawing phase so we can't really delete them here or after they're
        // poped-up from _cellStack. The confusion is coming from the "duality"
        // of the TrxCellRef - once as a cell reference with CTM, view depth etc.
        // and then as a placeholder of the overlapping reference box
        _hiddenRefBoxes.push_back(cRefBox);

    _cellStack.push(cRefBox);
    if (active)
    {
        assert(NULL == _activeCS);
        _activeCS = cRefBox;
    }
    else if (!_drawprop->cellMarksHidden())
    {
        _marks->addRefMark(overlap.p1(), _cellStack.top()->ctm());
    }
}
Beispiel #17
0
/*! Temporary draw of the container contents on the screen using the virtual 
tmp_draw methods of the tdtddata objects. This happens only if 
the current quadTree object is visible. Current clip region data is
obtained from LayoutCanvas. In a sence this method is the same as openGL_draw
without fill and not handling selected shapes*/
void laydata::quadTree::motion_draw(const layprop::DrawProperties& drawprop,
                                                   ctmqueue& transtack) const {
   if (empty()) return;
   // check the entire holder for clipping...
   DBbox clip = drawprop.clipRegion();
   DBbox areal = _overlap.overlap(transtack.front());
   if      (clip.cliparea(areal) == 0        ) return;
   else if (!areal.visible(drawprop.ScrCTM())) return;
   tdtdata* wdt = _first;
   while(wdt) {
      wdt->motion_draw(drawprop, transtack, NULL);
      wdt = wdt->next();
   }
   for(byte i = 0; i < 4; i++) 
      if (_quads[i]) _quads[i]->motion_draw(drawprop, transtack);
}
//tui::CanvasStatus::CanvasStatus(){};
void tui::StatusLine::update(const int4b width, const CTM& _LayCTM)
{
   _sb_BL = TP(0,0)       * _LayCTM;
   _sb_TR = TP(width, 30) * _LayCTM;
   
   DBbox pixelbox = DBbox(TP(),TP(14,14)) * _LayCTM;
   _scaledpix = ((double)(pixelbox.p2().x()-pixelbox.p1().x()));
   _cY = TP(width-150, 17) * _LayCTM;
   _cX = TP(width-300, 17) * _LayCTM;
   _dY = TP(width-450, 17) * _LayCTM;
   _dX = TP(width-600, 17) * _LayCTM;
   _Ycoord = DBbox(TP(width - 130, 28), TP(width -   2, 2)) * _LayCTM;
   _Xcoord = DBbox(TP(width - 280, 28), TP(width - 162, 2)) * _LayCTM;
   _wcY = TP(width-120, 16) * _LayCTM;
   _wcX = TP(width-270, 16) * _LayCTM;
}
void tui::LayoutCanvas::OnZoom(wxCommandEvent& evt) {
   DBbox* box = NULL;
   switch (evt.GetInt())
   {
      case ZOOM_WINDOW : box = static_cast<DBbox*>(evt.GetClientData());break;
      case ZOOM_WINDOWM: box = DEBUG_NEW DBbox(presspoint.x(),presspoint.y(),
                                             ScrMARK.x(),ScrMARK.y());break;
      case ZOOM_IN     : box = DEBUG_NEW DBbox( (3*lp_BL.x() + lp_TR.x())/4, //in
                                                (3*lp_BL.y() + lp_TR.y())/4,
                                                (3*lp_TR.x() + lp_BL.x())/4,
                                                (3*lp_TR.y() + lp_BL.y())/4);
                        break;
      case ZOOM_OUT    : box = DEBUG_NEW DBbox( (5*lp_BL.x() - lp_TR.x())/4, //out
                                                (5*lp_BL.y() - lp_TR.y())/4,
                                                (5*lp_TR.x() - lp_BL.x())/4,
                                                (5*lp_TR.y() - lp_BL.y())/4);
                        break;
      case ZOOM_LEFT   : box = DEBUG_NEW DBbox( (  lp_TR.x() + lp_BL.x())/2, //left
                                                   lp_BL.y()               ,
                                                (3*lp_BL.x() - lp_TR.x())/2,
                                                   lp_TR.y()               );
                        break;
      case ZOOM_RIGHT  : box = DEBUG_NEW DBbox( (3*lp_TR.x() - lp_BL.x())/2, // right
                                                   lp_BL.y()               ,
                                                (  lp_TR.x() + lp_BL.x())/2,
                                                   lp_TR.y()               );
                        break;
      case ZOOM_UP     : box = DEBUG_NEW DBbox(    lp_BL.x()               , // up
                                                (3*lp_BL.y() - lp_TR.y())/2,
                                                   lp_TR.x()               ,
                                                (  lp_TR.y() + lp_BL.y())/2);
                        break;
      case ZOOM_DOWN   : box = DEBUG_NEW DBbox(    lp_BL.x()               , // down
                                                (  lp_TR.y() + lp_BL.y())/2,
                                                   lp_TR.x()               ,
                                                (3*lp_TR.y() - lp_BL.y())/2);
                        break;
      case ZOOM_EMPTY  : box = DEBUG_NEW DBbox(-10,-10,90,90);
                        break;
      case ZOOM_REFRESH: invalid_window = true; Refresh(); return;
      default: assert(false);
   }
   int Wcl, Hcl;
   GetClientSize(&Wcl,&Hcl);
   // To prevent a loss of precision in the following lines - don't use
   // integer variables (Wcl & Hcl) directly
   double W = Wcl;
   double H = Hcl;
   double w = abs(box->p1().x() - box->p2().x());
   double h = abs(box->p1().y() - box->p2().y());
   double sc =  ((W/H < w/h) ? w/W : h/H);
   double tx = ((box->p1().x() + box->p2().x()) - W*sc) / 2;
   double ty = ((box->p1().y() + box->p2().y()) - H*sc) / 2;
   _LayCTM.setCTM( sc, 0.0, 0.0, sc, tx, ty);
   _LayCTM.FlipX((box->p1().y() + box->p2().y())/2);  // flip Y coord towards the center
   DATC->setScrCTM(_LayCTM.Reversed());
   delete box;
   invalid_window = true;
   Refresh();
}
Beispiel #20
0
/*!Cut with polygon is pretty expensive operation and despite the fact that it
is executed over selected shapes only, there is no guarantee that the user will 
not do select_all() and then polycut(), and of course nobody can trust the user.
So this method is trying to minimize the calculations by executing cutpoly only 
on the shapes that overlap somehow with the cutting polygon */
void laydata::quadTree::cutpoly_selected(pointlist& plst, DBbox& cut_overlap, 
                                                           shapeList** decure) {
   // check the entire holder for clipping...
   if (cut_overlap.cliparea(_overlap) == 0) return;
   // now start traversing the shapes in the current horlder one by one
   tdtdata* wdt = _first;
   while(wdt) {
      // for fully selected shpes if they overlap with the cutting polygon
      if ((sh_selected == wdt->status()) && 
                                    (cut_overlap.cliparea(wdt->overlap()) != 0))
         // go and clip it
         wdt->polycut(plst, decure);
      wdt = wdt->next();
   }
   for(byte i = 0; i < 4; i++) 
      if (_quads[i]) _quads[i]->cutpoly_selected(plst, cut_overlap, decure);

}
Beispiel #21
0
/*! Temporary draw of the container contents on the screen using the virtual 
tmp_draw methods of the tdtddata objects. This happens only if 
the current quadTree object is visible. Current clip region data is
obtained from LayoutCanvas. In a sence this method is the same as openGL_draw
without fill and not handling selected shapes*/
void laydata::quadTree::tmp_draw(const layprop::DrawProperties& drawprop,
                                                   ctmqueue& transtack) const {
   if (empty()) return;
   // check the entire holder for clipping...
   DBbox clip = drawprop.clipRegion();   
   DBbox areal = _overlap * transtack.front(); 
   areal.normalize();
   if (clip.cliparea(areal) == 0) return;
   else {
      areal = areal * drawprop.ScrCTM();
      if (areal.area() < MIN_VISUAL_AREA) return;
   }   
   tdtdata* wdt = _first;
   while(wdt) {
      wdt->tmp_draw(drawprop, transtack);
      wdt = wdt->next();
   }
   for(byte i = 0; i < 4; i++) 
      if (_quads[i]) _quads[i]->tmp_draw(drawprop, transtack);
}
Beispiel #22
0
/*! Draw the contents of the container on the screen using the virtual 
openGL_draw methods of the tdtddata objects. This happens only if 
the current quadTree object is visible. Current clip region data is
obtained from LayoutCanvas. Draws also the select marks in case shape is
selected. \n This is the cherry of the quadTree algorithm cake*/
void laydata::quadTree::openGL_draw(ctmstack& transtack, const layprop::DrawProperties& drawprop,
                                                   const dataList* slst) const {
   if (empty()) return;
   // check the entire holder for clipping...
   DBbox clip = drawprop.clipRegion();
   DBbox areal = _overlap * transtack.top(); 
   areal.normalize();
   if (clip.cliparea(areal) == 0) return;
   else {
      areal = areal * drawprop.ScrCTM();
      if (areal.area() < MIN_VISUAL_AREA) return;
//      std::cout << "  ... with area " << areal.area() << "\n";
   }
   tdtdata* wdt = _first;
   // The drawing will be faster like this for the cells without selected shapes
   // that will be the wast majority of the cases. A bit bigger code though.
   // Seems the bargain is worth it.
   if (slst)
      while(wdt) {
         wdt->openGL_draw(transtack,drawprop);
         // in case the shape is somehow selected...
         if       (sh_selected == wdt->status()) wdt->draw_select(transtack.top());
         else if  (sh_partsel == wdt->status()) {
            dataList::const_iterator SI;
            for (SI = slst->begin(); SI != slst->end(); SI++)
               if (SI->first == wdt) break;
            assert(SI != slst->end());
            wdt->draw_select(transtack.top(), SI->second);
         }   
         wdt = wdt->next();
      }
   else
      // if there are no selected shapes
      while(wdt) {
         wdt->openGL_draw(transtack,drawprop);
         wdt = wdt->next();
      }
   for(byte i = 0; i < 4; i++) 
      if (_quads[i]) _quads[i]->openGL_draw(transtack, drawprop, slst);
}
Beispiel #23
0
/*! Perform the data selection using select_in box. Called by the corresponding
select methods of the parent structures in the data base - tdtlayer and tdtcell
*/
void laydata::quadTree::select_inBox(DBbox& select_in, dataList* selist, 
                                                          bool pselect) {
   // check the entire holder for clipping...
   if (select_in.cliparea(_overlap) == 0) return;
   // now start selecting one by one
   tdtdata* wdt = _first;
   while(wdt) {
      wdt->select_inBox(select_in, selist, pselect);
      wdt = wdt->next();
   }   
   for(byte i = 0; i < 4; i++) 
      if (_quads[i]) _quads[i]->select_inBox(select_in, selist, pselect);
}
Beispiel #24
0
void trend::TrendBase::text (const std::string* txt, const CTM& ftmtrx, const DBbox& ovl, const TP& cor, bool sel)
{
    if (sel)
        _clayer->text(txt, ftmtrx, &ovl, cor, true);
    else if (_drawprop->textBoxHidden())
        _clayer->text(txt, ftmtrx, NULL, cor, false);
    else
        _clayer->text(txt, ftmtrx, &ovl, cor, false);
    if (!_drawprop->textMarksHidden())
    {
        _marks->addTextMark(ovl.p1(),ftmtrx*_cellStack.top()->ctm());
    }
}
Beispiel #25
0
/*! Checks whether a single layout object shape will fit into one of the 
childrens quadTree. Returns the index of the child quadTree which fits 
the shape or -1 otherwise.
*/
int laydata::quadTree::fitsubtree(DBbox shovl, DBbox* maxsubbox ) {
   float clipedarea[4];
   // check the clipping to see in witch region to place the shape
   for (byte i = 0; i < 4 ; i++) {
      clipedarea[i] = maxsubbox[i].cliparea(shovl,true);
      if (-1 == clipedarea[i]) {//entirely inside the area
         return i;
      }
   }
   // if we got to this point - means that the shape does not fit
   // entirely inside neither of the four sub-areas. 
   // It is a decision time then
   byte candidate = biggest(clipedarea);
   // now calculate the eventual new overlaping box
   DBbox newovl = maxsubbox[candidate];
   newovl.overlap(shovl);
   // if the max area of the candidate does not blow more than 10% - 
   // then seems to be OK to get it
   if (newovl.area() < 1.1 * (_overlap.area() / 4)) {
      return candidate;
   }
   return -1; // shape can not be fit into any subtree
}
Beispiel #26
0
void trend::TrendBase::arefOBox(std::string cname, const CTM& trans, const DBbox& overlap, bool selected)
{
    if (!_drawprop->cellMarksHidden())
    {
        _marks->addARefMark(overlap.p1(), trans * _cellStack.top()->ctm());
    }

    if (selected || (!_drawprop->cellBoxHidden()))
    {
        TrxCellRef* cRefBox = DEBUG_NEW TrxCellRef(cname,
                              trans * _cellStack.top()->ctm(),
                              overlap,
                              _cellStack.size()
                                                  );
        _refLayer->addCellOBox(cRefBox, _cellStack.size(), selected);
    }
}
Beispiel #27
0
/*! Unselects already selected data using unselect_in box. Called by the corresponding
unselect methods of the parent structures in the data base - tdtlayer and tdtcell
*/
void laydata::quadTree::unselect_inBox(DBbox& unselect_in, dataList* unselist, 
                                                                 bool pselect) {
   // check the entire holder for clipping...
   if (unselect_in.cliparea(_overlap) == 0) return;
   tdtdata* wdt = _first;
   while (wdt) {
      // now start unselecting from the list
      dataList::iterator DI = unselist->begin();
      while ( DI != unselist->end() )
         if ((wdt == DI->first) &&
             (DI->first->unselect(unselect_in, *DI, pselect)))
               DI = unselist->erase(DI);
         else DI++;
      wdt = wdt->next();
   }   
   for(byte i = 0; i < 4; i++) 
      if (_quads[i]) _quads[i]->unselect_inBox(unselect_in, unselist, pselect);
}
void tui::LayoutCanvas::OnZoom(wxCommandEvent& evt) {
   DBbox* box = NULL;
   switch (evt.GetInt()) {
   case ZOOM_WINDOW : box = static_cast<DBbox*>(evt.GetClientData());break;
   case ZOOM_WINDOWM: box = new DBbox(presspoint.x(),presspoint.y(),
                                            ScrMARK.x(),ScrMARK.y());break;
   case ZOOM_IN     : box = new DBbox((3*lp_BL.x() + lp_TR.x())/4, //in
                            (3*lp_BL.y() + lp_TR.y())/4,
                            (3*lp_TR.x() + lp_BL.x())/4, 
                            (3*lp_TR.y() + lp_BL.y())/4); break;
   case ZOOM_OUT    : box = new DBbox((5*lp_BL.x() - lp_TR.x())/4, //out
                            (5*lp_BL.y() - lp_TR.y())/4,
                            (5*lp_TR.x() - lp_BL.x())/4, 
                            (5*lp_TR.y() - lp_BL.y())/4); break;
   case ZOOM_LEFT   : box = new DBbox((  lp_TR.x() + lp_BL.x())/2, //left
                               lp_BL.y()               ,
                            (3*lp_BL.x() - lp_TR.x())/2, 
                               lp_TR.y()               ); break;
   case ZOOM_RIGHT  : box = new DBbox((3*lp_TR.x() - lp_BL.x())/2, // right
                               lp_BL.y()               ,
                            (  lp_TR.x() + lp_BL.x())/2, 
                               lp_TR.y()               ); break;
   case ZOOM_UP     : box = new DBbox(   lp_BL.x()               , // up
                            (3*lp_BL.y() - lp_TR.y())/2,
                               lp_TR.x()               ,
                            (  lp_TR.y() + lp_BL.y())/2); break;
   case ZOOM_DOWN   : box = new DBbox(   lp_BL.x()               , // down
                            (  lp_TR.y() + lp_BL.y())/2,
                               lp_TR.x()               ,
                            (3*lp_TR.y() - lp_BL.y())/2); break;
   case ZOOM_EMPTY  : box = new DBbox(-10,-10,90,90); break;
   default: assert(false);
   }
   int W, H;
   GetClientSize(&W,&H);
   double w = abs(box->p1().x() - box->p2().x());
   double h = abs(box->p1().y() - box->p2().y());
   double sc = (W/H < w/h) ? w/W : h/H;
   double tx = ((box->p1().x() + box->p2().x()) - W*sc) / 2;
   double ty = ((box->p1().y() + box->p2().y()) - H*sc) / 2;
   _LayCTM.setCTM( sc, 0.0, 0.0, sc, tx, ty);
   _LayCTM.FlipX((box->p1().y() + box->p2().y())/2);  // flip Y coord towards the center
   Properties->setScrCTM(_LayCTM.Reversed());
   invalid_window = true;
   delete box;
   Refresh();
}
Beispiel #29
0
/*! Draw the contents of the container on the screen using the virtual 
openGL_draw methods of the tdtddata objects. This happens only if 
the current quadTree object is visible. Current clip region data is
obtained from LayoutCanvas. Draws also the select marks in case shape is
selected. \n This is the cherry of the quadTree algorithm cake*/
void laydata::quadTree::openGL_draw(layprop::DrawProperties& drawprop,
                                                   const dataList* slst, bool fill, bool bound) const {
   if (empty()) return;
   // check the entire holder for clipping...
   DBbox clip = drawprop.clipRegion();
   DBbox areal = _overlap * drawprop.topCTM(); 
   areal.normalize();
   if (clip.cliparea(areal) == 0) return;
   else {
      areal = areal * drawprop.ScrCTM();
      if (areal.area() < MIN_VISUAL_AREA) return;
//      std::cout << "  ... with area " << areal.area() << "\n";
   }
   tdtdata* wdt = _first;
//   bool fill = drawprop.getCurrentFill();
   // The drawing will be faster like this for the cells without selected shapes
   // that will be the wast majority of the cases. A bit bigger code though.
   // Seems the bargain is worth it.
   if (slst)
   {
      while(wdt)
      {
         pointlist points;
         // precalculate drawing data
         wdt->openGL_precalc(drawprop, points);
         if (0 != points.size())
         {
            // draw the shape fill (contents of refs, arefs and texts)
            if (fill)  wdt->openGL_drawfill(drawprop, points);
            // draw the outline of the shapes and overlapping boxes 
            if (bound) wdt->openGL_drawline(drawprop, points);
            if ((sh_selected == wdt->status()) || (sh_partsel == wdt->status()))
            {
               drawprop.setLineProps(true);
               if       (sh_selected == wdt->status())
                  wdt->openGL_drawsel(points, NULL);
               else if  (sh_partsel  == wdt->status())
               {
                  dataList::const_iterator SI;
                  for (SI = slst->begin(); SI != slst->end(); SI++)
                     if (SI->first == wdt) break;
                  assert(SI != slst->end());
                  wdt->openGL_drawsel(points, SI->second);
               }
               drawprop.setLineProps(false);
            }
            wdt->openGL_postclean(drawprop, points);
         }
         wdt = wdt->next();
      }
   }
   else
   {
      // if there are no selected shapes
      while(wdt)
      {
         pointlist points;
         // precalculate drawing data
         wdt->openGL_precalc(drawprop, points);
         // draw the shape fill (contents of refs, arefs and texts)
         if (fill)  wdt->openGL_drawfill(drawprop, points);
         // draw the outline of the shapes and overlapping boxes
         if (bound) wdt->openGL_drawline(drawprop, points);
         // clean-up
         wdt->openGL_postclean(drawprop, points);
         wdt = wdt->next();
      }
   }
   
/*   // The drawing will be faster like this for the cells without selected shapes
   // that will be the wast majority of the cases. A bit bigger code though.
   // Seems the bargain is worth it.
   if (slst)
      while(wdt) {
         wdt->openGL_draw(drawprop);
         // in case the shape is somehow selected...
         if       (sh_selected == wdt->status()) wdt->draw_select(drawprop.topCTM());
         else if  (sh_partsel == wdt->status()) {
            dataList::const_iterator SI;
            for (SI = slst->begin(); SI != slst->end(); SI++)
               if (SI->first == wdt) break;
            assert(SI != slst->end());
            wdt->draw_select(drawprop.topCTM(), SI->second);
         }   
         wdt = wdt->next();
      }
   else
      // if there are no selected shapes
      while(wdt) {
         wdt->openGL_draw(drawprop);
         wdt = wdt->next();
      }*/
   for(byte i = 0; i < 4; i++) 
      if (_quads[i]) _quads[i]->openGL_draw(drawprop, slst, fill, bound);
}