[QGIS Commit] r10906 - in branches/symbology-ng-branch/src: core plugins/labeling

svn_qgis at osgeo.org svn_qgis at osgeo.org
Fri Jun 12 07:45:21 EDT 2009


Author: wonder
Date: 2009-06-12 07:45:20 -0400 (Fri, 12 Jun 2009)
New Revision: 10906

Modified:
   branches/symbology-ng-branch/src/core/qgsvectorlayer.cpp
   branches/symbology-ng-branch/src/core/qgsvectorlayer.h
   branches/symbology-ng-branch/src/plugins/labeling/labeling.cpp
   branches/symbology-ng-branch/src/plugins/labeling/labelinggui.cpp
   branches/symbology-ng-branch/src/plugins/labeling/labelinggui.h
   branches/symbology-ng-branch/src/plugins/labeling/pallabeling.cpp
   branches/symbology-ng-branch/src/plugins/labeling/pallabeling.h
Log:
Features for labeling are now extracted in the main drawing loop (using a pair of hooks).
This avoids one more iteration through the layer.


Modified: branches/symbology-ng-branch/src/core/qgsvectorlayer.cpp
===================================================================
--- branches/symbology-ng-branch/src/core/qgsvectorlayer.cpp	2009-06-11 21:17:20 UTC (rev 10905)
+++ branches/symbology-ng-branch/src/core/qgsvectorlayer.cpp	2009-06-12 11:45:20 UTC (rev 10906)
@@ -105,7 +105,9 @@
     mLabelOn( false ),
     mFetching( false ),
     mRendererV2( NULL ),
-    mUsingRendererV2( false )
+    mUsingRendererV2( false ),
+    mLabelingPrepareLayerHook( NULL ),
+    mLabelingRegisterFeatureHook( NULL )
 {
   mActions = new QgsAttributeAction;
 
@@ -696,11 +698,29 @@
     
     QgsFeature fet;
     QgsAttributeList attributes = mRendererV2->usedAttributes();
+
+    bool labeling = FALSE;
+    if (mLabelingPrepareLayerHook)
+    {
+      int attrIndex;
+      if (mLabelingPrepareLayerHook(mLabelingContext, mLabelingLayerContext, attrIndex))
+      {
+        if (!attributes.contains(attrIndex))
+          attributes << attrIndex;
+        labeling = TRUE;
+      }
+    }
+
     select( attributes, rendererContext.extent() );
 
     while ( nextFeature( fet ) )
     {
       mRendererV2->renderFeature(fet, rendererContext);
+
+      if (labeling && mLabelingRegisterFeatureHook)
+      {
+        mLabelingRegisterFeatureHook(fet, mLabelingLayerContext);
+      }
     }
     
     mRendererV2->stopRender(rendererContext);
@@ -739,6 +759,19 @@
     int featureCount = 0;
     QgsFeature fet;
     QgsAttributeList attributes = mRenderer->classificationAttributes();
+
+    bool labeling = FALSE;
+    if (mLabelingPrepareLayerHook)
+    {
+      int attrIndex;
+      if (mLabelingPrepareLayerHook(mLabelingContext, mLabelingLayerContext, attrIndex))
+      {
+        if (!attributes.contains(attrIndex))
+          attributes << attrIndex;
+        labeling = TRUE;
+      }
+    }
+
     select( attributes, rendererContext.extent() );
 
     try
@@ -801,6 +834,11 @@
           rendererContext.rasterScaleFactor(),
           rendererContext.drawEditingInformation() );
 
+        if (labeling && mLabelingRegisterFeatureHook)
+        {
+          mLabelingRegisterFeatureHook(fet, mLabelingLayerContext);
+        }
+
         ++featureCount;
       }
     }
@@ -2087,6 +2125,18 @@
   return mLabelOn;
 }
 
