[Kst] branches/work/kst/portto4/kst/src

Barth Netterfield netterfield at astro.utoronto.ca
Fri Oct 28 13:57:52 UTC 2011


SVN commit 1261178 by netterfield:

BUG: 219845	
BUG: 284263

When exporting, all text is now rendered directly to the painter.
All sizes are referenced to the painter's font size.
Exports to PDF or SVG should now look right in all situations.


 M  +64 -42    libkstapp/legenditem.cpp  
 M  +1 -1      libkstapp/legenditem.h  
 M  +3 -4      libkstmath/curve.cpp  
 M  +2 -2      libkstmath/curve.h  
 M  +7 -10     libkstmath/image.cpp  
 M  +2 -2      libkstmath/image.h  
 M  +2 -2      libkstmath/relation.h  


--- branches/work/kst/portto4/kst/src/libkstapp/legenditem.cpp #1261177:1261178
@@ -29,12 +29,7 @@
 
 namespace Kst {
 
-struct DrawnLegendItem {
-  QPixmap pixmap;
-  QSize size;
-};
 
-
 LegendItem::LegendItem(PlotItem *parentPlot)
   : ViewItem(parentPlot->view()), _plotItem(parentPlot), _auto(true), _verticalDisplay(true) {
   setTypeName("Legend");
@@ -86,13 +81,11 @@
   }
 
 
-  QList<DrawnLegendItem> legendPixmaps;
-  QSize legendSize(0, 0);
-
   QFont font(_font);
-  qreal painter_scale = painter->device()->logicalDpiX()/view()->logicalDpiX();
-  font.setPointSizeF(view()->scaledFontSize(_fontScale, *painter->device())*painter_scale);
+  font.setPointSizeF(view()->scaledFontSize(_fontScale, *painter->device()));
 
+  painter->setFont(font);
+
   // generate string list of relation names
   QStringList names;
   bool allAuto = true;
@@ -166,29 +159,58 @@
     }
   }
 
+  QSize legendSize(0, 0);
+  QSize titleSize(0,0);
+  for (int draw = 0; draw<=1; draw++){ // do twice: once to get sizes; second to draw it.
+
+    if (draw) {
+      painter->drawRect(rect());
+    }
+    int x=rect().x();
+    int y=rect().y();
+    if (!_title.isEmpty()) {
+      int pad = painter->fontMetrics().ascent()/4;
+      Label::Parsed *parsed = Label::parse(_title);
+      Label::RenderContext rc(painter->font(), painter);
+      titleSize.setHeight(painter->fontMetrics().height()+pad);
+
+      rc.y = rect().y() + titleSize.height()-pad;
+      rc.x = qMax(rect().x()+pad, rect().x() + legendSize.width()/2 - titleSize.width()/2);
+      int x0 = rc.x;
+
+      Label::renderLabel(rc, parsed->chunk, false, true);
+
+      titleSize.setWidth(rc.x - x0 + 3*pad);
+      y+= titleSize.height();
+    }
+    legendSize.setWidth(0);
+    legendSize.setHeight(0);
   for (int i = 0; i<count; i++) {
     RelationPtr relation = legendItems.at(i);
-    DrawnLegendItem item;
-    item.pixmap = QPixmap(painter_scale*LEGENDITEMMAXWIDTH,
-                          painter_scale*LEGENDITEMMAXHEIGHT);
-    item.size = paintRelation(names.at(i), relation, &item.pixmap, font);
+      QSize size;
+      painter->save();
+      painter->translate(x,y);
+      size = paintRelation(names.at(i), relation, painter, draw);
+      painter->restore();
 
     if (_verticalDisplay) {
-      legendSize.setWidth(qMax(legendSize.width(), item.size.width()));
-      legendSize.setHeight(legendSize.height() + item.size.height());
+        legendSize.setWidth(qMax(legendSize.width(), size.width()));
+        legendSize.setHeight(legendSize.height() + size.height());
+        y+=size.height();
     } else {
-      legendSize.setHeight(qMax(legendSize.height(), item.size.height()));
-      legendSize.setWidth(legendSize.width() + item.size.width());
+        legendSize.setHeight(qMax(legendSize.height(), size.height()));
+        legendSize.setWidth(legendSize.width() + size.width());
+        x+=size.width();
     }
-
-    legendPixmaps.append(item);
   }
+    if (!draw) {
+      setViewRect(rect().x(), rect().y(), qMax(legendSize.width(), titleSize.width()), legendSize.height() + titleSize.height());
+    }
+  }
 
-  int x = rect().left();
-  int y = rect().top();
 
-  painter->save();
 
