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 }