X-Git-Url: https://git.lyx.org/gitweb/?a=blobdiff_plain;f=src%2FTextMetrics.cpp;h=e28d8fc9785873de5b8d8733a2163d117b502870;hb=1ab314f8e6e145dc73d0a26b7e82a280b497ea3c;hp=4fa2857ad6156baf4f3cba0a960b179bf6ed5f36;hpb=2356bc13eef1c51a7ca55ef60e71f3333f053f4c;p=lyx.git diff --git a/src/TextMetrics.cpp b/src/TextMetrics.cpp index 4fa2857ad6..e28d8fc978 100644 --- a/src/TextMetrics.cpp +++ b/src/TextMetrics.cpp @@ -27,7 +27,6 @@ #include "CoordCache.h" #include "Cursor.h" #include "CutAndPaste.h" -#include "support/debug.h" #include "FontIterator.h" #include "FuncRequest.h" #include "InsetList.h" @@ -49,10 +48,9 @@ #include "frontends/FontMetrics.h" #include "frontends/Painter.h" -using std::make_pair; -using std::max; -using std::min; -using std::pair; +#include "support/debug.h" + +using namespace std; namespace lyx { @@ -223,13 +221,13 @@ bool TextMetrics::metrics(MetricsInfo & mi, Dimension & dim, int min_width) int TextMetrics::rightMargin(ParagraphMetrics const & pm) const { - return main_text_? pm.rightMargin(bv_->buffer()) : 0; + return main_text_? pm.rightMargin(*bv_) : 0; } int TextMetrics::rightMargin(pit_type const pit) const { - return main_text_? par_metrics_[pit].rightMargin(bv_->buffer()) : 0; + return main_text_? par_metrics_[pit].rightMargin(*bv_) : 0; } @@ -378,35 +376,37 @@ bool TextMetrics::redoParagraph(pit_type const pit) // so better to calculate that once here. int const right_margin = rightMargin(pm); + // iterator pointing to paragraph to resolve macros + DocIterator parPos = text_->macrocontextPosition(); + if (!parPos.empty()) + parPos.pit() = pit; + else { + LYXERR(Debug::INFO, "MacroContext not initialised!" + << " Going through the buffer again and hope" + << " the context is better then."); + updateLabels(bv_->buffer()); + parPos = text_->macrocontextPosition(); + BOOST_ASSERT(!parPos.empty()); + parPos.pit() = pit; + } + // redo insets // FIXME: We should always use getFont(), see documentation of // noFontChange() in Inset.h. Font const bufferfont = buffer.params().getFont(); - MacroContext mc(buffer, par); InsetList::const_iterator ii = par.insetList().begin(); InsetList::const_iterator iend = par.insetList().end(); for (; ii != iend; ++ii) { - // the macro must come here, _before_ the metric call, because - // the macro should see itself to detect recursions. To find out - // whether the macro definition is a redefinition it will look - // at the MacroData::redefinition_. So it doesn't get confused - // by the already existing macro definition of itself in the - // macro context. - if (ii->inset->lyxCode() == MATHMACRO_CODE) { - // get macro data - MathMacroTemplate const & macroTemplate - = static_cast(*ii->inset); - - // valid? - if (macroTemplate.validMacro()) { - MacroData macro = macroTemplate.asMacroData(); - - // redefinition? - macro.setRedefinition(mc.has(macroTemplate.name())); - - // register macro (possibly overwrite the previous one of this paragraph) - mc.insert(macroTemplate.name(), macro); - } + // position already initialized? + if (!parPos.empty()) { + parPos.pos() = ii->pos; + + // A macro template would normally not be visible + // by itself. But the tex macro semantics allow + // recursion, so we artifically take the context + // after the macro template to simulate this. + if (ii->inset->lyxCode() == MATHMACRO_CODE) + parPos.pos()++; } // do the metric calculation @@ -415,6 +415,7 @@ bool TextMetrics::redoParagraph(pit_type const pit) - right_margin; Font const & font = ii->inset->noFontChange() ? bufferfont : getDisplayFont(pit, ii->pos); + MacroContext mc(buffer, parPos); MetricsInfo mi(bv_, font.fontInfo(), w, mc); ii->inset->metrics(mi, dim); Dimension const old_dim = pm.insetDimension(ii->inset); @@ -476,7 +477,7 @@ bool TextMetrics::redoParagraph(pit_type const pit) first = end; ++row_index; - pm.dim().wid = std::max(pm.dim().wid, dim.wid); + pm.dim().wid = max(pm.dim().wid, dim.wid); pm.dim().des += dim.height(); } while (first < par.size()); @@ -570,11 +571,8 @@ void TextMetrics::computeRowMetrics(pit_type const pit, align = par.params().align(); // Display-style insets should always be on a centred row - // The test on par.size() is to catch zero-size pars, which - // would trigger the assert in Paragraph::getInset(). - //inset = par.size() ? par.getInset(row.pos()) : 0; - if (row.pos() < par.size() && par.isInset(row.pos())) { - switch(par.getInset(row.pos())->display()) { + if (Inset const * inset = par.getInset(row.pos())) { + switch (inset->display()) { case Inset::AlignLeft: align = LYX_ALIGN_BLOCK; break; @@ -758,7 +756,7 @@ pit_type TextMetrics::rowBreakPoint(int width, pit_type const pit, if (par.isLineSeparator(i - 1)) add -= singleWidth(pit, i - 1); - add = std::max(add, label_end - x); + add = max(add, label_end - x); thiswidth += add; } @@ -783,20 +781,22 @@ pit_type TextMetrics::rowBreakPoint(int width, pit_type const pit, point = i + 1; break; } + Inset const * inset = 0; // Break before... if (i + 1 < end) { - if (par.isInset(i + 1) && par.getInset(i + 1)->display()) { + if ((inset = par.getInset(i + 1)) && inset->display()) { point = i + 1; break; } // ...and after. - if (par.isInset(i) && par.getInset(i)->display()) { + if ((inset = par.getInset(i)) && inset->display()) { point = i + 1; break; } } - if (!par.isInset(i) || par.getInset(i)->isChar()) { + inset = par.getInset(i); + if (!inset || inset->isChar()) { // some insets are line separators too if (par.isLineSeparator(i)) { // register breakpoint: @@ -1125,9 +1125,10 @@ pos_type TextMetrics::getColumnNearX(pit_type const pit, bool const rtl = lastrow ? text_->isRTL(buffer, par) : false; if (lastrow && ((rtl && left_side && vc == row.pos() && x < tmpx - 5) || - (!rtl && !left_side && vc == end && x > tmpx + 5))) - c = end; - else if (vc == row.pos()) { + (!rtl && !left_side && vc == end && x > tmpx + 5))) { + if (!par.isNewline(end - 1)) + c = end; + } else if (vc == row.pos()) { c = bidi.vis2log(vc); if (bidi.level(c) % 2 == 1) ++c; @@ -1208,7 +1209,7 @@ void TextMetrics::newParMetricsDown() // do it and update its position. redoParagraph(pit); par_metrics_[pit].setPosition(last.second.position() - + last.second.descent()); + + last.second.descent() + par_metrics_[pit].ascent()); } @@ -1222,7 +1223,7 @@ void TextMetrics::newParMetricsUp() // do it and update its position. redoParagraph(pit); par_metrics_[pit].setPosition(first.second.position() - - first.second.ascent()); + - first.second.ascent() - par_metrics_[pit].descent()); } // y is screen coordinate @@ -1540,7 +1541,7 @@ int TextMetrics::cursorX(CursorSlice const & sl, int TextMetrics::cursorY(CursorSlice const & sl, bool boundary) const { - //lyxerr << "TextMetrics::cursorY: boundary: " << boundary << std::endl; + //lyxerr << "TextMetrics::cursorY: boundary: " << boundary << endl; ParagraphMetrics const & pm = par_metrics_[sl.pit()]; if (pm.rows().empty()) return 0; @@ -1650,7 +1651,7 @@ void TextMetrics::deleteLineForward(Cursor & cur) text_->deleteWordForward(cur); else cap::cutSelection(cur, true, false); - checkBufferStructure(cur.buffer(), cur); + cur.checkBufferStructure(); } } @@ -1697,7 +1698,7 @@ int TextMetrics::leftMargin(int max_width, int l_margin = 0; if (text_->isMainText(buffer)) - l_margin += changebarMargin(); + l_margin += bv_->leftMargin(); l_margin += theFontMetrics(buffer.params().getFont()).signedWidth( tclass.leftmargin()); @@ -1709,6 +1710,7 @@ int TextMetrics::leftMargin(int max_width, if (pars[newpar].layout()->isEnvironment()) { l_margin = leftMargin(max_width, newpar); } + //FIXME Should this check for emptyLayout() as well? if (par.layout() == tclass.defaultLayout()) { if (pars[newpar].params().noindent()) parindent.erase(); @@ -1820,7 +1822,7 @@ int TextMetrics::leftMargin(int max_width, || layout->labeltype == LABEL_TOP_ENVIRONMENT || layout->labeltype == LABEL_CENTERED_TOP_ENVIRONMENT || (layout->labeltype == LABEL_STATIC - && layout->latextype == LATEX_ENVIRONMENT + && layout->latextype == LATEX_ENVIRONMENT && !isFirstInSequence(pit, pars))) && align == LYX_ALIGN_BLOCK && !par.params().noindent() @@ -1830,7 +1832,7 @@ int TextMetrics::leftMargin(int max_width, && !(!par.empty() && par.isInset(pos) && par.getInset(pos)->display()) - && (par.layout() != tclass.defaultLayout() + && (par.layout() != tclass.defaultLayout() //should this check emptyLayout()? || buffer.params().paragraph_separation == BufferParams::PARSEP_INDENT)) { @@ -1935,7 +1937,7 @@ void TextMetrics::drawParagraph(PainterInfo & pi, pit_type pit, int x, int y) co // 12 lines lower): if (lyxerr.debugging(Debug::PAINTING) && inside && (row_selection || pi.full_repaint || row_has_changed)) { - std::string const foreword = text_->isMainText(bv_->buffer()) ? + string const foreword = text_->isMainText(bv_->buffer()) ? "main text redraw " : "inset text redraw: "; LYXERR(Debug::PAINTING, foreword << "pit=" << pit << " row=" << i << " row_selection=" << row_selection