[Kst] [Bug 121068] Arrow view objects not always clipped correctly

Andrew Walker arwalker at sumusltd.com
Wed Feb 1 18:45:46 CET 2006


------- You are receiving this mail because: -------
You are the assignee for the bug, or are watching the assignee.
         
http://bugs.kde.org/show_bug.cgi?id=121068         




------- Additional Comments From arwalker sumusltd com  2006-02-01 18:45 -------
Does the following address your concerns George?

Index: kstviewline.cpp
===================================================================
--- kstviewline.cpp     (revision 504657)
+++ kstviewline.cpp     (working copy)
 @ -22,6 +22,7  @

 #include <klocale.h>

+#include <qbitmap.h>
 #include <qmetaobject.h>
 #include <qpainter.h>
 #include <qvariant.h>
 @ -84,12 +85,34  @
 }


+QRegion KstViewLine::clipRegion() {
+  if (_clipMask.isNull()) {
+    int w = width();
+    QRect rect(0, 0, _geom.bottomRight().x() + w + 1, _geom.bottomRight().y() + w + 1);
+    QBitmap bm(rect.size(), true);
+    if (!bm.isNull()) {
+      KstPainter p;
+      p.setMakingMask(true);
+      p.begin(&bm);
+      p.setViewXForm(true);
+      p.eraseRect(rect);
+      paintSelf(p, QRegion());
+      p.flush();
+      p.end();
+      _clipMask = QRegion(bm);
+    } else {
+      _clipMask = QRegion(); // only invalidate our own variable
+    }
+  }
+
+  return _clipMask;
+}
+
 void KstViewLine::paintSelf(KstPainter& p, const QRegion& bounds) {
   p.save();
   if (p.type() != KstPainter::P_PRINT && p.type() != KstPainter::P_EXPORT) {
     if (p.makingMask()) {
       p.setRasterOp(Qt::SetROP);
-      KstViewObject::paintSelf(p, geometry());
     } else {
       const QRegion clip(clipRegion());
       KstViewObject::paintSelf(p, bounds - clip);
 @ -104,30 +127,14  @
   p.setPen(pen);

   const QRect geom(geometry());
-  int u = 0, v = 0;
-
-  // Adjust for large widths.  We don't want the line clipped because it goes
-  // out of the bounding box.
-  if (_width > 1 && geom.height() > 0) {
-    double theta = atan(geom.width()/geom.height());
-    int w = _width;
-    if (theta >= 0 && theta <= M_PI/4) {
-      u = int(fabs((w / 2.0) * (sin(theta) + cos(theta))));
-      v = int(fabs((w / 2.0) * (1.5*sin(theta) + 0.5*cos(theta))));
-    } else {
-      u = int(fabs((w / 2.0) * (1.5*sin(theta) + 0.5*cos(theta))));
-      v = int(fabs((w / 2.0) * (sin(theta) + cos(theta))));
-    }
-  }
-
   switch (_orientation) {
     case UpLeft:
     case DownRight:
-      p.drawLine(geom.bottomRight() + QPoint(-u, -v), geom.topLeft() + QPoint(u, v));
+      p.drawLine(geom.bottomRight(), geom.topLeft());
       break;
     case UpRight:
     case DownLeft:
-      p.drawLine(geom.bottomLeft() + QPoint(u, -v), geom.topRight() + QPoint(-u, v));
+      p.drawLine(geom.bottomLeft(), geom.topRight());
       break;
   }
   p.restore();
 @ -238,21 +245,21  @
     if (_from.y() < _to.y()) {
       _orientation = DownRight;
       move(_from);
-      resize(QSize(kMax(_width, _to.x() - _from.x() + 1), kMax(_width, _to.y()- _from.y() + 1)));
+      resize(QSize(_to.x() - _from.x() + 1, _to.y() - _from.y() + 1));
     } else {
       _orientation = UpRight;
       move(QPoint(_from.x(), _to.y()));
-      resize(QSize(kMax(_width, _to.x() - _from.x() + 1), kMax(_width, _from.y() - _to.y() + 1)));
+      resize(QSize(_to.x() - _from.x() + 1, _from.y() - _to.y() + 1));
     }
   } else {
     if (_from.y() < _to.y()) {
       _orientation = DownLeft;
       move(QPoint(_to.x(), _from.y()));
-      resize(QSize(kMax(_width, _from.x() - _to.x() + 1), kMax(_width, _to.y()- _from.y() + 1)));
+      resize(QSize(_from.x() - _to.x() + 1, _to.y() - _from.y() + 1));
     } else {
       _orientation = UpLeft;
       move(_to);
-      resize(QSize(kMax(_width, _from.x() - _to.x() + 1), kMax(_width, _from.y() - _to.y() + 1)));
+      resize(QSize(_from.x() - _to.x() + 1, _from.y() - _to.y() + 1));
     }
   }
 }
Index: kstviewline.h
===================================================================
--- kstviewline.h       (revision 504657)
+++ kstviewline.h       (working copy)
 @ -51,7 +51,8  @
     // just calls KstViewObject functions - Q_PROPERTY doesn't work in KstViewObject?
     void setForegroundColor(const QColor& color);
     QColor foregroundColor() const;
-
+    QRegion clipRegion();
+
     virtual void setCapStyle(Qt::PenCapStyle style);
     virtual Qt::PenCapStyle capStyle() const;
     virtual void setPenStyle(Qt::PenStyle style);
Index: kstviewarrow.cpp
===================================================================
--- kstviewarrow.cpp    (revision 504657)
+++ kstviewarrow.cpp    (working copy)
 @ -58,8 +58,8  @
 }


