diff options
author | Rodrigo Arias Mallo <rodarima@gmail.com> | 2024-12-10 22:30:12 +0100 |
---|---|---|
committer | Rodrigo Arias Mallo <rodarima@gmail.com> | 2024-12-10 22:30:12 +0100 |
commit | 429d5f88b94ff28416cbfc6420b6389fa284df97 (patch) | |
tree | fb6fdaf7731de1ef396f98b748c56f3149801c84 /dw/types.cc |
Import RTFL 0.1.1v0.1.1
Diffstat (limited to 'dw/types.cc')
-rw-r--r-- | dw/types.cc | 367 |
1 files changed, 367 insertions, 0 deletions
diff --git a/dw/types.cc b/dw/types.cc new file mode 100644 index 0000000..3962d97 --- /dev/null +++ b/dw/types.cc @@ -0,0 +1,367 @@ +/* + * RTFL (originally part of dillo) + * + * Copyright 2005-2007 Sebastian Geerken <sgeerken@dillo.org> + * + * This program 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 3 of the License, or + * (at your option) any later version; with the following exception: + * + * The copyright holders of RTFL give you permission to link this file + * statically or dynamically against all versions of the graphviz + * library, which are published by AT&T Corp. under one of the following + * licenses: + * + * - Common Public License version 1.0 as published by International + * Business Machines Corporation (IBM), or + * - Eclipse Public License version 1.0 as published by the Eclipse + * Foundation. + * + * This program 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 program. If not, see <http://www.gnu.org/licenses/>. + */ + + + +#include "core.hh" +#include "../lout/msg.h" + +using namespace lout; + +namespace dw { +namespace core { + +Rectangle::Rectangle (int x, int y, int width, int height) +{ + this->x = x; + this->y = y; + this->width = width; + this->height = height; +} + +/* + * Draw rectangle in view relative to point (x,y). + */ +void Rectangle::draw (core::View *view, core::style::Style *style, int x,int y) +{ + const bool filled = false; + + view->drawRectangle(style->color, core::style::Color::SHADING_NORMAL,filled, + x + this->x, y + this->y, this->width, this->height); +} + +/** + * Return whether this rectangle and otherRect intersect. If yes, + * return the intersection rectangle in dest. + */ +bool Rectangle::intersectsWith (Rectangle *otherRect, Rectangle *dest) +{ + bool doIntersect = + this->x < otherRect->x + otherRect->width && + this->y < otherRect->y + otherRect->height && + otherRect->x < this->x + this->width && + otherRect->y < this->y + this->height; + + if (doIntersect) { + dest->x = misc::max(this->x, otherRect->x); + dest->y = misc::max(this->y, otherRect->y); + dest->width = misc::min(this->x + this->width, + otherRect->x + otherRect->width) - dest->x; + dest->height = misc::min(this->y + this->height, + otherRect->y + otherRect->height) - dest->y; + } else { + dest->x = dest->y = dest->width = dest->height = 0; + } + + return doIntersect; +} + +/* + * Return whether this is a subset of otherRect. + */ +bool Rectangle::isSubsetOf (Rectangle *otherRect) +{ + return + x >= otherRect->x && + y >= otherRect->y && + x + width <= otherRect->x + otherRect->width && + y + height <= otherRect->y + otherRect->height; +} + +bool Rectangle::isPointWithin (int x, int y) +{ + return + x >= this->x && y >= this->y && + x < this->x + width && y < this->y + height; +} + +// ---------------------------------------------------------------------- + +Circle::Circle (int x, int y, int radius) +{ + this->x = x; + this->y = y; + this->radius = radius; +} + +/* + * Draw circle in view relative to point (x,y). + */ +void Circle::draw (core::View *view, core::style::Style *style, int x, int y) +{ + const bool filled = false; + + view->drawArc(style->color, core::style::Color::SHADING_NORMAL, filled, + x + this->x, y + this->y, 2 * this->radius, 2 * this->radius, + 0, 360); +} + +bool Circle::isPointWithin (int x, int y) +{ + return + (x - this->x) * (x - this->x) + (y - this->y) * (y - this->y) + <= radius * radius; +} + +// ---------------------------------------------------------------------- + +Polygon::Polygon () +{ + points = new misc::SimpleVector<Point> (8); + minx = miny = 0xffffff; + maxx = maxy = -0xffffff; +} + +Polygon::~Polygon () +{ + delete points; +} + +/* + * Draw polygon in view relative to point (x,y). + */ +void Polygon::draw (core::View *view, core::style::Style *style, int x, int y) +{ + if (points->size()) { + int i; + const bool filled = false, convex = false; + Point *pointArray = (Point *)malloc(points->size()*sizeof(struct Point)); + + for (i = 0; i < points->size(); i++) { + pointArray[i].x = x + points->getRef(i)->x; + pointArray[i].y = y + points->getRef(i)->y; + } + view->drawPolygon(style->color, core::style::Color::SHADING_NORMAL, + filled, convex, pointArray, i); + free(pointArray); + } +} + +void Polygon::addPoint (int x, int y) +{ + points->increase (); + points->getRef(points->size () - 1)->x = x; + points->getRef(points->size () - 1)->y = y; + + minx = misc::min(minx, x); + miny = misc::min(miny, y); + maxx = misc::max(maxx, x); + maxy = misc::max(maxy, y); +} + +/** + * \brief Return, whether the line, limited by (ax1, ay1) and (ax2, ay2), + * crosses the unlimited line, determined by two points (bx1, by1) and + * (bx2, by2). + */ +bool Polygon::linesCross0(int ax1, int ay1, int ax2, int ay2, + int bx1, int by1, int bx2, int by2) +{ + /** TODO Some more description */ + // If the scalar product is 0, it means that one point is on the second + // line, so we check for <= 0, not < 0. + int z1 = zOfVectorProduct (ax1 - bx1, ay1 - by1, bx2 - bx1, by2 - by1); + int z2 = zOfVectorProduct (ax2 - bx1, ay2 - by1, bx2 - bx1, by2 - by1); + + return (z1 <= 0 && z2 >= 0) || (z1 >= 0 && z2 <= 0); +} + +/** + * \brief Return, whether the line, limited by (ax1, ay1) and (ax2, ay2), + * crosses the line, limited by (bx1, by1) and (bx2, by2). + */ +bool Polygon::linesCross(int ax1, int ay1, int ax2, int ay2, + int bx1, int by1, int bx2, int by2) +{ + bool cross = + linesCross0 (ax1, ay1, ax2, ay2, bx1, by1, bx2, by2) && + linesCross0 (bx1, by1, bx2, by2, ax1, ay1, ax2, ay2); + _MSG("(%d, %d) - (%d, %d) and (%d, %d) - (%d, %d) cross? %s.\n", + ax1, ay1, ax2, ay2, bx1, by1, bx2, by2, cross ? "Yes" : "No"); + return cross; +} + +bool Polygon::isPointWithin (int x, int y) +{ + if (points->size () < 3 || + (x < minx || x > maxx || y < miny || y >= maxy)) + return false; + else { + int numCrosses = 0; + for (int i = 0; i < points->size () - 1; i++) { + if (linesCross (minx - 1, miny - 1, x, y, + points->getRef(i)->x, points->getRef(i)->y, + points->getRef(i + 1)->x, points->getRef(i + 1)->y)) + numCrosses++; + } + if (linesCross (minx - 1, miny - 1, x, y, + points->getRef(points->size () - 1)->x, + points->getRef(points->size () - 1)->y, + points->getRef(0)->x, points->getRef(0)->y)) + numCrosses++; + + return numCrosses % 2 == 1; + } +} + +Region::Region() +{ + rectangleList = new container::typed::List <Rectangle> (true); +} + +Region::~Region() +{ + delete rectangleList; +} + +/** + * \brief Add a rectangle to the region and combine it with + * existing rectangles if possible. + * The number of rectangles is forced to be less than 16 + * by combining excessive rectangles. + */ +void Region::addRectangle (Rectangle *rPointer) +{ + container::typed::Iterator <Rectangle> it; + Rectangle *r = new Rectangle (rPointer->x, rPointer->y, + rPointer->width, rPointer->height); + + for (it = rectangleList->iterator (); it.hasNext (); ) { + Rectangle *ownRect = it.getNext (); + + int combinedHeight = + misc::max(r->y + r->height, ownRect->y + ownRect->height) - + misc::min(r->y, ownRect->y); + int combinedWidth = + misc::max(r->x + r->width, ownRect->x + ownRect->width) - + misc::min(r->x, ownRect->x); + + if (rectangleList->size() >= 16 || + combinedWidth * combinedHeight <= + ownRect->width * ownRect->height + r->width * r->height) { + + r->x = misc::min(r->x, ownRect->x); + r->y = misc::min(r->y, ownRect->y); + r->width = combinedWidth; + r->height = combinedHeight; + + rectangleList->removeRef (ownRect); + } + } + + rectangleList->append (r); +} + +Content::Type Content::maskForSelection (bool followReferences) +{ + Content::Type widgetMask = (Content::Type) + (Content::WIDGET_IN_FLOW | + (followReferences ? Content::WIDGET_OOF_REF : Content::WIDGET_OOF_CONT)); + return (Content::Type)(Content::SELECTION_CONTENT | widgetMask); +} + +void Content::intoStringBuffer(Content *content, misc::StringBuffer *sb) +{ + switch(content->type) { + case START: + sb->append ("<start>"); + break; + case END: + sb->append ("<end>"); + break; + case TEXT: + sb->append ("\""); + sb->append (content->text); + sb->append ("\""); + break; + case WIDGET_IN_FLOW: + sb->append ("<widget in flow: "); + sb->appendPointer (content->widget); + sb->append (" ("); + sb->append (content->widget->getClassName()); + sb->append (")>"); + break; + case WIDGET_OOF_REF: + sb->append ("<widget oof ref: "); + sb->appendPointer (content->widget); + sb->append (" ("); + sb->append (content->widget->getClassName()); + sb->append (")>"); + break; + case WIDGET_OOF_CONT: + sb->append ("<widget oof cont: "); + sb->appendPointer (content->widget); + sb->append (" ("); + sb->append (content->widget->getClassName()); + sb->append (")>"); + break; + case BREAK: + sb->append ("<break>"); + break; + default: + sb->append ("<"); + sb->appendInt (content->type); + sb->append ("?>"); + break; + } +} + +void Content::maskIntoStringBuffer(Type mask, misc::StringBuffer *sb) +{ + sb->append ((mask & START) ? "st" : "--"); + sb->append (":"); + sb->append ((mask & END) ? "en" : "--"); + sb->append (":"); + sb->append ((mask & TEXT) ? "tx" : "--"); + sb->append (":"); + sb->append ((mask & WIDGET_IN_FLOW) ? "wf" : "--"); + sb->append (":"); + sb->append ((mask & WIDGET_OOF_REF) ? "Wr" : "--"); + sb->append (":"); + sb->append ((mask & WIDGET_OOF_CONT) ? "Wc" : "--"); + sb->append (":"); + sb->append ((mask & BREAK) ? "br" : "--"); +} + +void Content::print (Content *content) +{ + misc::StringBuffer sb; + intoStringBuffer (content, &sb); + printf ("%s", sb.getChars ()); +} + +void Content::printMask (Type mask) +{ + misc::StringBuffer sb; + maskIntoStringBuffer (mask, &sb); + printf ("%s", sb.getChars ()); +} + +} // namespace core +} // namespace dw |