Am Montag, 21. Februar 2005 09:22 schrieb Andre Poenitz:
> I think replacing 
> 
>  void DocIterator::forwardPar()
>  {
>   forwardPos();
>   while (!empty() && (!inTexted() || pos() != 0))
>    forwardPos();
>  }
> 
> with something more sensible would be better. Most likely a cut&paste
> job from forwardPos, but not stepping over all characters, but only over
> insets.

I tried that. The good news: I have something that gives instant paragraph 
break with the user guide on a 2.6 GHz P4 (I'll try the slow machine 
tomorrow). I could find no bugs so far. The bad news: The code is 
probably still too complicated, and if we are going to use this we need 
to put some explanations in.

I started by turning this

forwardPos();
while (!empty() && (!inTexted() || pos() != 0))
 forwardPos();


into a do-while loop:

do
 forwardPos();
while (!empty() && (!inTexted() || pos() != 0));


and then replacing forwardPos() by the actual code of forwardPos(). I 
tried to remove parts of it then, but I always got segfaults (it seemed 
that pariterator got into an inconsistent state).

The only change that seems to make all the difference is this:

#ifdef SLOW_forwardPar
 ++tip.pos();
#else
 tip.pos() = lastp;
#endif

If you want to test this you need Jean-Marcs latest patch, too.


Georg
diff -p -r -U 3 -X excl.tmp lyx-1.4-clean/src/dociterator.C lyx-1.4-cvs/src/dociterator.C
--- lyx-1.4-clean/src/dociterator.C	2005-02-15 18:34:30.000000000 +0100
+++ lyx-1.4-cvs/src/dociterator.C	2005-02-23 22:01:57.000000000 +0100
@@ -381,9 +381,82 @@ void DocIterator::forwardPosNoDescend()
 
 void DocIterator::forwardPar()
 {
+#if 0
 	forwardPos();
 	while (!empty() && (!inTexted() || pos() != 0))
 		forwardPos();
+#else
+	do {
+		//this dog bites his tail
+		if (empty()) {
+			push_back(CursorSlice(*inset_));
+			continue;
+		}
+
+		CursorSlice & tip = top();
+		//lyxerr << "XXX\n" << *this << endl;
+
+		// this is used twice and shows up in the profiler!
+		pos_type const lastp = lastpos();
+
+		// move into an inset to the right if possible
+		InsetBase * n = 0;
+
+		if (tip.pos() != lastp) {
+			// this is impossible for pos() == size()
+			if (inMathed()) {
+				n = (tip.cell().begin() + tip.pos())->nucleus();
+			} else {
+				if (paragraph().isInset(tip.pos()))
+					n = paragraph().getInset(tip.pos());
+			}
+		}
+
+		if (n && n->isActive()) {
+			//lyxerr << "... descend" << endl;
+			push_back(CursorSlice(*n));
+			continue;
+		}
+
+		// otherwise move on one position if possible
+		if (tip.pos() < lastp) {
+			//lyxerr << "... next pos" << endl;
+			// The following two lines make all the speed difference:
+#ifdef SLOW_forwardPar
+			++tip.pos();
+#else
+			tip.pos() = lastp;
+#endif
+			continue;
+		}
+		//lyxerr << "... no next pos" << endl;
+
+		// otherwise move on one paragraph if possible
+		if (tip.pit() < lastpit()) {
+			//lyxerr << "... next par" << endl;
+			++tip.pit();
+			tip.pos() = 0;
+			continue;
+		}
+		//lyxerr << "... no next pit" << endl;
+
+		// otherwise try to move on one cell if possible
+		if (tip.idx() < lastidx()) {
+			//lyxerr << "... next idx" << endl;
+			++tip.idx();
+			tip.pit() = 0;
+			tip.pos() = 0;
+			continue;
+		}
+		//lyxerr << "... no next idx" << endl;
+
+		// otherwise leave inset and jump over inset as a whole
+		pop_back();
+		// 'top' is invalid now...
+		if (!empty())
+			++top().pos();
+	} while (!empty() && (!inTexted() || pos() != 0));
+#endif
 }
 
 

Reply via email to