-void KstViewArrow::paintArrow(KstPainter& p, const QPoint& to, const QPoint &from, int w) {
-  double deltax = _toArrowScaling * 2.0 * double(w);
+void KstViewArrow::paintArrow(KstPainter& p, const QPoint& to, const QPoint &from, int w, double arrowScaling) {
+  double deltax = arrowScaling * 2.0 * double(w);
   double theta = atan2(double(from.y() - to.y()), double(from.x() - to.x())) -M_PI / 2.0;
   double sina = sin(theta);
   double cosa = cos(theta);
 @ -81,28 +81,31  @

 QRegion KstViewArrow::clipRegion() {
   if (_clipMask.isNull()) {
+    double arrowScaling = _toArrowScaling;
+    if (_fromArrowScaling > arrowScaling) {
+      arrowScaling = _fromArrowScaling;
+    }
+
+    int w = int(ceil(sqrt(3.0) * arrowScaling * 2.0 * double(width())));
+    QRect rect(0, 0, _geom.bottomRight().x() + w + 1, _geom.bottomRight().y() + w + 1 );
     _myClipMask = QRegion();
-    QBitmap bm1(_geom.bottomRight().x(), _geom.bottomRight().y(), true);
-    if (!bm1.isNull()) {
+    QBitmap bm(rect.size(), true);
+    if (!bm.isNull()) {
       KstPainter p;
       p.setMakingMask(true);
-      p.begin(&bm1);
+      p.begin(&bm);
       p.setViewXForm(true);
+
       KstViewLine::paintSelf(p, QRegion());
       p.flush();
-      p.end();
-      _clipMask = QRegion(bm1);
-    }
-    QBitmap bm2(_geom.bottomRight().x(), _geom.bottomRight().y(), true);
-    if (!bm2.isNull()) {
-      KstPainter p;
-      p.setMakingMask(true);
-      p.begin(&bm2);
-      p.setViewXForm(true);
-      paintSelf(p, QRegion());
+      _clipMask = QRegion(bm);
+
+      p.eraseRect(rect);
+      paintSelf(p, QRegion());
       p.flush();
+      _myClipMask = QRegion(bm);
+
       p.end();
-      _myClipMask = QRegion(bm2);
     }
   }

 @ -121,7 +124,7  @
       p.setClipRegion(bounds & clip);
     }
   } else {
-      KstViewLine::paintSelf(p, bounds);
+    KstViewLine::paintSelf(p, bounds);
   }

   if (hasArrow()) {
 @ -135,10 +138,10  @
     p.setBrush(_foregroundColor);

     if (_hasToArrow) {
-      paintArrow(p, to, from, w);
+      paintArrow(p, to, from, w, _toArrowScaling);
     }
     if (_hasFromArrow) {
-      paintArrow(p, from, to, w);
+      paintArrow(p, from, to, w, _fromArrowScaling);
     }
   }
   p.restore();
Index: kstviewarrow.h
===================================================================
--- kstviewarrow.h      (revision 504657)
+++ kstviewarrow.h      (working copy)
 @ -39,7 +39,7  @
     QMap<QString, QVariant > widgetHints(const QString& propertyName) const;

     void paintSelf(KstPainter& p, const QRegion& bounds);
-    void paintArrow(KstPainter& p, const QPoint& to, const QPoint &from, int w);
+    void paintArrow(KstPainter& p, const QPoint& to, const QPoint &from, int w, double arrowScaling);
     // true if either end has an arrow
     bool hasArrow() const;


More information about the Kst mailing list