region.cxx

来自「linux可以运行程序源码」· CXX 代码 · 共 249 行

CXX
249
字号
/* Copyright (C) 2002-2005 RealVNC Ltd.  All Rights Reserved. *  * This is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. *  * This software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the * GNU General Public License for more details. *  * You should have received a copy of the GNU General Public License * along with this software; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, * USA. */// Cross-platform Region class based on the X11 region implementation.  Note// that for efficiency this code manipulates the Xlib region structure// directly.  Apart from the layout of the structure, there is one other key// assumption made: a Region returned from XCreateRegion must always have its// rects member allocated so that there is space for at least one rectangle.//#include <rfb/Region.h>#include <Xregion/Xregion.h>#include <Xregion/region.h>#include <assert.h>#include <stdio.h>// A _RectRegion must never be passed as a return parameter to the Xlib region// operations.  This is because for efficiency its "rects" member has not been// allocated with Xmalloc.  It is however safe to pass it as an input// parameter.class _RectRegion {public:  _RectRegion(const rfb::Rect& r) {    region.rects = &region.extents;    region.numRects = 1;    region.extents.x1 = r.tl.x;    region.extents.y1 = r.tl.y;    region.extents.x2 = r.br.x;    region.extents.y2 = r.br.y;    region.size = 1;    if (r.is_empty())      region.numRects = 0;  }  REGION region;};rfb::Region::Region() {  xrgn = XCreateRegion();  assert(xrgn);}rfb::Region::Region(const Rect& r) {  xrgn = XCreateRegion();  assert(xrgn);  reset(r);}rfb::Region::Region(const rfb::Region& r) {  xrgn = XCreateRegion();  assert(xrgn);  XUnionRegion(xrgn, r.xrgn, xrgn);}rfb::Region::~Region() {  XDestroyRegion(xrgn);}rfb::Region& rfb::Region::operator=(const rfb::Region& r) {  clear();  XUnionRegion(xrgn, r.xrgn, xrgn);  return *this;}void rfb::Region::clear() {  xrgn->numRects = 0;  xrgn->extents.x1 = 0;  xrgn->extents.y1 = 0;  xrgn->extents.x2 = 0;  xrgn->extents.y2 = 0;}void rfb::Region::reset(const Rect& r) {  if (r.is_empty()) {    clear();  } else {    xrgn->numRects = 1;    xrgn->rects[0].x1 = xrgn->extents.x1 = r.tl.x;    xrgn->rects[0].y1 = xrgn->extents.y1 = r.tl.y;    xrgn->rects[0].x2 = xrgn->extents.x2 = r.br.x;    xrgn->rects[0].y2 = xrgn->extents.y2 = r.br.y;  }}void rfb::Region::translate(const Point& delta) {  XOffsetRegion(xrgn, delta.x, delta.y);}void rfb::Region::setOrderedRects(const std::vector<Rect>& rects) {  clear();  std::vector<Rect>::const_iterator i;  for (i=rects.begin(); i != rects.end(); i++) {    _RectRegion rr(*i);    XUnionRegion(xrgn, &rr.region, xrgn);  }}void rfb::Region::setExtentsAndOrderedRects(const ShortRect* extents,                                            int nRects, const ShortRect* rects){  if (xrgn->size < nRects)  {    BOX* prevRects = xrgn->rects;    xrgn->rects = (BOX*)Xrealloc((char*)xrgn->rects, nRects * sizeof(BOX));    if (!xrgn->rects) {      fprintf(stderr,"Xrealloc failed\n");      Xfree(prevRects);      return;    }    xrgn->size = nRects;  }  xrgn->numRects = nRects;  xrgn->extents.x1 = extents->x1;  xrgn->extents.y1 = extents->y1;  xrgn->extents.x2 = extents->x2;  xrgn->extents.y2 = extents->y2;  for (int i = 0; i < nRects; i++) {    xrgn->rects[i].x1 = rects[i].x1;    xrgn->rects[i].y1 = rects[i].y1;    xrgn->rects[i].x2 = rects[i].x2;    xrgn->rects[i].y2 = rects[i].y2;  }}void rfb::Region::copyFrom(const rfb::Region& r) {  XUnionRegion(r.xrgn, r.xrgn, xrgn);}void rfb::Region::assign_intersect(const rfb::Region& r) {  XIntersectRegion(xrgn, r.xrgn, xrgn);}void rfb::Region::assign_union(const rfb::Region& r) {  XUnionRegion(xrgn, r.xrgn, xrgn);}void rfb::Region::assign_subtract(const rfb::Region& r) {  XSubtractRegion(xrgn, r.xrgn, xrgn);}rfb::Region rfb::Region::intersect(const rfb::Region& r) const {  rfb::Region ret;  XIntersectRegion(xrgn, r.xrgn, ret.xrgn);  return ret;}rfb::Region rfb::Region::union_(const rfb::Region& r) const {  rfb::Region ret;  XUnionRegion(xrgn, r.xrgn, ret.xrgn);  return ret;}rfb::Region rfb::Region::subtract(const rfb::Region& r) const {  rfb::Region ret;  XSubtractRegion(xrgn, r.xrgn, ret.xrgn);  return ret;}bool rfb::Region::equals(const rfb::Region& r) const {  return XEqualRegion(xrgn, r.xrgn);}int rfb::Region::numRects() const {  return xrgn->numRects;}bool rfb::Region::get_rects(std::vector<Rect>* rects,                            bool left2right, bool topdown, int maxArea) const{  int nRects = xrgn->numRects;  int xInc = left2right ? 1 : -1;  int yInc = topdown ? 1 : -1;  int i = topdown ? 0 : nRects-1;  rects->clear();  rects->reserve(nRects);  while (nRects > 0) {    int firstInNextBand = i;    int nRectsInBand = 0;    while (nRects > 0 && xrgn->rects[firstInNextBand].y1 == xrgn->rects[i].y1)    {      firstInNextBand += yInc;      nRects--;      nRectsInBand++;    }    if (xInc != yInc)      i = firstInNextBand - yInc;    while (nRectsInBand > 0) {      int y = xrgn->rects[i].y1;      int h = maxArea / (xrgn->rects[i].x2 - xrgn->rects[i].x1);      if (!h) h = xrgn->rects[i].y2 - y;      do {        if (h > xrgn->rects[i].y2 - y)          h = xrgn->rects[i].y2 - y;        Rect r(xrgn->rects[i].x1, y, xrgn->rects[i].x2, y+h);        rects->push_back(r);        y += h;      } while (y < xrgn->rects[i].y2);      i += xInc;      nRectsInBand--;    }    i = firstInNextBand;  }  return !rects->empty();}rfb::Rect rfb::Region::get_bounding_rect() const {  return Rect(xrgn->extents.x1, xrgn->extents.y1,              xrgn->extents.x2, xrgn->extents.y2);}void rfb::Region::debug_print(const char* prefix) const{  fprintf(stderr,"%s num rects %3ld extents %3d,%3d %3dx%3d\n",          prefix, xrgn->numRects, xrgn->extents.x1, xrgn->extents.y1,          xrgn->extents.x2-xrgn->extents.x1,          xrgn->extents.y2-xrgn->extents.y1);  for (int i = 0; i < xrgn->numRects; i++) {    fprintf(stderr,"    rect %3d,%3d %3dx%3d\n",            xrgn->rects[i].x1, xrgn->rects[i].y1,            xrgn->rects[i].x2-xrgn->rects[i].x1,            xrgn->rects[i].y2-xrgn->rects[i].y1);  }}

⌨️ 快捷键说明

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