+#if 0
   if (!_title.isEmpty()) {
     // Paint the title
     Label::Parsed *parsed = Label::parse(_title);
@@ -232,56 +254,56 @@
       x += item.size.width();
     }
   }
-
-  painter->restore();
+#endif
 }
 
 
-QSize LegendItem::paintRelation(QString name, RelationPtr relation, QPixmap *pixmap, const QFont &font) {
+QSize LegendItem::paintRelation(QString name, RelationPtr relation, QPainter *painter, bool draw) {
   Label::Parsed *parsed = Label::parse(name);
   parsed->chunk->attributes.color = _color;
 
-  pixmap->fill(Qt::transparent);
+  int fontHeight = painter->fontMetrics().height();
+  int fontAscent = painter->fontMetrics().ascent();
 
-  QPainter pixmapPainter(pixmap);
-  QFontMetrics fm(font);
-  QSize symbol_size = relation->legendSymbolSize(font);
+  QSize symbol_size = relation->legendSymbolSize(painter);
   int label_width = 0;
-  int paddingValue = fm.height() / 4;
+  int paddingValue = fontHeight / 4;
 
   if (relation->symbolLabelOnTop()) {
-    Label::RenderContext tmprc(font, &pixmapPainter);
+    Label::RenderContext tmprc(painter->font(), painter);
     Label::renderLabel(tmprc, parsed->chunk, false, false);
     label_width = tmprc.x;
-    pixmapPainter.translate(paddingValue, fm.height()+paddingValue / 2);
+    painter->translate(paddingValue, fontHeight+paddingValue / 2);
     symbol_size.setWidth(qMax(label_width, symbol_size.width()));
   } else {
-    pixmapPainter.translate(paddingValue, paddingValue / 2);
+    painter->translate(paddingValue, paddingValue / 2);
   }
 
-  relation->paintLegendSymbol(&pixmapPainter, font, symbol_size);
+  if (draw) {
+    relation->paintLegendSymbol(painter, symbol_size);
+  }
 
-
   if (relation->symbolLabelOnTop()) {
-    pixmapPainter.translate((symbol_size.width()-label_width)/2, fm.ascent() - fm.height());
+    painter->translate((symbol_size.width()-label_width)/2, fontAscent - fontHeight);
   } else {
-    pixmapPainter.translate(symbol_size.width() + paddingValue, 0);
+    painter->translate(symbol_size.width() + paddingValue, 0);
   }
-  Label::RenderContext rc(font, &pixmapPainter);
+  Label::RenderContext rc(painter->font(), painter);
   if (relation->symbolLabelOnTop()) {
     rc.y = 0;
   } else {
-    rc.y = (symbol_size.height()+fm.boundingRect('M').height())/2;
+    rc.y = (symbol_size.height()+painter->fontMetrics().boundingRect('M').height())/2;
   }
   if (parsed) {
-    Label::renderLabel(rc, parsed->chunk, false, true);
+    Label::renderLabel(rc, parsed->chunk, false, draw);
+
     delete parsed;
     parsed = 0;
   }
 
   double h = symbol_size.height() + paddingValue;
   if (relation->symbolLabelOnTop()) {
-    h += fm.height();
+    h += fontHeight;
   }
   if (relation->symbolLabelOnTop()) {
     return QSize(qMax(rc.x,(symbol_size.width())) + (paddingValue * 2), h);
--- branches/work/kst/portto4/kst/src/libkstapp/legenditem.h #1261177:1261178
@@ -85,7 +85,7 @@
     virtual QString _automaticDescriptiveName() const;
     virtual void _initializeShortName();
   private:
-    QSize paintRelation(QString name, RelationPtr relation, QPixmap *pixmap, const QFont &font);
+    QSize paintRelation(QString name, RelationPtr relation, QPainter *painter, bool draw);
 
     PlotItem *_plotItem;
     bool _auto;
--- branches/work/kst/portto4/kst/src/libkstmath/curve.cpp #1261177:1261178
@@ -1565,13 +1565,12 @@
 }
 
 
-QSize Curve::legendSymbolSize(const QFont &font) {
-  QFontMetrics fm(font);
-  return QSize(fm.height()*3.5, fm.height());
+QSize Curve::legendSymbolSize(QPainter *p) {
+  return QSize(p->fontMetrics().height()*3.5, p->fontMetrics().height());
 }
 
 
-void Curve::paintLegendSymbol(QPainter *p, const QFont &font, const QSize &size) {
+void Curve::paintLegendSymbol(QPainter *p, const QSize &size) {
   QRect bound(QPoint(0,0),size);
 
   int width;
--- branches/work/kst/portto4/kst/src/libkstmath/curve.h #1261177:1261178
@@ -146,8 +146,8 @@
     void updatePaintObjects(const CurveRenderContext& context);
 
     // render the legend symbol for this curve
-    virtual QSize legendSymbolSize(const QFont &font);
-    virtual void paintLegendSymbol(QPainter *p, const QFont &font, const QSize &size);
+    virtual QSize legendSymbolSize(QPainter *p);
+    virtual void paintLegendSymbol(QPainter *p, const QSize &size);
     virtual bool symbolLabelOnTop() {return false;}
 
     // see KstRelation::distanceToPoint
--- branches/work/kst/portto4/kst/src/libkstmath/image.cpp #1261177:1261178
@@ -771,23 +771,22 @@
 }
 
 
-QSize Image::legendSymbolSize(const QFont &font) {
-  QFontMetrics fm(font);
-  return QSize(fm.height()*7, 2*fm.height());
+QSize Image::legendSymbolSize(QPainter *p) {
+  return QSize(p->fontMetrics().height()*7, 2*p->fontMetrics().height());
 }
 
 
-void Image::paintLegendSymbol(QPainter *p, const QFont &font, const QSize &size) {
+void Image::paintLegendSymbol(QPainter *p, const QSize &size) {
   QRect bound(QPoint(0,0),size);
-  QFontMetrics fm(font);
 
   if (hasColorMap() && (_pal.colorCount()>0)) {
     double spacing;
     int minor_ticks;
     computeMajorTickSpacing(&spacing, &minor_ticks, TicksCoarse, upperThreshold() - lowerThreshold());
 
-    int l = bound.left(), r = bound.right(), t = bound.top(), b = bound.bottom()-fm.height();
+    int l = bound.left(), r = bound.right(), t = bound.top(), b = bound.bottom()-p->fontMetrics().height();
     // draw the color palette
+    p->drawRect(l,t,(r-l),(b-t));
     p->save();
     for (int i = l; i <= r; i++) {
       int index = (int)floor(static_cast<double>(((i - l) * (_pal.colorCount() - 1))) / (r - l));
@@ -796,19 +795,17 @@
       p->drawLine(i, t, i, b);
     }
     p->restore();
-    p->drawRect(l,t,(r-l),(b-t));
     double min = int(lowerThreshold()/spacing)*spacing;
     if (min<lowerThreshold()) {
       min += spacing;
     }
     p->save();
-    p->setFont(font);
     for (double tick = min; tick < upperThreshold(); tick+=spacing) {
       int x = (tick-lowerThreshold())*(r-l)/(upperThreshold()-lowerThreshold())+l;
-      p->drawLine(x,b,x,b-fm.ascent()/3);
+      p->drawLine(x,b,x,b-p->fontMetrics().ascent()/3);
       QString tickStr = QString::number(tick);
       QRect bound = p->boundingRect(QRect(),Qt::AlignLeft|Qt::AlignBottom, tickStr);
-      p->drawText(QPoint(x-bound.width()/2, b+fm.ascent()), tickStr);
+      p->drawText(QPoint(x-bound.width()/2, b+p->fontMetrics().ascent()), tickStr);
     }
     p->restore();
   } else if (hasContourMap()) {
--- branches/work/kst/portto4/kst/src/libkstmath/image.h #1261177:1261178
@@ -116,8 +116,8 @@
     virtual void yRange(double xFrom, double xTo, double* yMin, double* yMax);
 
     // see KstRelation::paintLegendSymbol
-    virtual QSize legendSymbolSize(const QFont &font);
-    virtual void paintLegendSymbol(QPainter *p, const QFont &font, const QSize &size);
+    virtual QSize legendSymbolSize(QPainter *p);
+    virtual void paintLegendSymbol(QPainter *p, const QSize &size);
     virtual bool symbolLabelOnTop() {return true;}
 
     virtual QString descriptionTip() const;
--- branches/work/kst/portto4/kst/src/libkstmath/relation.h #1261177:1261178
@@ -130,8 +130,8 @@
     virtual void updatePaintObjects(const CurveRenderContext& context) = 0;
 
     // render the legend symbol for this curve
-    virtual QSize legendSymbolSize(const QFont &font) = 0;
-    virtual void paintLegendSymbol(QPainter *p, const QFont &font, const QSize &size) = 0;
+    virtual QSize legendSymbolSize(QPainter *p) = 0;
+    virtual void paintLegendSymbol(QPainter *p, const QSize &size) = 0;
     virtual bool symbolLabelOnTop() = 0;
 
     //virtual SharedPtr<Relation> makeDuplicate(QMap< SharedPtr<Relation>, SharedPtr<Relation> > &duplicatedRelations) = 0;


More information about the Kst mailing list