]> git.lyx.org Git - features.git/commitdiff
hfilltextclean.diff
authorLars Gullik Bjønnes <larsbj@gullik.org>
Tue, 4 Dec 2001 16:32:15 +0000 (16:32 +0000)
committerLars Gullik Bjønnes <larsbj@gullik.org>
Tue, 4 Dec 2001 16:32:15 +0000 (16:32 +0000)
git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/trunk@3144 a592a061-630c-0410-9148-cb99ea01b6c8

src/ChangeLog
src/Makefile.am
src/lyxlength.C
src/lyxtext.h
src/text.C

index ca8ed313da07882bc6656fc19a28026d0fe523d6..617d99e32f6a937ce5856c5450360fef97ccdc65 100644 (file)
@@ -1,3 +1,8 @@
+2001-12-04  John Levon  <moz@compsoc.man.ac.uk>
+
+       * lyxtext.h:
+       * text.C: fix hfill at end of line, clean up
+
 2001-12-04  Juergen Vigna  <jug@sad.it>
 
        * undo_funcs.C (textHandleUndo): added a call to inset->update() so
index 6662a8a5bf1b2050b7ec7c78e1be8c42e0ae3013..09f138cba9441301081cc7190bbad7098a56128f 100644 (file)
@@ -156,7 +156,7 @@ lyx_SOURCES = \
        lyxgluelength.C \
        lyxgluelength.h \
        lyxlength.C \
-       lexlength.h \
+       lyxlength.h \
        lyxlex.C \
        lyxlex.h \
        lyxlex_pimpl.C \
index 35bfb87ad5a2cfdd429d95db265f3c7c7f64299f..2c52c7dbb8dd04937b923fcd12c52d7ec3efb251 100644 (file)
@@ -80,15 +80,15 @@ string const LyXLength::asLatexString() const
        case PW:
        case PE:
            buffer << abs(static_cast<int>(val_/100)) << "."
-                               << abs(static_cast<int>(val_)%100) << "\\columnwidth";
+                  << abs(static_cast<int>(val_)%100) << "\\columnwidth";
            break;
        case PP:
            buffer << abs(static_cast<int>(val_/100)) << "."
-                               << abs(static_cast<int>(val_)%100) << "\\pagewidth";
+                  << abs(static_cast<int>(val_)%100) << "\\pagewidth";
            break;
        case PL:
            buffer << abs(static_cast<int>(val_/100)) << "."
-                               << abs(static_cast<int>(val_)%100) << "\\linewidth";
+                  << abs(static_cast<int>(val_)%100) << "\\linewidth";
            break;
        default:
            buffer << val_ << unit_name[unit_]; // setw?
index fdc849bfa78f563da504cacc950568111af27076..d4ed74020c5ed4d5b04d7d6620822ddcdbb0542d 100644 (file)
@@ -560,9 +560,9 @@ private:
                Painter * pain; 
                // has the background been cleared
                bool cleared;
-               /// x offset
+               /// x offset (e.g. for insets)
                int xo;
-               /// y offset 
+               /// y offset (e.g. for insets)
                int yo;
                /// FIXME
                float x;
@@ -627,9 +627,23 @@ private:
        ///
        int singleWidth(BufferView *, Paragraph * par,
                lyx::pos_type pos, char c) const;
-       ///
-       void draw(BufferView *, Row const * row,
-                 lyx::pos_type & pos, int offset, float & x, bool cleared);
+
+       /// draw normal chars
+       void drawChars(DrawRowParams & p, lyx::pos_type & vpos,
+               bool hebrew, bool arabic);
+       /// draw from arabic composed char
+       void drawArabicComposeChar(DrawRowParams & p, lyx::pos_type & vpos);
+       /// draw from hebrew composed char
+       void drawHebrewComposeChar(DrawRowParams & p, lyx::pos_type & vpos);
+       /// draw a mark for foreign language, starting from orig_x
+       void drawForeignMark(DrawRowParams & p, float const orig_x, LyXFont const & orig_font);
+       /// draw an inset 
+       void drawInset(DrawRowParams & p, lyx::pos_type const pos);
+       /// draw new line marker
+       void drawNewline(DrawRowParams & p, lyx::pos_type const pos);
+       /// draw text
+       void draw(DrawRowParams & p, lyx::pos_type & vpos);
 
        /// get the next breakpoint in a given paragraph
        lyx::pos_type nextBreakPoint(BufferView *, Row const * row, int width) const;
