+ ++to.pos();
+ }
+}
+
+
+void LyXText::write(Buffer const & buf, std::ostream & os) const
+{
+ ParagraphList::const_iterator pit = paragraphs().begin();
+ ParagraphList::const_iterator end = paragraphs().end();
+ Paragraph::depth_type dth = 0;
+ for (; pit != end; ++pit)
+ pit->write(buf, os, buf.params(), dth);
+}
+
+
+bool LyXText::read(Buffer const & buf, LyXLex & lex)
+{
+ static Change current_change;
+
+ bool the_end_read = false;
+ ParagraphList::iterator pit = paragraphs().begin();
+ Paragraph::depth_type depth = 0;
+
+ while (lex.isOK()) {
+ lex.nextToken();
+ string token = lex.getString();
+
+ if (token.empty())
+ continue;
+
+ if (in_inset_) {
+
+ if (token == "\\end_inset") {
+ the_end_read = true;
+ break;
+ }
+
+ if (token == "\\end_document") {
+ lex.printError("\\end_document read in inset! Error in document!");
+ return false;
+ }
+
+ } else {
+
+ if (token == "\\end_document") {
+ the_end_read = true;
+ continue;
+ }
+
+ }
+
+ // FIXME: ugly.
+ int unknown = 0;
+
+ if (token == "\\begin_layout") {
+ lex.pushToken(token);
+
+ Paragraph par;
+ par.params().depth(depth);
+ if (buf.params().tracking_changes)
+ par.trackChanges();
+ LyXFont f(LyXFont::ALL_INHERIT, buf.params().language);
+ par.setFont(0, f);
+
+ // insert after
+ if (pit != paragraphs().end())
+ ++pit;
+
+ pit = paragraphs().insert(pit, par);
+
+ // FIXME: goddamn InsetTabular makes us pass a Buffer
+ // not BufferParams
+ ::readParagraph(buf, *pit, lex);
+
+ } else if (token == "\\begin_deeper") {
+ ++depth;
+ } else if (token == "\\end_deeper") {
+ if (!depth) {
+ lex.printError("\\end_deeper: " "depth is already null");
+ } else {
+ --depth;
+ }
+ } else {
+ ++unknown;
+ }
+
+ }
+ return the_end_read;
+}
+
+
+int LyXText::ascent() const
+{
+ return firstRow()->ascent_of_text();
+}
+
+
+int LyXText::descent() const
+{
+ return height - firstRow()->ascent_of_text();
+}
+
+
+int LyXText::cursorX(CursorSlice const & cur) const
+{
+ ParagraphList::iterator pit = getPar(cur);
+ if (pit->rows.empty())
+ return xo_;
+ Row const & row = *pit->getRow(cur.pos());
+ pos_type pos = cur.pos();
+ pos_type cursor_vpos = 0;
+ double x = row.x();
+ double fill_separator = row.fill_separator();
+ double fill_hfill = row.fill_hfill();
+ double fill_label_hfill = row.fill_label_hfill();
+ pos_type const row_pos = row.pos();
+ pos_type const end = row.endpos();
+
+ if (end <= row_pos)
+ cursor_vpos = row_pos;
+ else if (pos >= end)
+ cursor_vpos = isRTL(*pit) ? row_pos : end;
+ else if (pos > row_pos && pos >= end)
+ // Place cursor after char at (logical) position pos - 1
+ cursor_vpos = (bidi.level(pos - 1) % 2 == 0)
+ ? bidi.log2vis(pos - 1) + 1 : bidi.log2vis(pos - 1);
+ else
+ // Place cursor before char at (logical) position pos
+ cursor_vpos = (bidi.level(pos) % 2 == 0)
+ ? bidi.log2vis(pos) : bidi.log2vis(pos) + 1;
+
+ pos_type body_pos = pit->beginOfBody();
+ if (body_pos > 0 &&
+ (body_pos > end || !pit->isLineSeparator(body_pos - 1)))
+ body_pos = 0;
+
+ for (pos_type vpos = row_pos; vpos < cursor_vpos; ++vpos) {
+ pos_type pos = bidi.vis2log(vpos);
+ if (body_pos > 0 && pos == body_pos - 1) {
+ x += fill_label_hfill
+ + font_metrics::width(pit->layout()->labelsep,
+ getLabelFont(pit));
+ if (pit->isLineSeparator(body_pos - 1))
+ x -= singleWidth(pit, body_pos - 1);
+ }
+
+ if (hfillExpansion(*pit, row, pos)) {
+ x += singleWidth(pit, pos);
+ if (pos >= body_pos)
+ x += fill_hfill;
+ else
+ x += fill_label_hfill;
+ } else if (pit->isSeparator(pos)) {
+ x += singleWidth(pit, pos);
+ if (pos >= body_pos)
+ x += fill_separator;
+ } else
+ x += singleWidth(pit, pos);
+ }
+ return xo_ + int(x);
+}
+
+
+int LyXText::cursorY(CursorSlice const & cur) const
+{
+ Paragraph & par = *getPar(cur);
+ Row & row = *par.getRow(cur.pos());
+ return yo_ + par.y + row.y_offset() + row.baseline();
+}
+
+
+CursorSlice & LyXText::cursor()
+{
+ //lyxerr << "# accessing slice " << findText(this) << endl;
+ if (this != bv()->cursor().text()) {
+ lyxerr << "cursor: " << bv()->cursor()
+ << "\ntext: " << bv()->cursor().text()
+ << "\nthis: " << this << endl;
+ BOOST_ASSERT(false);