]> git.lyx.org Git - lyx.git/blobdiff - src/TextMetrics.cpp
Revert 23154.
[lyx.git] / src / TextMetrics.cpp
index 69eef18615c3fec8c5a43a5ef50dcdbdc669dc18..a9ce0f04dc7321b9f232e0152e888f33f97b9eb9 100644 (file)
@@ -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,6 +48,8 @@
 #include "frontends/FontMetrics.h"
 #include "frontends/Painter.h"
 
+#include "support/debug.h"
+
 using namespace std;
 
 namespace lyx {
@@ -729,6 +730,15 @@ pit_type TextMetrics::rowBreakPoint(int width, pit_type const pit,
 
        pos_type const body_pos = par.beginOfBody();
 
+       // check for possible inline completion
+       DocIterator const & inlineCompletionPos = bv_->inlineCompletionPos();
+       pos_type inlineCompletionLPos = -1;
+       if (inlineCompletionPos.inTexted()
+           && inlineCompletionPos.text() == text_
+           && inlineCompletionPos.pit() == pit) {
+               // draw logically behind the previous character
+               inlineCompletionLPos = inlineCompletionPos.pos() - 1;
+       }
 
        // Now we iterate through until we reach the right margin
        // or the end of the par, then choose the possible break
@@ -747,6 +757,13 @@ pit_type TextMetrics::rowBreakPoint(int width, pit_type const pit,
        for ( ; i < end; ++i, ++fi) {
                int thiswidth = pm.singleWidth(i, *fi);
 
+               // add inline completion width
+               if (inlineCompletionLPos == i) {
+                       docstring const & completion = bv_->inlineCompletion();
+                       if (completion.length() > 0)
+                               thiswidth += theFontMetrics(*fi).width(completion);
+               }
+
                // add the auto-hfill from label end to the body
                if (body_pos && i == body_pos) {
                        FontMetrics const & fm = theFontMetrics(
@@ -829,6 +846,16 @@ int TextMetrics::rowWidth(int right_margin, pit_type const pit,
        int w = leftMargin(max_width_, pit, first);
        int label_end = labelEnd(pit);
 
+       // check for possible inline completion
+       DocIterator const & inlineCompletionPos = bv_->inlineCompletionPos();
+       pos_type inlineCompletionLPos = -1;
+       if (inlineCompletionPos.inTexted()
+           && inlineCompletionPos.text() == text_
+           && inlineCompletionPos.pit() == pit) {
+               // draw logically behind the previous character
+               inlineCompletionLPos = inlineCompletionPos.pos() - 1;
+       }
+
        pos_type const body_pos = par.beginOfBody();
        pos_type i = first;
 
@@ -844,6 +871,13 @@ int TextMetrics::rowWidth(int right_margin, pit_type const pit,
                                w = max(w, label_end);
                        }
                        w += pm.singleWidth(i, *fi);
+
+                       // add inline completion width
+                       if (inlineCompletionLPos == i) {
+                               docstring const & completion = bv_->inlineCompletion();
+                               if (completion.length() > 0)
+                                       w += theFontMetrics(*fi).width(completion);
+                       }
                }
        }
 
@@ -861,7 +895,7 @@ int TextMetrics::rowWidth(int right_margin, pit_type const pit,
 
 
 Dimension TextMetrics::rowHeight(pit_type const pit, pos_type const first,
-               pos_type const end) const
+               pos_type const end, bool topBottomSpace) const
 {
        Paragraph const & par = text_->getPar(pit);
        // get the maximum ascent and the maximum descent
@@ -932,7 +966,7 @@ Dimension TextMetrics::rowHeight(pit_type const pit, pos_type const first,
        ParagraphList const & pars = text_->paragraphs();
 
        // is it a top line?
-       if (first == 0) {
+       if (first == 0 && topBottomSpace) {
                BufferParams const & bufparams = buffer.params();
                // some parskips VERY EASY IMPLEMENTATION
                if (bufparams.paragraph_separation
@@ -964,7 +998,7 @@ Dimension TextMetrics::rowHeight(pit_type const pit, pos_type const first,
                     || layout->labeltype == LABEL_BIBLIO
                     || layout->labeltype == LABEL_CENTERED_TOP_ENVIRONMENT)
                    && isFirstInSequence(pit, pars)
-                   && !par.getLabelstring().empty())
+                   && !par.labelString().empty())
                {
                        labeladdon = int(
                                  labelfont_metrics.maxHeight()
@@ -1003,7 +1037,7 @@ Dimension TextMetrics::rowHeight(pit_type const pit, pos_type const first,
        }
 
        // is it a bottom line?
-       if (end >= par.size()) {
+       if (end >= par.size() && topBottomSpace) {
                // add the layout spaces, for example before and after
                // a section, or between the items of a itemize or enumerate
                // environment
@@ -1038,7 +1072,7 @@ Dimension TextMetrics::rowHeight(pit_type const pit, pos_type const first,
        // following code in another method specially tailored for the
        // main Text. The following test is thus bogus.
        // Top and bottom margin of the document (only at top-level)
-       if (main_text_) {
+       if (main_text_ && topBottomSpace) {
                if (pit == 0 && first == 0)
                        maxasc += 20;
                if (pit + 1 == pit_type(pars.size()) &&
@@ -1492,6 +1526,18 @@ int TextMetrics::cursorX(CursorSlice const & sl,
            (body_pos > end || !par.isLineSeparator(body_pos - 1)))
                body_pos = 0;
 
+       // check for possible inline completion in this row
+       DocIterator const & inlineCompletionPos = bv_->inlineCompletionPos();
+       pos_type inlineCompletionVPos = -1;
+       if (inlineCompletionPos.inTexted()
+           && inlineCompletionPos.text() == text_
+           && inlineCompletionPos.pit() == pit
+           && inlineCompletionPos.pos() >= row_pos
+           && inlineCompletionPos.pos() <= end) {
+               // draw logically behind the previous character
+               inlineCompletionVPos = bidi.log2vis(inlineCompletionPos.pos() - 1);
+       }
+
        // Use font span to speed things up, see below
        FontSpan font_span;
        Font font;
@@ -1501,6 +1547,15 @@ int TextMetrics::cursorX(CursorSlice const & sl,
        if (end > 0 && end < par.size() && par.isSeparator(end - 1))
                skipped_sep_vpos = bidi.log2vis(end - 1);
        
+       // Inline completion RTL special case row_pos == cursor_pos:
+       // "__|b" => cursor_pos is right of __
+       if (row_pos == inlineCompletionVPos && row_pos == cursor_vpos) {
+               font = getDisplayFont(pit, row_pos + 1);
+               docstring const & completion = bv_->inlineCompletion();
+               if (font.isRightToLeft() && completion.length() > 0)
+                       x += theFontMetrics(font.fontInfo()).width(completion);
+       }
+       
        for (pos_type vpos = row_pos; vpos < cursor_vpos; ++vpos) {
                // Skip the separator which is at the logical end of the row
                if (vpos == skipped_sep_vpos)
@@ -1522,6 +1577,26 @@ int TextMetrics::cursorX(CursorSlice const & sl,
 
                x += pm.singleWidth(pos, font);
 
+               // Inline completion RTL case:
+               // "a__|b", __ of b => non-boundary a-pos is right of __
+               if (vpos + 1 == inlineCompletionVPos 
+                   && (vpos + 1 < cursor_vpos || !boundary_correction)) {
+                       font = getDisplayFont(pit, vpos + 1);
+                       docstring const & completion = bv_->inlineCompletion();
+                       if (font.isRightToLeft() && completion.length() > 0)
+                               x += theFontMetrics(font.fontInfo()).width(completion);
+               }
+               
+               //  Inline completion LTR case:
+               // "b|__a", __ of b => non-boundary a-pos is in front of __
+               if (vpos == inlineCompletionVPos
+                   && (vpos + 1 < cursor_vpos || boundary_correction)) {
+                       font = getDisplayFont(pit, vpos);
+                       docstring const & completion = bv_->inlineCompletion();
+                       if (!font.isRightToLeft() && completion.length() > 0)
+                               x += theFontMetrics(font.fontInfo()).width(completion);
+               }
+               
                if (par.isSeparator(pos) && pos >= body_pos)
                        x += row.separator;
        }
@@ -1709,6 +1784,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();
@@ -1734,9 +1810,9 @@ int TextMetrics::leftMargin(int max_width,
                        l_margin += theFontMetrics(buffer.params().getFont()).signedWidth(
                                layout->leftmargin);
                }
-               if (!par.getLabelstring().empty()) {
+               if (!par.labelString().empty()) {
                        l_margin += labelfont_metrics.signedWidth(layout->labelindent);
-                       l_margin += labelfont_metrics.width(par.getLabelstring());
+                       l_margin += labelfont_metrics.width(par.labelString());
                        l_margin += labelfont_metrics.width(layout->labelsep);
                }
                break;
@@ -1780,7 +1856,7 @@ int TextMetrics::leftMargin(int max_width,
                           LABEL_CENTERED_TOP_ENVIRONMENT) {
                        l_margin += labelfont_metrics.signedWidth(layout->labelindent);
                        l_margin += labelfont_metrics.width(layout->labelsep);
-                       l_margin += labelfont_metrics.width(par.getLabelstring());
+                       l_margin += labelfont_metrics.width(par.labelString());
                }
                break;
 
@@ -1830,7 +1906,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))
        {