index 91cd22327981214368d304413a322e9d8bcd1c99..33aa39f811651ecf1aff3cedabb092d6e0c8ae6d 100644 (file)
@@ -410,212 +410,243 @@ bool LyXText::isBoundary(Buffer const * buf, Paragraph * par,
        return rtl != rtl2;
 }
 
+void LyXText::drawNewline(DrawRowParams & p, pos_type const pos)
+{
+       // Draw end-of-line marker
+       LyXFont const font = getFont(p.bv->buffer(), p.row->par(), pos);
+       int const wid = lyxfont::width('n', font);
+       int const asc = lyxfont::maxAscent(font);
+       int const y = p.yo + p.row->baseline();
+       int xp[3];
+       int yp[3];
+               
+       yp[0] = int(y - 0.875 * asc * 0.75);
+       yp[1] = int(y - 0.500 * asc * 0.75);
+       yp[2] = int(y - 0.125 * asc * 0.75);
+       if (bidi_level(pos) % 2 == 0) {
+               xp[0] = int(p.x + wid * 0.375);
+               xp[1] = int(p.x);
+               xp[2] = int(p.x + wid * 0.375);
+       } else { 
+               xp[0] = int(p.x + wid * 0.625);
+               xp[1] = int(p.x + wid);
+               xp[2] = int(p.x + wid * 0.625);
+       }
+       p.pain->lines(xp, yp, 3, LColor::eolmarker);
+       yp[0] = int(y - 0.500 * asc * 0.75);
+       yp[1] = int(y - 0.500 * asc * 0.75);
+       yp[2] = int(y - asc * 0.75);
+       if (bidi_level(pos) % 2 == 0) {
+               xp[0] = int(p.x);
+               xp[1] = int(p.x + wid);
+               xp[2] = int(p.x + wid);
+       } else {
+               xp[0] = int(p.x + wid);
+               xp[1] = int(p.x);
+               xp[2] = int(p.x);
+       }
+       p.pain->lines(xp, yp, 3, LColor::eolmarker);
+
+       p.x += wid;
+}
 