+void QgsVectorLayer::setLabelingHooks(LabelingPrepareLayerHook prepareLayerHook,
+                                      LabelingRegisterFeatureHook registerFeatureHook,
+                                      void* context,
+                                      void* layerContext)
+{
+  mLabelingPrepareLayerHook = prepareLayerHook;
+  mLabelingRegisterFeatureHook = registerFeatureHook;
+  mLabelingContext = context;
+  mLabelingLayerContext = layerContext;
+}
+
+
 bool QgsVectorLayer::startEditing()
 {
   if ( !mDataProvider )

Modified: branches/symbology-ng-branch/src/core/qgsvectorlayer.h
===================================================================
--- branches/symbology-ng-branch/src/core/qgsvectorlayer.h	2009-06-11 21:17:20 UTC (rev 10905)
+++ branches/symbology-ng-branch/src/core/qgsvectorlayer.h	2009-06-12 11:45:20 UTC (rev 10906)
@@ -54,6 +54,10 @@
 typedef QSet<int> QgsFeatureIds;
 typedef QSet<int> QgsAttributeIds;
 
+typedef int (*LabelingPrepareLayerHook)(void*, void*, int&);
+typedef void (*LabelingRegisterFeatureHook)(QgsFeature&, void*);
+
+
 /** \ingroup core
  * Vector layer backed by a data source provider.
  */
@@ -340,6 +344,11 @@
     /** Label is on */
     bool hasLabelsEnabled( void ) const;
 
+    void setLabelingHooks(LabelingPrepareLayerHook prepareLayerHook,
+                          LabelingRegisterFeatureHook registerFeatureHook,
+                          void* mLabelingContext,
+                          void* mLabelingLayerContext);
+
     /** Returns true if the provider is in editing mode */
     virtual bool isEditable() const;
 
@@ -667,6 +676,12 @@
     /** Label */
     QgsLabel *mLabel;
 
+    LabelingPrepareLayerHook mLabelingPrepareLayerHook;
+    LabelingRegisterFeatureHook mLabelingRegisterFeatureHook;
+    void* mLabelingContext;
+    void* mLabelingLayerContext;
+
+
     /** Display labels */
     bool mLabelOn;
 

Modified: branches/symbology-ng-branch/src/plugins/labeling/labeling.cpp
===================================================================
--- branches/symbology-ng-branch/src/plugins/labeling/labeling.cpp	2009-06-11 21:17:20 UTC (rev 10905)
+++ branches/symbology-ng-branch/src/plugins/labeling/labeling.cpp	2009-06-12 11:45:20 UTC (rev 10906)
@@ -89,17 +89,6 @@
 
 void Labeling::doLabeling( QPainter * painter )
 {
-  int w = painter->device()->width();
-  int h = painter->device()->height();
-
-
-  QgsMapLayer* layer = mQGisIface->activeLayer();
-  if (layer == NULL || layer->type() != QgsMapLayer::VectorLayer)
-  {
-    painter->drawLine(0,0,w,h);
-    return;
-  }
-
   mLBL->doLabeling(painter);
 }
 

Modified: branches/symbology-ng-branch/src/plugins/labeling/labelinggui.cpp
===================================================================
--- branches/symbology-ng-branch/src/plugins/labeling/labelinggui.cpp	2009-06-11 21:17:20 UTC (rev 10905)
+++ branches/symbology-ng-branch/src/plugins/labeling/labelinggui.cpp	2009-06-12 11:45:20 UTC (rev 10906)
@@ -42,7 +42,7 @@
   populatePlacementMethods();
   populateFieldNames();
 
-  PalLabeling::LayerSettings lyr = lbl->layer(layerId);
+  LayerSettings lyr = lbl->layer(layerId);
   if (!lyr.layerId.isEmpty())
   {
     // load the labeling settings
@@ -74,12 +74,12 @@
   return static_cast<QgsVectorLayer*>(layer);
 }
 
-PalLabeling::LayerSettings LabelingGui::layerSettings()
+LayerSettings LabelingGui::layerSettings()
 {
-  PalLabeling::LayerSettings lyr;
+  LayerSettings lyr;
   lyr.layerId = mLayerId;
   lyr.fieldName = cboFieldName->currentText();
-  lyr.placement = (PalLabeling::Placement) cboPlacement->itemData(cboPlacement->currentIndex()).toInt();
+  lyr.placement = (LayerSettings::Placement) cboPlacement->itemData(cboPlacement->currentIndex()).toInt();
   lyr.textColor = btnTextColor->color();
   lyr.textFont = lblFontPreview->font();
   lyr.enabled = chkEnableLabeling->isChecked();
@@ -94,18 +94,18 @@
   switch (layer()->geometryType())
   {
     case QGis::Point:
-      cboPlacement->addItem(tr("Around the point"), QVariant(PalLabeling::AroundPoint));
+      cboPlacement->addItem(tr("Around the point"), QVariant(LayerSettings::AroundPoint));
       break;
     case QGis::Line:
-      cboPlacement->addItem(tr("On the line"), QVariant(PalLabeling::OnLine));
-      cboPlacement->addItem(tr("Around the line"), QVariant(PalLabeling::AroundLine));
+      cboPlacement->addItem(tr("On the line"), QVariant(LayerSettings::OnLine));
+      cboPlacement->addItem(tr("Around the line"), QVariant(LayerSettings::AroundLine));
       break;
     case QGis::Polygon:
-      cboPlacement->addItem(tr("Horizontal"), QVariant(PalLabeling::Horizontal));
-      cboPlacement->addItem(tr("Free"), QVariant(PalLabeling::Free));
-      cboPlacement->addItem(tr("Around the centroid"), QVariant(PalLabeling::AroundPoint));
-      cboPlacement->addItem(tr("On the perimeter"), QVariant(PalLabeling::OnLine));
-      cboPlacement->addItem(tr("Around the perimeter"), QVariant(PalLabeling::AroundLine));
+      cboPlacement->addItem(tr("Horizontal"), QVariant(LayerSettings::Horizontal));
+      cboPlacement->addItem(tr("Free"), QVariant(LayerSettings::Free));
+      cboPlacement->addItem(tr("Around the centroid"), QVariant(LayerSettings::AroundPoint));
+      cboPlacement->addItem(tr("On the perimeter"), QVariant(LayerSettings::OnLine));
+      cboPlacement->addItem(tr("Around the perimeter"), QVariant(LayerSettings::AroundLine));
       break;
   }
 }

Modified: branches/symbology-ng-branch/src/plugins/labeling/labelinggui.h
===================================================================
--- branches/symbology-ng-branch/src/plugins/labeling/labelinggui.h	2009-06-11 21:17:20 UTC (rev 10905)
+++ branches/symbology-ng-branch/src/plugins/labeling/labelinggui.h	2009-06-12 11:45:20 UTC (rev 10906)
@@ -35,7 +35,7 @@
     LabelingGui( PalLabeling* lbl, QString layerId, QWidget* parent );
     ~LabelingGui();
 
-    PalLabeling::LayerSettings layerSettings();
+    LayerSettings layerSettings();
 
   public slots:
     void changeTextColor();

Modified: branches/symbology-ng-branch/src/plugins/labeling/pallabeling.cpp
===================================================================
--- branches/symbology-ng-branch/src/plugins/labeling/pallabeling.cpp	2009-06-11 21:17:20 UTC (rev 10905)
+++ branches/symbology-ng-branch/src/plugins/labeling/pallabeling.cpp	2009-06-12 11:45:20 UTC (rev 10906)
@@ -59,12 +59,48 @@
   int mId;
 };
 
+// -------------
 
+LayerSettings::LayerSettings()
+  : palLayer(NULL), fontMetrics(NULL)
+{
+}
 
+LayerSettings::~LayerSettings()
+{
+  // pal layer is deleted internally in PAL
+  delete fontMetrics;
+}
+
+void LayerSettings::calculateLabelSize(QString text, double& labelX, double& labelY)
+{
+  //QFontMetrics fontMetrics(textFont);
+  QRect labelRect = /*QRect(0,0,20,20);*/ fontMetrics->boundingRect(text);
+
+  // 2px border...
+  QgsPoint ptSize = xform->toMapCoordinates( labelRect.width()+2,labelRect.height()+2 );
+  labelX = fabs(ptSize.x()-ptZero.x());
+  labelY = fabs(ptSize.y()-ptZero.y());
+}
+
+void LayerSettings::registerFeature(QgsFeature& f)
+{
+  QString labelText = f.attributeMap()[fieldIndex].toString();
+  double labelX, labelY; // will receive label size
+  calculateLabelSize(labelText, labelX, labelY);
+
+  //std::cout << labelX << " " << labelY << std::endl;
+  MyLabel* lbl = new MyLabel(f.id(), labelText, GEOSGeom_clone( f.geometry()->asGeos() ) );
+
+  // register feature to the layer
+  palLayer->registerFeature(lbl->strId(), lbl, labelX, labelY);
+}
+
+
 // -------------
 
 PalLabeling::PalLabeling(QgsMapCanvas* mapCanvas)
-  : mMapCanvas(mapCanvas)
+  : mMapCanvas(mapCanvas), mPal(NULL)
 {
   // find out engine defaults
   Pal p;
@@ -79,11 +115,31 @@
     case POPMUSIC_CHAIN: mSearch = Popmusic_Chain; break;
     case POPMUSIC_TABU_CHAIN: mSearch = Popmusic_Tabu_Chain; break;
   }
+
+  initPal();
 }
 
+
+PalLabeling::~PalLabeling()
+{
+  delete mPal;
+
+  // make sure to remove hooks from all layers
+  while (mLayers.count())
+  {
+    removeLayer(mLayers[0].layerId);
+  }
+}
+
+
 void PalLabeling::addLayer(LayerSettings layerSettings)
 {
   mLayers.append(layerSettings);
+
+  QgsVectorLayer* vlayer = (QgsVectorLayer*) QgsMapLayerRegistry::instance()->mapLayer(layerSettings.layerId);
+
+  LayerSettings& lyr = mLayers[ mLayers.count()-1 ]; // make sure we have the right pointer
+  vlayer->setLabelingHooks(PalLabeling::prepareLayerHook, PalLabeling::registerFeatureHook, this, &lyr);
 }
 
 void PalLabeling::removeLayer(QString layerId)
@@ -92,13 +148,16 @@
   {
     if (mLayers.at(i).layerId == layerId)
     {
+      QgsVectorLayer* vlayer = (QgsVectorLayer*) QgsMapLayerRegistry::instance()->mapLayer(mLayers.at(i).layerId);
+      if (vlayer) { vlayer->setLabelingHooks(NULL, NULL, NULL, NULL); }
+
       mLayers.removeAt(i);
       return;
     }
   }
 }
 
-PalLabeling::LayerSettings PalLabeling::layer(QString layerId)
+LayerSettings PalLabeling::layer(QString layerId)
 {
   for (int i = 0; i < mLayers.count(); i++)
   {
@@ -111,71 +170,63 @@
 }
 
 
-int PalLabeling::prepareLayer(Pal& pal, const LayerSettings& lyr)
+
+int PalLabeling::prepareLayerHook(void* context, void* layerContext, int& attrIndex)
 {
-  if (!lyr.enabled)
-    return 0;
+  PalLabeling* thisClass = (PalLabeling*) context;
+  LayerSettings* lyr = (LayerSettings*) layerContext;
 
-  QgsVectorLayer* vlayer = (QgsVectorLayer*) QgsMapLayerRegistry::instance()->mapLayer(lyr.layerId);
+  QgsVectorLayer* vlayer = (QgsVectorLayer*) QgsMapLayerRegistry::instance()->mapLayer(lyr->layerId);
   if (vlayer == NULL)
     return 0;
 
-  QgsAttributeList attrs;
-
-  int fldName = vlayer->dataProvider()->fieldNameIndex(lyr.fieldName);
-  if (fldName == -1)
+  // find out which field will be needed
+  int fldIndex = vlayer->dataProvider()->fieldNameIndex(lyr->fieldName);
+  if (fldIndex == -1)
     return 0;
-  attrs << fldName;
-  vlayer->select(attrs, mMapCanvas->extent());
+  attrIndex = fldIndex;
 
 
   // how to place the labels
   Arrangement arrangement;
-  switch (lyr.placement)
+  switch (lyr->placement)
   {
-    case AroundPoint: arrangement = P_POINT; break;
-    case OnLine:      arrangement = P_LINE; break;
-    case AroundLine:  arrangement = P_LINE_AROUND; break;
-    case Horizontal:  arrangement = P_HORIZ; break;
-    case Free:        arrangement = P_FREE; break;
+    case LayerSettings::AroundPoint: arrangement = P_POINT; break;
+    case LayerSettings::OnLine:      arrangement = P_LINE; break;
+    case LayerSettings::AroundLine:  arrangement = P_LINE_AROUND; break;
+    case LayerSettings::Horizontal:  arrangement = P_HORIZ; break;
+    case LayerSettings::Free:        arrangement = P_FREE; break;
   }
 
   // create the pal layer
-  double priority = 1 - lyr.priority/10.0; // convert 0..10 --> 1..0
-  Layer* l = pal.addLayer(lyr.layerId.toLocal8Bit().data(), -1, -1, arrangement, METER, priority, lyr.obstacle, true, true);
+  double priority = 1 - lyr->priority/10.0; // convert 0..10 --> 1..0
+  Layer* l = thisClass->mPal->addLayer(lyr->layerId.toLocal8Bit().data(), -1, -1, arrangement, METER, priority, lyr->obstacle, true, true);
 
-  QFontMetrics fm(lyr.textFont);
+  // save the pal layer to our layer context (with some additional info)
+  lyr->palLayer = l;
+  lyr->fieldIndex = fldIndex;
+  lyr->fontMetrics = new QFontMetrics(lyr->textFont);
+  lyr->fontBaseline = lyr->fontMetrics->boundingRect("X").bottom(); // dummy text to find out how many pixels of the text are below the baseline
+  lyr->xform = thisClass->mMapCanvas->mapRenderer()->coordinateTransform();
+  lyr->ptZero = lyr->xform->toMapCoordinates( 0,0 );
 
-  QgsFeature f;
-  int feats = 0;
-  const QgsMapToPixel* xform = mMapCanvas->mapRenderer()->coordinateTransform();
-  QgsPoint ptZero = xform->toMapCoordinates( 0,0 );
+  return 1; // init successful
+}
 
-  while (vlayer->nextFeature(f))
-  {
-    QString labelText = f.attributeMap()[fldName].toString();
-    QRect labelRect = fm.boundingRect(labelText);
-    //std::cout << "bound: " << labelRect.width() << "x" << labelRect.height() << std::endl;
-    // 2px border...
-    QgsPoint ptSize = xform->toMapCoordinates( labelRect.width()+2,labelRect.height()+2 );
-    double labelX = fabs(ptSize.x()-ptZero.x());
-    double labelY = fabs(ptSize.y()-ptZero.y());
-    //std::cout << "L " << labelX << " " << labelY << std::endl;
-
-    MyLabel* lbl = new MyLabel(f.id(), labelText, GEOSGeom_clone( f.geometry()->asGeos() ) );
-
-    // TODO: owner of the id?
-    l->registerFeature(lbl->strId(), lbl, labelX, labelY);
-    feats++;
-  }
-
-  return feats;
+void PalLabeling::registerFeatureHook(QgsFeature& f, void* layerContext)
+{
+  LayerSettings* lyr = (LayerSettings*) layerContext;
+  lyr->registerFeature(f);
 }
 
 
-void PalLabeling::doLabeling(QPainter* painter)
+void PalLabeling::initPal()
 {
-  Pal p;
+  // delete if exists already
+  if (mPal)
+    delete mPal;
+  
+  mPal = new Pal;
 
   SearchMethod s;
   switch (mSearch)
@@ -185,32 +236,31 @@
     case Popmusic_Chain: s = POPMUSIC_CHAIN; break;
     case Popmusic_Tabu_Chain: s = POPMUSIC_TABU_CHAIN; break;
   }
-  p.setSearch(s);
+  mPal->setSearch(s);
 
   // set number of candidates generated per feature
-  p.setPointP(mCandPoint);
-  p.setLineP(mCandLine);
-  p.setPolyP(mCandPolygon);
+  mPal->setPointP(mCandPoint);
+  mPal->setLineP(mCandLine);
+  mPal->setPolyP(mCandPolygon);
+}
 
