X-Git-Url: https://git.lyx.org/gitweb/?a=blobdiff_plain;f=src%2FTextMetrics.cpp;h=938223050961fbe55778f9d7719849ae62ba137f;hb=63ead2010d7b2d51861e650133662c3518cd0d09;hp=6c3197cfbc72bbd39b16886112679d29b8497362;hpb=c981018111b0fc9d15f3c23d9cbfa8750e214a80;p=lyx.git diff --git a/src/TextMetrics.cpp b/src/TextMetrics.cpp index 6c3197cfbc..9382230509 100644 --- a/src/TextMetrics.cpp +++ b/src/TextMetrics.cpp @@ -158,6 +158,7 @@ pair TextMetrics::first() const pair TextMetrics::last() const { + LASSERT(!par_metrics_.empty(), /**/); ParMetricsCache::const_reverse_iterator it = par_metrics_.rbegin(); return make_pair(it->first, &it->second); } @@ -313,6 +314,9 @@ bool TextMetrics::isRTLBoundary(pit_type pit, pos_type pos) const } +// isRTLBoundary returns false on a real end-of-line boundary, +// because otherwise the two boundary types get mixed up. +// This is the whole purpose of this being in TextMetrics. bool TextMetrics::isRTLBoundary(pit_type pit, pos_type pos, Font const & font) const { @@ -371,6 +375,30 @@ bool TextMetrics::redoParagraph(pit_type const pit) main_text_ = (text_ == &buffer.text()); bool changed = false; + // Check whether there are InsetBibItems that need fixing + // FIXME: This check ought to be done somewhere else. It is the reason + // why text_ is not const. But then, where else to do it? + // Well, how can you end up with either (a) a biblio environment that + // has no InsetBibitem or (b) a biblio environment with more than one + // InsetBibitem? I think the answer is: when paragraphs are merged; + // when layout is set; when material is pasted. + if (par.brokenBiblio()) { + Cursor & cur = const_cast(bv_->cursor()); + // In some cases, we do not know how to record undo + if (&cur.inset() == &text_->inset()) + cur.recordUndo(ATOMIC_UNDO, pit, pit); + + int const moveCursor = par.fixBiblio(buffer); + + // Is it necessary to update the cursor? + if (&cur.inset() == &text_->inset() && cur.pit() == pit) { + if (moveCursor > 0) + cur.posForward(); + else if (moveCursor < 0 && cur.pos() >= -moveCursor) + cur.posBackward(); + } + } + // Optimisation: this is used in the next two loops // so better to calculate that once here. int const right_margin = rightMargin(pm); @@ -393,12 +421,11 @@ bool TextMetrics::redoParagraph(pit_type const pit) } // redo insets - // FIXME: We should always use getFont(), see documentation of - // noFontChange() in Inset.h. Font const bufferfont = buffer.params().getFont(); InsetList::const_iterator ii = par.insetList().begin(); InsetList::const_iterator iend = par.insetList().end(); for (; ii != iend; ++ii) { + // FIXME Doesn't this HAVE to be non-empty? // position already initialized? if (!parPos.empty()) { parPos.pos() = ii->pos; @@ -415,8 +442,8 @@ bool TextMetrics::redoParagraph(pit_type const pit) Dimension dim; int const w = max_width_ - leftMargin(max_width_, pit, ii->pos) - right_margin; - Font const & font = ii->inset->noFontChange() ? - bufferfont : displayFont(pit, ii->pos); + Font const & font = ii->inset->inheritFont() ? + displayFont(pit, ii->pos) : bufferfont; MacroContext mc(&buffer, parPos); MetricsInfo mi(bv_, font.fontInfo(), w, mc); ii->inset->metrics(mi, dim); @@ -580,6 +607,11 @@ void TextMetrics::computeRowMetrics(pit_type const pit, } } + // Has the user requested we not justify stuff? + if (!bv_->buffer().params().justification + && align == LYX_ALIGN_BLOCK) + align = LYX_ALIGN_LEFT; + switch (align) { case LYX_ALIGN_BLOCK: { int const ns = numberOfSeparators(par, row); @@ -684,6 +716,8 @@ int TextMetrics::labelFill(pit_type const pit, Row const & row) const } +#if 0 +// Not used, see TextMetrics::rowBreakPoint. // this needs special handling - only newlines count as a break point static pos_type addressBreakPoint(pos_type i, Paragraph const & par) { @@ -695,6 +729,7 @@ static pos_type addressBreakPoint(pos_type i, Paragraph const & par) return end; } +#endif int TextMetrics::labelEnd(pit_type const pit) const @@ -775,8 +810,13 @@ pos_type TextMetrics::rowBreakPoint(int width, pit_type const pit, Layout const & layout = par.layout(); +#if 0 + //FIXME: As long as leftMargin() is not correctly implemented for + // MARGIN_RIGHT_ADDRESS_BOX, we should also not do this here. + // Otherwise, long rows will be painted off the screen. if (layout.margintype == MARGIN_RIGHT_ADDRESS_BOX) return addressBreakPoint(pos, par); +#endif pos_type const body_pos = par.beginOfBody(); @@ -1049,16 +1089,14 @@ Dimension TextMetrics::rowHeight(pit_type const pit, pos_type const first, if (first == 0 && topBottomSpace) { BufferParams const & bufparams = buffer.params(); // some parskips VERY EASY IMPLEMENTATION - if (bufparams.paragraph_separation - == BufferParams::ParagraphSkipSeparation - && inset.lyxCode() != ERT_CODE - && inset.lyxCode() != LISTINGS_CODE - && pit > 0 - && ((layout.isParagraph() && par.getDepth() == 0) - || (pars[pit - 1].layout().isParagraph() - && pars[pit - 1].getDepth() == 0))) - { - maxasc += bufparams.getDefSkip().inPixels(*bv_); + if (bufparams.paragraph_separation == BufferParams::ParagraphSkipSeparation + && !inset.getLayout().parbreakIsNewline() + && !par.layout().parbreak_is_newline + && pit > 0 + && ((layout.isParagraph() && par.getDepth() == 0) + || (pars[pit - 1].layout().isParagraph() + && pars[pit - 1].getDepth() == 0))) { + maxasc += bufparams.getDefSkip().inPixels(*bv_); } if (par.params().startOfAppendix()) @@ -1210,12 +1248,13 @@ pos_type TextMetrics::getColumnNearX(pit_type const pit, // If lastrow is false, we don't need to compute // the value of rtl. - bool const rtl = lastrow ? text_->isRTL(par) : false; + bool const rtl_on_lastrow = lastrow ? text_->isRTL(par) : false; // if the first character is a separator, and we are in RTL // text, this character will not be painted on screen - // and thus we should not count it and skip to the next. - if (rtl && par.isSeparator(bidi.vis2log(vc))) + // and thus we should not count it and skip to the next. Only + // in freespacing paragraphs, this first character is painted. + if (!par.isFreeSpacing() && par.isSeparator(bidi.vis2log(vc))) ++vc; while (vc < end && tmpx <= x) { @@ -1245,8 +1284,8 @@ pos_type TextMetrics::getColumnNearX(pit_type const pit, boundary = false; if (lastrow && - ((rtl && left_side && vc == row.pos() && x < tmpx - 5) || - (!rtl && !left_side && vc == end && x > tmpx + 5))) { + ((rtl_on_lastrow && left_side && vc == row.pos() && x < tmpx - 5) || + (!rtl_on_lastrow && !left_side && vc == end && x > tmpx + 5))) { if (!par.isNewline(end - 1)) c = end; } else if (vc == row.pos()) { @@ -1359,7 +1398,8 @@ pit_type TextMetrics::getPitNearY(int y) int yy = -1; ParMetricsCache::const_iterator it = par_metrics_.begin(); ParMetricsCache::const_iterator et = par_metrics_.end(); - ParMetricsCache::const_iterator last = et; last--; + ParMetricsCache::const_iterator last = et; + --last; ParagraphMetrics const & pm = it->second; @@ -1495,7 +1535,7 @@ Inset * TextMetrics::editXY(Cursor & cur, int x, int y, // This should be just before or just behind the // cursor position set above. LASSERT(inset == inset_before - || inset == pars[pit].getInset(pos), /**/); + || inset == pars[pit].getInset(pos), return 0); // Make sure the cursor points to the position before // this inset. @@ -1953,16 +1993,18 @@ int TextMetrics::leftMargin(int max_width, case MARGIN_RIGHT_ADDRESS_BOX: { #if 0 - // ok, a terrible hack. The left margin depends on the widest - // row in this paragraph. - RowList::iterator rit = par.rows().begin(); - RowList::iterator end = par.rows().end(); - // FIXME: This is wrong. + // The left margin depends on the widest row in this paragraph. + // This code is wrong because it depends on the rows, but at the + // same time this function is used in redoParagraph to construct + // the rows. + ParagraphMetrics const & pm = par_metrics_[pit]; + RowList::const_iterator rit = pm.rows().begin(); + RowList::const_iterator end = pm.rows().end(); int minfill = max_width; for ( ; rit != end; ++rit) if (rit->fill() < minfill) minfill = rit->fill(); - l_margin += theFontMetrics(params.getFont()).signedWidth(layout.leftmargin); + l_margin += theFontMetrics(buffer.params().getFont()).signedWidth(layout.leftmargin); l_margin += minfill; #endif // also wrong, but much shorter. @@ -1989,7 +2031,7 @@ int TextMetrics::leftMargin(int max_width, || (layout.labeltype == LABEL_STATIC && layout.latextype == LATEX_ENVIRONMENT && !text_->isFirstInSequence(pit))) - && align == LYX_ALIGN_BLOCK + && (align == LYX_ALIGN_BLOCK || align == LYX_ALIGN_LEFT) && !par.params().noindent() // in some insets, paragraphs are never indented && !text_->inset().neverIndent()