-void LyXText::draw(BufferView * bview, Row const * row,
-                   pos_type & vpos, int offset, float & x, bool cleared)
+void LyXText::drawInset(DrawRowParams & p, pos_type const pos)
 {
-       Painter & pain = bview->painter();
-       
-       pos_type pos = vis2log(vpos);
-       char c = row->par()->getChar(pos);
-       float tmpx = x;
+       Inset * inset = p.row->par()->getInset(pos);
 
-       if (IsNewlineChar(c)) {
-               ++vpos;
-               // Draw end-of-line marker
-               LyXFont const font = getFont(bview->buffer(), row->par(), pos);
-               int const wid = lyxfont::width('n', font);
-               int const asc = lyxfont::maxAscent(font);
-               int const y = offset + row->baseline();
-               int xp[3];
-               int yp[3];
-               
-               if (bidi_level(pos) % 2 == 0) {
-                       xp[0] = int(x + wid * 0.375);
-                       yp[0] = int(y - 0.875 * asc * 0.75);
-                       
-                       xp[1] = int(x);
-                       yp[1] = int(y - 0.500 * asc * 0.75);
-                       
-                       xp[2] = int(x + wid * 0.375);
-                       yp[2] = int(y - 0.125 * asc * 0.75);
-                       
-                       pain.lines(xp, yp, 3, LColor::eolmarker);
-                       
-                       xp[0] = int(x);
-                       yp[0] = int(y - 0.500 * asc * 0.75);
-                       
-                       xp[1] = int(x + wid);
-                       yp[1] = int(y - 0.500 * asc * 0.75);
-                       
-                       xp[2] = int(x + wid);
-                       yp[2] = int(y - asc * 0.75);
-                       
-                       pain.lines(xp, yp, 3, LColor::eolmarker);
-               } else {
-                       xp[0] = int(x + wid * 0.625);
-                       yp[0] = int(y - 0.875 * asc * 0.75);
-                       
-                       xp[1] = int(x + wid);
-                       yp[1] = int(y - 0.500 * asc * 0.75);
-                       
-                       xp[2] = int(x + wid * 0.625);
-                       yp[2] = int(y - 0.125 * asc * 0.75);
-                       
-                       pain.lines(xp, yp, 3, LColor::eolmarker);
-                       
-                       xp[0] = int(x + wid);
-                       yp[0] = int(y - 0.500 * asc * 0.75);
-                       
-                       xp[1] = int(x);
-                       yp[1] = int(y - 0.500 * asc * 0.75);
-                       
-                       xp[2] = int(x);
-                       yp[2] = int(y - asc * 0.75);
-                       
-                       pain.lines(xp, yp, 3, LColor::eolmarker);
-               }
-               x += wid;
+       // FIXME: shouldn't happen
+       if (!inset) {
                return;
        }
+       LyXFont const & font = getFont(p.bv->buffer(), p.row->par(), pos);
+       inset->update(p.bv, font, false);
+       inset->draw(p.bv, font, p.yo + p.row->baseline(), p.x, p.cleared);
+       if (!need_break_row && !inset_owner 
+               && p.bv->text->status() == CHANGED_IN_DRAW) {
+               Row * prev = p.row->previous();
+               if (prev && prev->par() == p.row->par()) {
+                       breakAgainOneRow(p.bv, prev);
+               } 
+               setCursor(p.bv, cursor.par(), cursor.pos());
+               need_break_row = p.row;
+       }
+}
 
-       LyXFont font = getFont(bview->buffer(), row->par(), pos);
-       LyXFont font2 = font;
 
-       if (c == Paragraph::META_INSET) {
-               Inset * tmpinset = row->par()->getInset(pos);
-               if (tmpinset) {
-                       tmpinset->update(bview, font, false);
-                       tmpinset->draw(bview, font, offset+row->baseline(), x,
-                                      cleared);
-                       if (!need_break_row && !inset_owner &&
-                           bview->text->status() == CHANGED_IN_DRAW)
-                       {
-                               if (row->previous() && row->previous()->par() == row->par())
-                                       breakAgainOneRow(bview, row->previous());
-                               setCursor(bview, cursor.par(), cursor.pos());
-                               need_break_row = const_cast<Row *>(row);
+void LyXText::drawForeignMark(DrawRowParams & p, float const orig_x, LyXFont const & orig_font)
+{
+       if (!lyxrc.mark_foreign_language)
+               return; 
+       if (orig_font.language() == latex_language)
+               return;
+       if (orig_font.language() == p.bv->buffer()->params.language)
+               return;
+       int const y = p.yo + p.row->height() - 1;
+       p.pain->line(int(orig_x), y, int(p.x), y, LColor::language);
+}
+
+void LyXText::drawHebrewComposeChar(DrawRowParams & p, pos_type & vpos)
+{
+       pos_type pos = vis2log(vpos);
+       string str;
+
+       // first char 
+       char c = p.row->par()->getChar(pos);
+       str += c;
+       ++vpos; 
+       LyXFont const & font = getFont(p.bv->buffer(), p.row->par(), pos);
+       int const width = lyxfont::width(c, font);
+       int dx = 0;
+       for (pos_type i = pos-1; i >= 0; --i) {
+               c = p.row->par()->getChar(i);
+               if (!Encodings::IsComposeChar_hebrew(c)) {
+                       if (IsPrintableNonspace(c)) {
+                               int const width2 = 
+                                       singleWidth(p.bv, p.row->par(), i, c);
+                               // dalet / resh
+                               dx = (c == 'ø' || c == 'ã')
+                                       ? width2 - width 
+                                       : (width2 - width) / 2;
                        }
+                       break;
                }
-               ++vpos;
+       }
+       // Draw nikud
+       p.pain->text(int(p.x) + dx, p.yo + p.row->baseline(), str, font);
+}
 
-               if (lyxrc.mark_foreign_language &&
-                       font.language() != latex_language &&
-                   font.language() != bview->buffer()->params.language) {
-                       int const y = offset + row->height() - 1;
-                       pain.line(int(tmpx), y, int(x), y, LColor::language);
+void LyXText::drawArabicComposeChar(DrawRowParams & p, pos_type & vpos)
+{
+       pos_type pos = vis2log(vpos);
+       string str;
+       // first char 
+       char c = p.row->par()->getChar(pos);
+       c = transformChar(c, p.row->par(), pos);
+       str +=c;
+       ++vpos;
+       LyXFont const & font = getFont(p.bv->buffer(), p.row->par(), pos);
+       int const width = lyxfont::width(c, font);
+       int dx = 0;
+       for (pos_type i = pos-1; i >= 0; --i) {
+               c = p.row->par()->getChar(i);
+               if (!Encodings::IsComposeChar_arabic(c)) {
+                       if (IsPrintableNonspace(c)) {
+                               int const width2 = 
+                                       singleWidth(p.bv, p.row->par(), i, c);
+                               dx = (width2 - width) / 2;
+                       }
+                       break;
                }
-
-               return;
        }
+       // Draw nikud
+       p.pain->text(int(p.x) + dx, p.yo + p.row->baseline(), str, font);
+}
+void LyXText::drawChars(DrawRowParams & p, pos_type & vpos,
+       bool hebrew, bool arabic)
+{
+       pos_type pos = vis2log(vpos);
+       pos_type const last = rowLastPrintable(p.row);
+       LyXFont const & orig_font = getFont(p.bv->buffer(), p.row->par(), pos);
+       // first character
+       string str;
+       str += p.row->par()->getChar(pos);
+       if (arabic) {
+               unsigned char c = str[0];
+               str[0] = transformChar(c, p.row->par(), pos);
+       }
+       ++vpos;
 
-       // usual characters, no insets
+       // collect as much similar chars as we can
+       while (vpos <= last && (pos = vis2log(vpos)) >= 0) {
+               char c = p.row->par()->getChar(pos);
+               if (!IsPrintableNonspace(c))
+                       break;
+               if (arabic && Encodings::IsComposeChar_arabic(c))
+                       break;
+               if (hebrew && Encodings::IsComposeChar_hebrew(c))
+                       break;
+               if (orig_font != getFont(p.bv->buffer(), p.row->par(), pos))
+                       break;
+               str += c;
+               ++vpos;
+       }
+       // Draw text and set the new x position
+       p.pain->text(int(p.x), p.yo + p.row->baseline(), str, orig_font);
+       p.x += lyxfont::width(str, orig_font);
+}
 
-       // Collect character that we can draw in one command
-
-       // This is dirty, but fast. Notice that it will never be too small.
-       // For the record, I'll note that Microsoft Word has a limit
-       // of 768 here. We have none :-) (Asger)
-       // Ok. I am the first to admit that the use of std::string will be
-       // a tiny bit slower than using a POD char array. However, I claim
-       // that this slowdown is so small that it is close to inperceptive.
-       // So IMHO we should go with the easier and clearer implementation.
-       // And even if 1024 is a large number here it might overflow, string
-       // will only overflow if the machine is out of memory...
-       static string textstring;
-       textstring = c;
-       ++vpos;
+void LyXText::draw(DrawRowParams & p, pos_type & vpos)
+{
+       pos_type const pos = vis2log(vpos);
+       Paragraph * par = p.row->par();
 
-       pos_type const last = rowLastPrintable(row);
+       LyXFont const & orig_font = getFont(p.bv->buffer(), par, pos);
 
-       if (font.language()->lang() == "hebrew") {
-               if (Encodings::IsComposeChar_hebrew(c)) {
-                       int const width = lyxfont::width(c, font2);
-                       int dx = 0;
-                       for (pos_type i = pos-1; i >= 0; --i) {
-                               c = row->par()->getChar(i);
-                               if (!Encodings::IsComposeChar_hebrew(c)) {
-                                       if (IsPrintableNonspace(c)) {
-                                               int const width2 =
-                                                       singleWidth(bview,
-                                                                   row->par(),
-                                                                   i, c);
-                                               dx = (c == 'ø' || c == 'ã') // dalet / resh
-                                                       ? width2 - width : (width2 - width) / 2;
-                                       }
-                                       break;
-                               }
-                       }
-                       // Draw nikud
-                       pain.text(int(x) + dx, offset + row->baseline(),
-                                 textstring, font);
-               } else {
-                       while (vpos <= last &&
-                              (pos = vis2log(vpos)) >= 0
-                              && IsPrintableNonspace(c = row->par()->getChar(pos))
-                              && !Encodings::IsComposeChar_hebrew(c)
-                              && font2 == getFont(bview->buffer(), row->par(), pos)) {
-                               textstring += c;
-                               ++vpos;
-                       }
-                       // Draw text and set the new x position
-                       pain.text(int(x), offset + row->baseline(),
-                                 textstring, font);
-                       x += lyxfont::width(textstring, font);
-               }
-       } else if (font.language()->lang() == "arabic" &&
-                  (lyxrc.font_norm_type == LyXRC::ISO_8859_6_8 ||
-                   lyxrc.font_norm_type == LyXRC::ISO_10646_1)) {
-               if (Encodings::IsComposeChar_arabic(c)) {
-                       c = transformChar(c, row->par(), pos);
-                       textstring = c;
-                       int const width = lyxfont::width(c, font2);
-                       int dx = 0;
-                       for (pos_type i = pos-1; i >= 0; --i) {
-                               c = row->par()->getChar(i);
-                               if (!Encodings::IsComposeChar_arabic(c)) {
-                                       if (IsPrintableNonspace(c)) {
-                                               int const width2 =
-                                                       singleWidth(bview,
-                                                                   row->par(),
-                                                                   i, c);
-                                               dx = (width2 - width) / 2;
-                                       }
-                                       break;
-                               }
-                       }
-                       // Draw nikud
-                       pain.text(int(x) + dx, offset + row->baseline(), 
-                                 textstring, font);
-               } else {
-                       textstring = transformChar(c, row->par(), pos);
-                       while (vpos <= last &&
-                              (pos = vis2log(vpos)) >= 0
-                              && IsPrintableNonspace(c = row->par()->getChar(pos))
-                              && !Encodings::IsComposeChar_arabic(c)
-                              && font2 == getFont(bview->buffer(), row->par(), pos)) {
-                               c = transformChar(c, row->par(), pos);
-                               textstring += c;
-                               ++vpos;
-                       }
-                       // Draw text and set the new x position
-                       pain.text(int(x), offset + row->baseline(),
-                                 textstring, font);
-                       x += lyxfont::width(textstring, font);
-               }
-       } else {
-               while (vpos <= last &&
-                      (pos = vis2log(vpos)) >= 0
-                      && IsPrintableNonspace(c = row->par()->getChar(pos))
-                      && font2 == getFont(bview->buffer(), row->par(), pos)) {
-                       textstring += c;
-                       ++vpos;
-               }
-               // Draw text and set the new x position
-               pain.text(int(x), offset + row->baseline(), textstring, font);
-               x += lyxfont::width(textstring, font);
+       float const orig_x = p.x;
+        
+       char const c = par->getChar(pos);
+       if (IsNewlineChar(c)) {
+               ++vpos;
+               drawNewline(p, pos);
+               return;
+       } else if (IsInsetChar(c)) {
+               drawInset(p, pos);
+               ++vpos;
+               drawForeignMark(p, orig_x, orig_font);
+               return;
        }
 
+       // usual characters, no insets
+
+       // special case languages
+       bool const hebrew = (orig_font.language()->lang() == "hebrew");
+       bool const arabic = 
+               orig_font.language()->lang() == "arabic" &&
+               (lyxrc.font_norm_type == LyXRC::ISO_8859_6_8 ||
+               lyxrc.font_norm_type == LyXRC::ISO_10646_1);
+
+       // draw as many chars as we can
+       if ((!hebrew && !arabic)
+               || (hebrew && !Encodings::IsComposeChar_hebrew(c))
+               || (arabic && !Encodings::IsComposeChar_arabic(c))) {
+               drawChars(p, vpos, true, false);
+       } else if (hebrew) {
+               drawHebrewComposeChar(p, vpos);
+       } else if (arabic) {
+               drawArabicComposeChar(p, vpos);
+       }
+
+       drawForeignMark(p, orig_x, orig_font);
 #ifdef INHERIT_LANGUAGE
 #ifdef WITH_WARNINGS
        if ((font.language() == inherit_language) ||
@@ -623,17 +654,6 @@ void LyXText::draw(BufferView * bview, Row const * row,
                lyxerr << "No this shouldn't happen!\n";
 #endif
 #endif
-       if (lyxrc.mark_foreign_language &&
-           font.language() != latex_language &&
-           font.language() != bview->buffer()->params.language) {
-               int const y = offset + row->height() - 1;
-               pain.line(int(tmpx), y, int(x), y,
-                         LColor::language);
-       }
-
-       // If we want ulem.sty support, drawing
-       // routines should go here. (Asger)
-       // Why shouldn't LyXFont::drawText handle it internally?
 }
 
 
@@ -1156,8 +1176,16 @@ bool LyXText::hfillExpansion(Buffer const * buf, Row const * row_ptr,
                return false;
        
        // at the end of a row it does not count
-       if (pos >= rowLast(row_ptr))
-               return false;
+       // unless another hfill exists on the line
+       if (pos >= rowLast(row_ptr)) {
+               pos_type i = row_ptr->pos();
+               while (i < pos && !row_ptr->par()->isHfill(i)) {
+                       ++i;
+               }
+               if (i == pos) {
+                       return false;
+               }
+       } 
        
        // at the beginning of a row it does not count, if it is not 
        // the first row of a paragaph
@@ -1852,11 +1880,13 @@ void LyXText::insertChar(BufferView * bview, char c)
        }
    
        // the display inset stuff
-       if (cursor.row()->par()->isInset(cursor.row()->pos())
-           && cursor.row()->par()->getInset(cursor.row()->pos())
-           && (cursor.row()->par()->getInset(cursor.row()->pos())->display() ||
-               cursor.row()->par()->getInset(cursor.row()->pos())->needFullRow()))
-               cursor.row()->fill(-1); // to force a new break  
+       if (cursor.row()->par()->isInset(cursor.row()->pos())) {
+               Inset * inset = cursor.row()->par()->getInset(cursor.row()->pos());
+               if (inset && (inset->display() || inset->needFullRow())) { 
+                       // force a new break
+                       cursor.row()->fill(-1); // to force a new break  
+               }
+       }
 
        // get the cursor row fist
        Row * row = cursor.row();
@@ -3557,7 +3587,7 @@ void LyXText::paintRowText(DrawRowParams & p)
                                p.x += p.separator;
                        ++vpos;
                } else {
-                       draw(p.bv, p.row, vpos, p.yo, p.x, p.cleared);
+                       draw(p, vpos);
                }
        }
 }