aboutsummaryrefslogtreecommitdiff
path: root/dw
diff options
context:
space:
mode:
authorSebastian Geerken <devnull@localhost>2012-10-08 10:41:54 +0200
committerSebastian Geerken <devnull@localhost>2012-10-08 10:41:54 +0200
commit24a87b2dcedb21d8d1f3c68036cf644633dd1005 (patch)
tree6b57014ea8c935237960ae0e827661676f758b90 /dw
parent2cd28ca74309f81d295a0860a140e030ee7f80d3 (diff)
Some work on textblock iterators related to floats.
Diffstat (limited to 'dw')
-rw-r--r--dw/outofflowmgr.hh7
-rw-r--r--dw/textblock.cc2
-rw-r--r--dw/textblock.hh3
-rw-r--r--dw/textblock_iterator.cc272
4 files changed, 200 insertions, 84 deletions
diff --git a/dw/outofflowmgr.hh b/dw/outofflowmgr.hh
index c59a62b2..5e96b639 100644
--- a/dw/outofflowmgr.hh
+++ b/dw/outofflowmgr.hh
@@ -91,6 +91,13 @@ public:
//inline static bool isRefOutOfFlow (int ref) { return false; }
//inline static int createRefNormalFlow (int lineNo) { return lineNo; }
//inline static int getLineNoFromRef (int ref) { return ref; }
+
+ // for iterators
+ inline int getNumWidgets () {
+ return leftFloats->size() + rightFloats->size(); }
+ inline core::Widget *getWidget (int i) {
+ return i < leftFloats->size() ? leftFloats->get(i)->widget :
+ rightFloats->get(leftFloats->size())->widget; }
};
} // namespace dw
diff --git a/dw/textblock.cc b/dw/textblock.cc
index ff94486b..c7f254e6 100644
--- a/dw/textblock.cc
+++ b/dw/textblock.cc
@@ -801,7 +801,7 @@ bool Textblock::sendSelectionEvent (core::SelectionState::EventType eventType,
}
}
it = new TextblockIterator (this, core::Content::SELECTION_CONTENT,
- wordIndex);
+ false, wordIndex);
r = selectionHandleEvent (eventType, it, charPos, link, event);
it->unref ();
return r;
diff --git a/dw/textblock.hh b/dw/textblock.hh
index 3a927464..c386a391 100644
--- a/dw/textblock.hh
+++ b/dw/textblock.hh
@@ -315,13 +315,14 @@ protected:
class TextblockIterator: public core::Iterator
{
private:
+ bool oofm;
int index;
public:
TextblockIterator (Textblock *textblock, core::Content::Type mask,
bool atEnd);
TextblockIterator (Textblock *textblock, core::Content::Type mask,
- int index);
+ bool oofm, int index);
lout::object::Object *clone();
int compareTo(lout::misc::Comparable *other);
diff --git a/dw/textblock_iterator.cc b/dw/textblock_iterator.cc
index 63720ffb..d3d8eda5 100644
--- a/dw/textblock_iterator.cc
+++ b/dw/textblock_iterator.cc
@@ -33,20 +33,34 @@ Textblock::TextblockIterator::TextblockIterator (Textblock *textblock,
bool atEnd):
core::Iterator (textblock, mask, atEnd)
{
- index = atEnd ? textblock->words->size () : -1;
+ if (atEnd) {
+ if (textblock->outOfFlowMgr) {
+ oofm = true;
+ index = textblock->outOfFlowMgr->getNumWidgets();
+ } else {
+ oofm = false;
+ index = textblock->words->size();
+ }
+ } else {
+ oofm = false;
+ index = -1;
+ }
+
content.type = atEnd ? core::Content::END : core::Content::START;
}
Textblock::TextblockIterator::TextblockIterator (Textblock *textblock,
core::Content::Type mask,
- int index):
+ bool oofm, int index):
core::Iterator (textblock, mask, false)
{
+ this->oofm = oofm;
this->index = index;
+ // TODO To be completely exact, oofm should be considered here.
if (index < 0)
content.type = core::Content::START;
- else if (index >= textblock->words->size ())
+ else if (index >= textblock->words->size())
content.type = core::Content::END;
else
content = textblock->words->getRef(index)->content;
@@ -54,12 +68,20 @@ Textblock::TextblockIterator::TextblockIterator (Textblock *textblock,
object::Object *Textblock::TextblockIterator::clone()
{
- return new TextblockIterator ((Textblock*)getWidget(), getMask(), index);
+ return
+ new TextblockIterator ((Textblock*)getWidget(), getMask(), oofm, index);
}
int Textblock::TextblockIterator::compareTo(misc::Comparable *other)
{
- return index - ((TextblockIterator*)other)->index;
+ TextblockIterator *otherTI = (TextblockIterator*)other;
+
+ if (oofm && !otherTI->oofm)
+ return +1;
+ else if (!oofm && otherTI->oofm)
+ return -1;
+ else
+ return index - otherTI->index;
}
bool Textblock::TextblockIterator::next ()
@@ -69,15 +91,53 @@ bool Textblock::TextblockIterator::next ()
if (content.type == core::Content::END)
return false;
+ short type;
+
do {
index++;
- if (index >= textblock->words->size ()) {
- content.type = core::Content::END;
- return false;
+
+ if (oofm) {
+ // Iterating over OOFM.
+ if (index >= textblock->outOfFlowMgr->getNumWidgets()) {
+ // End of OOFM list reached.
+ content.type = core::Content::END;
+ return false;
+ }
+ type = core::Content::WIDGET_OOF_CONT;
+ } else {
+ // Iterating over words list.
+ if (index < textblock->words->size ())
+ // Still words left.
+ type = textblock->words->getRef(index)->content.type;
+ else {
+ // End of words list reached.
+ if (textblock->outOfFlowMgr) {
+ oofm = true;
+ index = 0;
+ if (textblock->outOfFlowMgr->getNumWidgets() > 0)
+ // Start with OOFM widgets.
+ type = core::Content::WIDGET_OOF_CONT;
+ else {
+ // No OOFM widgets (number is 0).
+ content.type = core::Content::END;
+ return false;
+ }
+ } else {
+ // No OOFM widgets (no OOFM agt all).
+ content.type = core::Content::END;
+ return false;
+ }
+ }
}
- } while ((textblock->words->getRef(index)->content.type & getMask()) == 0);
+ } while ((type & getMask()) == 0);
+
+ if (oofm) {
+ content.type = core::Content::WIDGET_OOF_CONT;
+ content.type = false;
+ content.widget = textblock->outOfFlowMgr->getWidget (index);
+ } else
+ content = textblock->words->getRef(index)->content;
- content = textblock->words->getRef(index)->content;
return true;
}
@@ -88,70 +148,111 @@ bool Textblock::TextblockIterator::prev ()
if (content.type == core::Content::START)
return false;
+ short type;
+
do {
index--;
- if (index < 0) {
- content.type = core::Content::START;
- return false;
+
+ if (oofm) {
+ // Iterating over OOFM.
+ if (index >= 0)
+ // Still widgets left.
+ type = core::Content::WIDGET_OOF_CONT;
+ else {
+ // Beginning of OOFM list reached. Continue with words.
+ oofm = false;
+ index = textblock->words->size() - 1;
+ if (index < 0) {
+ // There are no words. (Actually, this case should not
+ // happen: When there are OOF widgets, ther must be OOF
+ // references, or widgets in flow, which contain
+ // references.
+ content.type = core::Content::END;
+ return false;
+ }
+ type = textblock->words->getRef(index)->content.type;
+ }
+ } else {
+ // Iterating over words list.
+ if (index < 0) {
+ // Beginning of words list reached.
+ content.type = core::Content::START;
+ return false;
+ }
+ type = textblock->words->getRef(index)->content.type;
}
- } while ((textblock->words->getRef(index)->content.type & getMask()) == 0);
+ } while ((type & getMask()) == 0);
+
+ if (oofm) {
+ content.type = core::Content::WIDGET_OOF_CONT;
+ content.type = false;
+ content.widget = textblock->outOfFlowMgr->getWidget (index);
+ } else
+ content = textblock->words->getRef(index)->content;
- content = textblock->words->getRef(index)->content;
return true;
}
void Textblock::TextblockIterator::highlight (int start, int end,
core::HighlightLayer layer)
{
- Textblock *textblock = (Textblock*)getWidget();
- int index1 = index, index2 = index;
-
- if (textblock->hlStart[layer].index > textblock->hlEnd[layer].index) {
- /* nothing is highlighted */
- textblock->hlStart[layer].index = index;
- textblock->hlEnd[layer].index = index;
- }
-
- if (textblock->hlStart[layer].index >= index) {
- index2 = textblock->hlStart[layer].index;
- textblock->hlStart[layer].index = index;
- textblock->hlStart[layer].nChar = start;
- }
+ if (!oofm) {
+ Textblock *textblock = (Textblock*)getWidget();
+ int index1 = index, index2 = index;
+
+ if (textblock->hlStart[layer].index > textblock->hlEnd[layer].index) {
+ /* nothing is highlighted */
+ textblock->hlStart[layer].index = index;
+ textblock->hlEnd[layer].index = index;
+ }
+
+ if (textblock->hlStart[layer].index >= index) {
+ index2 = textblock->hlStart[layer].index;
+ textblock->hlStart[layer].index = index;
+ textblock->hlStart[layer].nChar = start;
+ }
+
+ if (textblock->hlEnd[layer].index <= index) {
+ index2 = textblock->hlEnd[layer].index;
+ textblock->hlEnd[layer].index = index;
+ textblock->hlEnd[layer].nChar = end;
+ }
- if (textblock->hlEnd[layer].index <= index) {
- index2 = textblock->hlEnd[layer].index;
- textblock->hlEnd[layer].index = index;
- textblock->hlEnd[layer].nChar = end;
+ textblock->queueDrawRange (index1, index2);
}
- textblock->queueDrawRange (index1, index2);
+ // TODO What about OOF widgets?
}
void Textblock::TextblockIterator::unhighlight (int direction,
core::HighlightLayer layer)
{
- Textblock *textblock = (Textblock*)getWidget();
- int index1 = index, index2 = index;
-
- if (textblock->hlStart[layer].index > textblock->hlEnd[layer].index)
- return;
-
- if (direction == 0) {
- index1 = textblock->hlStart[layer].index;
- index2 = textblock->hlEnd[layer].index;
- textblock->hlStart[layer].index = 1;
- textblock->hlEnd[layer].index = 0;
- } else if (direction > 0 && textblock->hlStart[layer].index <= index) {
- index1 = textblock->hlStart[layer].index;
- textblock->hlStart[layer].index = index + 1;
- textblock->hlStart[layer].nChar = 0;
- } else if (direction < 0 && textblock->hlEnd[layer].index >= index) {
- index1 = textblock->hlEnd[layer].index;
- textblock->hlEnd[layer].index = index - 1;
- textblock->hlEnd[layer].nChar = INT_MAX;
+ if (!oofm) {
+ Textblock *textblock = (Textblock*)getWidget();
+ int index1 = index, index2 = index;
+
+ if (textblock->hlStart[layer].index > textblock->hlEnd[layer].index)
+ return;
+
+ if (direction == 0) {
+ index1 = textblock->hlStart[layer].index;
+ index2 = textblock->hlEnd[layer].index;
+ textblock->hlStart[layer].index = 1;
+ textblock->hlEnd[layer].index = 0;
+ } else if (direction > 0 && textblock->hlStart[layer].index <= index) {
+ index1 = textblock->hlStart[layer].index;
+ textblock->hlStart[layer].index = index + 1;
+ textblock->hlStart[layer].nChar = 0;
+ } else if (direction < 0 && textblock->hlEnd[layer].index >= index) {
+ index1 = textblock->hlEnd[layer].index;
+ textblock->hlEnd[layer].index = index - 1;
+ textblock->hlEnd[layer].nChar = INT_MAX;
+ }
+
+ textblock->queueDrawRange (index1, index2);
}
- textblock->queueDrawRange (index1, index2);
+ // TODO What about OOF widgets?
}
void Textblock::queueDrawRange (int index1, int index2)
@@ -183,37 +284,44 @@ void Textblock::TextblockIterator::getAllocation (int start, int end,
core::Allocation *allocation)
{
Textblock *textblock = (Textblock*)getWidget();
- int lineIndex = textblock->findLineOfWord (index);
- Line *line = textblock->lines->getRef (lineIndex);
- Word *word = textblock->words->getRef (index);
- allocation->x =
- textblock->allocation.x + textblock->lineXOffsetWidget (line);
-
- for (int i = line->firstWord; i < index; i++) {
- Word *w = textblock->words->getRef(i);
- allocation->x += w->size.width + w->effSpace;
- }
- if (start > 0 && word->content.type == core::Content::TEXT) {
- allocation->x += textblock->textWidth (word->content.text, 0, start,
- word->style);
- }
- allocation->y = textblock->lineYOffsetCanvas (line) + line->boxAscent -
- word->size.ascent;
-
- allocation->width = word->size.width;
- if (word->content.type == core::Content::TEXT) {
- int wordEnd = strlen(word->content.text);
-
- if (start > 0 || end < wordEnd) {
- end = misc::min(end, wordEnd); /* end could be INT_MAX */
- allocation->width =
- textblock->textWidth (word->content.text, start, end - start,
- word->style);
+ if (oofm) {
+ // TODO Consider start and end?
+ *allocation =
+ *(textblock->outOfFlowMgr->getWidget(index)->getAllocation());
+ } else {
+ int lineIndex = textblock->findLineOfWord (index);
+ Line *line = textblock->lines->getRef (lineIndex);
+ Word *word = textblock->words->getRef (index);
+
+ allocation->x =
+ textblock->allocation.x + textblock->lineXOffsetWidget (line);
+
+ for (int i = line->firstWord; i < index; i++) {
+ Word *w = textblock->words->getRef(i);
+ allocation->x += w->size.width + w->effSpace;
+ }
+ if (start > 0 && word->content.type == core::Content::TEXT) {
+ allocation->x += textblock->textWidth (word->content.text, 0, start,
+ word->style);
+ }
+ allocation->y = textblock->lineYOffsetCanvas (line) + line->boxAscent -
+ word->size.ascent;
+
+ allocation->width = word->size.width;
+ if (word->content.type == core::Content::TEXT) {
+ int wordEnd = strlen(word->content.text);
+
+ if (start > 0 || end < wordEnd) {
+ end = misc::min(end, wordEnd); /* end could be INT_MAX */
+ allocation->width =
+ textblock->textWidth (word->content.text, start, end - start,
+ word->style);
+ }
}
+ allocation->ascent = word->size.ascent;
+ allocation->descent = word->size.descent;
}
- allocation->ascent = word->size.ascent;
- allocation->descent = word->size.descent;
}
} // namespace dw