-  //p.setSearch(POPMUSIC_TABU_CHAIN);// this is really slow! // default is CHAIN (worst, fastest)
-  // TODO: API 0.2 - no mention about changing map units!
-  // pal map units = METER by default ... change setMapUnit
-  //p.setMapUnit(METER);
-  // pal label units ... to be chosen
-  // pal dist label - pixels?
 
+
+void PalLabeling::doLabeling(QPainter* painter)
+{
+
   QTime t;
   t.start();
 
-  int feats = 0;
+  // make sure to delete fontmetrics otherwise it crashes inside Qt when drawing... :-(
+  // probably gets invalid when setting fonts in the label drawing loop
   for (int i = 0; i < mLayers.count(); i++)
   {
-    feats += prepareLayer(p, mLayers.at(i));
+    LayerSettings& lyr = mLayers[i];
+    delete lyr.fontMetrics;
+    lyr.fontMetrics = NULL;
   }
 
-  std::cout << "LABELING prepare: " << t.elapsed() << "ms" << std::endl;
-  t.restart();
-
   // do the labeling itself
   double scale = 1; // scale denominator
   QgsRectangle r = mMapCanvas->extent();
@@ -219,7 +269,7 @@
   std::list<Label*>* labels;
   try
   {
-     labels = p.labeller(scale, bbox, NULL, false);
+     labels = mPal->labeller(scale, bbox, NULL, false);
   }
   catch ( std::exception e )
   {
@@ -227,14 +277,9 @@
     return;
   }
 
-  std::cout << "LABELING work:   " << t.elapsed() << "ms" << std::endl;
-  std::cout << "-->> " << labels->size() << "/" << feats << std::endl;
+  std::cout << "LABELING work:   " << t.elapsed() << "ms  ... labels# " << labels->size() << std::endl;
   t.restart();
 
-  QFontMetrics fm = painter->fontMetrics();
-  QRect labelRect = fm.boundingRect("X"); // dummy text to find out height
-  int baseline = labelRect.bottom(); // how many pixels of the text are below the baseline
-
   // draw the labels
   const QgsMapToPixel* xform = mMapCanvas->mapRenderer()->coordinateTransform();
   std::list<Label*>::iterator it = labels->begin();
@@ -251,7 +296,7 @@
     painter->save();
     painter->setPen( lyr.textColor );
     painter->setFont( lyr.textFont );
-    painter->translate( QPointF(outPt.x()+1, outPt.y()-1-baseline) );
+    painter->translate( QPointF(outPt.x()+1, outPt.y()-1-lyr.fontBaseline) );
     painter->rotate(-label->getRotation() * 180 / M_PI );
     painter->drawText(0,0, ((MyLabel*)label->getGeometry())->text());
     painter->restore();
@@ -263,6 +308,9 @@
   std::cout << "LABELING draw:   " << t.elapsed() << "ms" << std::endl;
 
   delete labels;
+
+  // re-create PAL
+  initPal();
 }
 
 void PalLabeling::numCandidatePositions(int& candPoint, int& candLine, int& candPolygon)

Modified: branches/symbology-ng-branch/src/plugins/labeling/pallabeling.h
===================================================================
--- branches/symbology-ng-branch/src/plugins/labeling/pallabeling.h	2009-06-11 21:17:20 UTC (rev 10905)
+++ branches/symbology-ng-branch/src/plugins/labeling/pallabeling.h	2009-06-12 11:45:20 UTC (rev 10906)
@@ -11,35 +11,59 @@
 namespace pal
 {
   class Pal;
+  class Layer;
 }
 
+class QgsMapToPixel;
+class QgsFeature;
+#include "qgspoint.h"
+
+
+class LayerSettings
+{
+public:
+  LayerSettings();
+  ~LayerSettings();
+
+  enum Placement
+  {
+    AroundPoint, // Point / Polygon
+    OnLine, // Line / Polygon
+    AroundLine, // Line / Polygon
+    Horizontal, // Polygon
+    Free // Polygon
+  };
+
+  QString layerId;
+  QString fieldName;
+  Placement placement;
+  QFont textFont;
+  QColor textColor;
+  bool enabled;
+  int priority; // 0 = low, 10 = high
+  bool obstacle; // whether it's an obstacle
+
+  // called from register feature hook
+  void calculateLabelSize(QString text, double& labelX, double& labelY);
+
+  // implementation of register feature hook
+  void registerFeature(QgsFeature& f);
+
+  // temporary stuff: set when layer gets prepared
+  pal::Layer* palLayer;
+  int fieldIndex;
+  QFontMetrics* fontMetrics;
+  int fontBaseline;
+  const QgsMapToPixel* xform;
+  QgsPoint ptZero;
+};
+
 class PalLabeling
 {
 public:
     PalLabeling(QgsMapCanvas* mapCanvas);
+    ~PalLabeling();
 
-    enum Placement
-    {
-      AroundPoint, // Point / Polygon
-      OnLine, // Line / Polygon
-      AroundLine, // Line / Polygon
-      Horizontal, // Polygon
-      Free // Polygon
-    };
-
-    struct LayerSettings
-    {
-      //LayerSettings()
-      QString layerId;
-      QString fieldName;
-      Placement placement;
-      QFont textFont;
-      QColor textColor;
-      bool enabled;
-      int priority; // 0 = low, 10 = high
-      bool obstacle; // whether it's an obstacle
-    };
-
     void doLabeling(QPainter* painter);
 
     void addLayer(LayerSettings layerSettings);
@@ -56,14 +80,23 @@
     void setSearchMethod(Search s);
     Search searchMethod() const;
 
+
+    //! hook called when drawing layer before issuing select()
+    static int prepareLayerHook(void* context, void* layerContext, int& attrIndex);
+    //! hook called when drawing for every feature in a layer
+    static void registerFeatureHook(QgsFeature& f, void* layerContext);
+
 protected:
-    int prepareLayer(pal::Pal& pal, const LayerSettings& lyr);
 
+    void initPal();
+
 protected:
     QList<LayerSettings> mLayers;
     QgsMapCanvas* mMapCanvas;
     int mCandPoint, mCandLine, mCandPolygon;
     Search mSearch;
+
+    pal::Pal* mPal;
 };
 
 #endif // PALLABELING_H



More information about the QGIS-commit mailing list