[prev in list] [next in list] [prev in thread] [next in thread] 

List:       kde-commits
Subject:    =?utf-8?q?=5Bcalligra/textlayout-anchors-boemann=5D_libs/textlay?=
From:       Casper Boemann <cbo () boemann ! dk>
Date:       2011-05-01 12:19:34
Message-ID: 20110501121934.86CA7A60A6 () git ! kde ! org
[Download RAW message or body]

Git commit 1476315005af56327ac6ac14992bfec62779a4a3 by Casper Boemann.
Committed on 01/05/2011 at 11:49.
Pushed by boemann into branch 'textlayout-anchors-boemann'.

More work on getting anchors towork.
We now actually detect them and add them to our internal list during layout
We just never actually place the obstructions at heir right place

M  +3    -6    libs/textlayout/AnchorStrategy.cpp     
M  +4    -1    libs/textlayout/AnchorStrategy.h     
M  +2    -2    libs/textlayout/FloatingAnchorStrategy.cpp     
M  +2    -1    libs/textlayout/FloatingAnchorStrategy.h     
M  +2    -2    libs/textlayout/InlineAnchorStrategy.cpp     
M  +2    -1    libs/textlayout/InlineAnchorStrategy.h     
M  +42   -64   libs/textlayout/KoTextDocumentLayout.cpp     
M  +25   -15   libs/textlayout/KoTextDocumentLayout.h     
M  +3    -2    libs/textlayout/KoTextLayoutArea.cpp     
M  +0    -10   libs/textlayout/KoTextShapeContainerModel.cpp     

http://commits.kde.org/calligra/1476315005af56327ac6ac14992bfec62779a4a3

diff --git a/libs/textlayout/AnchorStrategy.cpp b/libs/textlayout/AnchorStrategy.cpp
index 195d8ac..1446f2c 100644
--- a/libs/textlayout/AnchorStrategy.cpp
+++ b/libs/textlayout/AnchorStrategy.cpp
@@ -31,9 +31,10 @@
 
 
 
-AnchorStrategy::AnchorStrategy(KoTextAnchor *anchor)
+AnchorStrategy::AnchorStrategy(KoTextAnchor *anchor, KoTextLayoutRootArea *rootArea)
         : m_model(0)
         , m_anchor(anchor)
+        , m_rootArea(rootArea)
 {
 }
 
@@ -51,11 +52,7 @@ void AnchorStrategy::detachFromModel()
 /// as multiple shapes can hold 1 text flow; the anchored shape can be moved between \
containers and thus models  void AnchorStrategy::updatePosition(KoShape *shape, const \
QTextDocument *document, int posInDocument)  {
-    KoTextDocumentLayout *lay = \
                qobject_cast<KoTextDocumentLayout*>(document->documentLayout());
-    Q_ASSERT(lay);
-    KoTextLayoutRootArea *rootArea = lay->rootAreaForPosition(posInDocument);
-    Q_ASSERT(rootArea);
-    KoShapeContainer *container = \
dynamic_cast<KoShapeContainer*>(rootArea->associatedShape()); +    KoShapeContainer \
*container = dynamic_cast<KoShapeContainer*>(m_rootArea->associatedShape());  if \
(container == 0) {  if (m_model)
             m_model->removeAnchor(m_anchor);
diff --git a/libs/textlayout/AnchorStrategy.h b/libs/textlayout/AnchorStrategy.h
index 302479f..19285af 100644
--- a/libs/textlayout/AnchorStrategy.h
+++ b/libs/textlayout/AnchorStrategy.h
@@ -24,14 +24,16 @@
 
 class KoTextShapeContainerModel;
 class KoTextShapeData;
+class KoTextLayoutRootArea;
 class KoShape;
 class QTextBlock;
 class QTextLayout;
 
+
 class AnchorStrategy  : public KoAnchorStrategy
 {
 public:
-    AnchorStrategy(KoTextAnchor *anchor);
+    AnchorStrategy(KoTextAnchor *anchor, KoTextLayoutRootArea *rootArea);
     virtual ~AnchorStrategy();
 
     virtual void detachFromModel();
@@ -41,6 +43,7 @@ public:
 private:
     KoTextShapeContainerModel *m_model;
     KoTextAnchor * const m_anchor;
+    KoTextLayoutRootArea *m_rootArea;
 };
 
 #endif /* INLINEANCHORSTRATEGY_H_ */
diff --git a/libs/textlayout/FloatingAnchorStrategy.cpp \
b/libs/textlayout/FloatingAnchorStrategy.cpp index 7b75fb2..fedb7f0 100644
--- a/libs/textlayout/FloatingAnchorStrategy.cpp
+++ b/libs/textlayout/FloatingAnchorStrategy.cpp
@@ -29,8 +29,8 @@
 #include <QTextLayout>
 #include <QTextBlock>
 
-FloatingAnchorStrategy::FloatingAnchorStrategy(KoTextAnchor *anchor)
-        : AnchorStrategy(anchor)
+FloatingAnchorStrategy::FloatingAnchorStrategy(KoTextAnchor *anchor, \
KoTextLayoutRootArea *rootArea) +        : AnchorStrategy(anchor, rootArea)
         , m_anchor(anchor)
         , m_knowledgePoint(-1)
         , m_finished(false)
diff --git a/libs/textlayout/FloatingAnchorStrategy.h \
b/libs/textlayout/FloatingAnchorStrategy.h index 2dc8f85..5ac858a 100644
--- a/libs/textlayout/FloatingAnchorStrategy.h
+++ b/libs/textlayout/FloatingAnchorStrategy.h
@@ -23,6 +23,7 @@
 
 #include "AnchorStrategy.h"
 
+class KoTextLayoutRootArea;
 class KoTextShapeData;
 class QTextBlock;
 class QTextLayout;
@@ -30,7 +31,7 @@ class QTextLayout;
 class FloatingAnchorStrategy  : public AnchorStrategy
 {
 public:
-    FloatingAnchorStrategy(KoTextAnchor *anchor);
+    FloatingAnchorStrategy(KoTextAnchor *anchor, KoTextLayoutRootArea *rootArea);
     ~FloatingAnchorStrategy();
 
     /**
diff --git a/libs/textlayout/InlineAnchorStrategy.cpp \
b/libs/textlayout/InlineAnchorStrategy.cpp index 4f92293..eaacf0c 100644
--- a/libs/textlayout/InlineAnchorStrategy.cpp
+++ b/libs/textlayout/InlineAnchorStrategy.cpp
@@ -25,8 +25,8 @@
 #include <QTextLayout>
 #include <QTextBlock>
 
-InlineAnchorStrategy::InlineAnchorStrategy(KoTextAnchor *anchor)
-        : AnchorStrategy(anchor)
+InlineAnchorStrategy::InlineAnchorStrategy(KoTextAnchor *anchor, \
KoTextLayoutRootArea *rootArea) +        : AnchorStrategy(anchor, rootArea)
         , m_anchor(anchor)
         , m_finished(false)
         , m_relayoutNeeded(false)
diff --git a/libs/textlayout/InlineAnchorStrategy.h \
b/libs/textlayout/InlineAnchorStrategy.h index 4bb8e78..51beccd 100644
--- a/libs/textlayout/InlineAnchorStrategy.h
+++ b/libs/textlayout/InlineAnchorStrategy.h
@@ -22,6 +22,7 @@
 
 #include "AnchorStrategy.h"
 
+class KoTextLayoutRootArea;
 class KoTextShapeData;
 class QTextBlock;
 class QTextLayout;
@@ -29,7 +30,7 @@ class QTextLayout;
 class InlineAnchorStrategy  : public AnchorStrategy
 {
 public:
-    InlineAnchorStrategy(KoTextAnchor *anchor);
+    InlineAnchorStrategy(KoTextAnchor *anchor, KoTextLayoutRootArea *rootArea);
     virtual ~InlineAnchorStrategy();
 
     /**
diff --git a/libs/textlayout/KoTextDocumentLayout.cpp \
b/libs/textlayout/KoTextDocumentLayout.cpp index 0f56562..d929b7b 100644
--- a/libs/textlayout/KoTextDocumentLayout.cpp
+++ b/libs/textlayout/KoTextDocumentLayout.cpp
@@ -90,6 +90,7 @@ public:
 
     QHash<KoShape*,KoTextLayoutObstruction*> anchoredObstructions; // all \
obstructions created in positionInlineObjects because KoTextAnchor from m_textAnchors \
                is in text
     QList<KoTextLayoutObstruction*> freeObstructions; // obstructions affecting the \
current rootArea, and not anchored +    KoTextLayoutRootArea *anchoringRootArea;
 
     qreal defaultTabSizing;
     qreal y;
@@ -120,8 +121,9 @@ KoTextDocumentLayout::KoTextDocumentLayout(QTextDocument *doc, \
KoTextLayoutRootA  
 KoTextDocumentLayout::~KoTextDocumentLayout()
 {
-    unregisterAllObstructions();
-
+    qDeleteAll(d->freeObstructions);
+    qDeleteAll(d->anchoredObstructions);
+    qDeleteAll(d->textAnchors);
     delete d;
 }
 
@@ -277,7 +279,7 @@ void KoTextDocumentLayout::drawInlineObject(QPainter *painter, \
const QRectF &rec  }
 
 
-void KoTextDocumentLayout::positionAnchoredShapes()
+void KoTextDocumentLayout::positionAnchoredObstructions()
 {
     // position anchored objects
 /*    while (positionInlineObjects()) {
@@ -294,7 +296,6 @@ void KoTextDocumentLayout::positionAnchoredShapes()
 // This method is called by qt every time  QTextLine.setWidth()/setNumColums() is \
called  void KoTextDocumentLayout::positionInlineObject(QTextInlineObject item, int \
position, const QTextFormat &format)  {
-        qDebug() << "positionInlineObject called";
     //We are called before layout so that we can position objects
     Q_ASSERT(format.isCharFormat());
     if (d->inlineTextObjectManager == 0)
@@ -307,33 +308,30 @@ void \
KoTextDocumentLayout::positionInlineObject(QTextInlineObject item, int posi  \
KoTextAnchor *anchor = dynamic_cast<KoTextAnchor*>(obj);  if (anchor) {
         qDebug() << "anchor detected";
-        KoShapeContainer *parent = anchor->shape()->parent();
-        if (parent) {
-            /*
-            KWPage page = m_frameSet->pageManager()->page(parent);
-            QRectF pageRect(0,page.offsetInDocument(),page.width(),page.height());
-            QRectF pageContentRect = parent->boundingRect();
-            int pageNumber = m_frameSet->pageManager()->pageNumber(parent);
-
-            anchor->setPageRect(pageRect);
-            //TODO get the right position for headers and footers
-            anchor->setPageContentRect(pageContentRect);
-            anchor->setPageNumber(pageNumber);
+
+        /*
+        KWPage page = m_frameSet->pageManager()->page(parent);
+        QRectF pageRect(0,page.offsetInDocument(),page.width(),page.height());
+        QRectF pageContentRect = parent->boundingRect();
+        int pageNumber = m_frameSet->pageManager()->pageNumber(parent);
+
+        anchor->setPageRect(pageRect);
+        //TODO get the right position for headers and footers
+        anchor->setPageContentRect(pageContentRect);
+        anchor->setPageNumber(pageNumber);
 */
-            // if there is no anchor strategy set then create one
-        qDebug() << "anchor detected 2";
-            if (!anchor->anchorStrategy()) {
-                //place anchored object far away, and let the layout position it \
                later
-                anchor->shape()->setPosition(QPointF(-10000,0));
-
-                if (anchor->behavesAsCharacter()) {
-        qDebug() << "anchor is inline";
-                    anchor->setAnchorStrategy(new InlineAnchorStrategy(anchor));
-                } else {
-                    anchor->setAnchorStrategy(new FloatingAnchorStrategy(anchor));
-                }
-                d->textAnchors.append(anchor);
+        // if there is no anchor strategy set then create one
+        if (!anchor->anchorStrategy()) {
+            //place anchored object far away, and let the layout position it later
+            anchor->shape()->setPosition(QPointF(-10000,0));
+
+            if (anchor->behavesAsCharacter()) {
+    qDebug() << "anchor is inline";
+                anchor->setAnchorStrategy(new InlineAnchorStrategy(anchor, \
d->anchoringRootArea)); +            } else {
+                anchor->setAnchorStrategy(new FloatingAnchorStrategy(anchor, \
d->anchoringRootArea));  }
+            d->textAnchors.append(anchor);
             anchor->updatePosition(document(), item, position, cf);
         }
     }
@@ -342,36 +340,18 @@ void \
KoTextDocumentLayout::positionInlineObject(QTextInlineObject item, int posi  }
 }
 
-void KoTextDocumentLayout::resetAnchor(int resetPosition)
+void KoTextDocumentLayout::beginAnchorCollecting(KoTextLayoutRootArea *rootArea)
 {
-    QList<KoTextAnchor *>::iterator iterBeginErase = d->textAnchors.end();
-    QList<KoTextAnchor *>::iterator iter;
-    for (iter = d->textAnchors.begin(); iter != d->textAnchors.end(); iter++) {
-
-        // if the position of anchor is bigger than resetPosition than remove the \
                anchor from layout
-        if ((*iter)->positionInDocument() >= resetPosition) {
-            (*iter)->anchorStrategy()->reset();
-
-            // delete obstruction
-            if (d->anchoredObstructions.contains((*iter)->shape())) {
-                KoTextLayoutObstruction *obstruction = \
                d->anchoredObstructions.value((*iter)->shape());
-                d->anchoredObstructions.remove((*iter)->shape());
-                delete obstruction;
-            }
-            (*iter)->setAnchorStrategy(0);
-
-            if (iterBeginErase == d->textAnchors.end()) {
-                iterBeginErase = iter;
-            }
-        }
+    foreach(KoTextAnchor *anchor, d->textAnchors) {
+        anchor->anchorStrategy()->reset();
+        anchor->setAnchorStrategy(0);
     }
 
-    d->textAnchors.erase(iterBeginErase,d->textAnchors.end());
+    qDeleteAll(d->anchoredObstructions);
+    d->anchoredObstructions.clear();
+    d->textAnchors.clear();
 
-    // update m_textAnchorIndex if necesary
-    if (d->textAnchorIndex > d->textAnchors.size()) {
-        d->textAnchorIndex = d->textAnchors.size();
-    }
+    d->anchoringRootArea = rootArea;
 }
 
 void KoTextDocumentLayout::resizeInlineObject(QTextInlineObject item, int position, \
const QTextFormat &format) @@ -443,6 +423,8 @@ void KoTextDocumentLayout::layout()
 
             rootArea->setReferenceRect(0, size.width(), d->y, d->y + size.height());
 
+            beginAnchorCollecting(rootArea);
+
             // Layout all that can fit into that root area
             bool finished = rootArea->layout(d->layoutPosition);
 
@@ -484,7 +466,11 @@ void KoTextDocumentLayout::layout()
             d->rootAreaList.append(rootArea);
             QSizeF size = d->provider->suggestSize(rootArea);
             d->freeObstructions = d->provider->relevantObstructions(rootArea);
+
             rootArea->setReferenceRect(0, size.width(), d->y, d->y + size.height());
+
+            beginAnchorCollecting(rootArea);
+
             // Layout all that can fit into that root area
             rootArea->layout(d->layoutPosition);
             d->provider->doPostLayout(rootArea, true);
@@ -561,12 +547,6 @@ void KoTextDocumentLayout::registerInlineObject(const \
                QTextInlineObject &inlineO
     d->inlineObjectExtents.insert(d->inlineObjectOffset + \
inlineObject.textPosition(), pos);  }
 
-void KoTextDocumentLayout::unregisterAllObstructions()
-{
-    qDeleteAll(d->anchoredObstructions);
-    d->anchoredObstructions.clear();
-}
-
 KoInlineObjectExtent KoTextDocumentLayout::inlineObjectExtent(const QTextFragment \
&fragment)  {
     if (d->inlineObjectExtents.contains(fragment.position()))
@@ -576,9 +556,7 @@ KoInlineObjectExtent \
KoTextDocumentLayout::inlineObjectExtent(const QTextFragmen  
 QList<KoTextLayoutObstruction *> KoTextDocumentLayout::currentObstructions()
 {
-//    QList<KoTextLayoutObstruction*> currentObstructions;
-
-    return d->freeObstructions;
+    return d->freeObstructions + d->anchoredObstructions.values();
 }
 
 QList<KoTextLayoutRootArea *> KoTextDocumentLayout::rootAreas() const
diff --git a/libs/textlayout/KoTextDocumentLayout.h \
b/libs/textlayout/KoTextDocumentLayout.h index aad3126..dfacc35 100644
--- a/libs/textlayout/KoTextDocumentLayout.h
+++ b/libs/textlayout/KoTextDocumentLayout.h
@@ -122,28 +122,38 @@ public:
     /// reimplemented to always return 1
     virtual int pageCount() const;
 
-    /** Anchors are special InlineObjects that we detect in positionInlineObject().
+    /**
+     * We have the concept of Obstructions which text has to run around in various \
ways. +     * We maintain two collections of obstructions. The free which are tied to \
just a position +     * (tied to pages), and the anchored obstructions which are each \
anchored to a KoTextAnchor +     *
+     * The free obstructions are collected from the KoTextLayoutRootAreaProvider \
during layout +     *
+     * The anchored obstructions are collected during layout of individual \
QTextLines in the +     * KoTextLayoutArea::layoutBlock() method.
+     */
+ 
+    /// Updates the registration of the shape for run around
+    void updateObstruction(KoShape *shape);
+
+
+    /**
+     * Anchors are special InlineObjects that we detect in positionInlineObject()
      * We save those for later so we can position them during layout instead.
-     * During layout positionAnchoredShapes() is called to do just that.
+     * During KoTextLayoutArea::layout() we call positionAnchoredObstructions()
      */
-    void positionAnchoredShapes();
-    // remove all anchors which document position is bigger or equal to \
                resetPosition
-    void resetAnchor(int resetPosition);
-    // remove inline object
+    /// remove all anchors and associated obstructions and set up for collecting new \
ones +    void beginAnchorCollecting(KoTextLayoutRootArea *rootArea);
+
+    /// Positions all anchored obstructions
+    void positionAnchoredObstructions();
+
+    /// remove inline object
     void removeInlineObject(KoTextAnchor *textAnchor);
 
     void clearInlineObjectRegistry(QTextBlock block);
     KoInlineObjectExtent inlineObjectExtent(const QTextFragment&);
 
-    /// Registers the shape as being relevant for run around at this moment in time
-    void registerObstruction(KoShape *shape);
-
-    /// Updates the registration of the shape for run around
-    void updateObstruction(KoShape *shape);
-
-    /// Clear all registrations of shapest for run around
-    void unregisterAllObstructions();
-
     /**
      * We allow a text document to be distributed onto a sequence of \
                KoTextLayoutRootArea;
      * which brings up the need to figure out which KoTextLayoutRootArea is used for \
                a certain
diff --git a/libs/textlayout/KoTextLayoutArea.cpp \
b/libs/textlayout/KoTextLayoutArea.cpp index b49fac7..690b6ce 100644
--- a/libs/textlayout/KoTextLayoutArea.cpp
+++ b/libs/textlayout/KoTextLayoutArea.cpp
@@ -734,6 +734,9 @@ bool KoTextLayoutArea::layoutBlock(FrameIterator *cursor)
 
     while (line.isValid()) {
         runAroundHelper.setLine(this, line);
+
+        documentLayout()->positionAnchoredObstructions();
+
         runAroundHelper.fit( /* resetHorizontalPosition */ false, QPointF(x(), \
m_y));  
         qreal bottomOfText = line.y() + line.height();
@@ -791,8 +794,6 @@ bool KoTextLayoutArea::layoutBlock(FrameIterator *cursor)
             }
         }
 
-        documentLayout()->positionAnchoredShapes();
-
         // Expand bounding rect so if we have content outside we show it
         expandBoundingLeft(line.x());
         expandBoundingRight(line.x() + line.naturalTextWidth());
diff --git a/libs/textlayout/KoTextShapeContainerModel.cpp \
b/libs/textlayout/KoTextShapeContainerModel.cpp index 3bd549c..80ac07b 100644
--- a/libs/textlayout/KoTextShapeContainerModel.cpp
+++ b/libs/textlayout/KoTextShapeContainerModel.cpp
@@ -231,15 +231,5 @@ void KoTextShapeContainerModel::relayoutInlineObject(KoShape \
                *child)
     KoTextShapeData *data  = \
qobject_cast<KoTextShapeData*>(child->parent()->userData());  Q_ASSERT(data);
     data->setDirty();
-
-    KoTextDocumentLayout *lay = \
                qobject_cast<KoTextDocumentLayout*>(data->document()->documentLayout());
                
-    if (lay) {
-        if (d->children.contains(child)) {
-            Relation relation = d->children.value(child);
-            if (relation.anchor) {
-                lay->resetAnchor(relation.anchor->positionInDocument());
-            }
-        }
-    }
 }
 


[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic