the hfill change is as pointed out by Michael.

The rest just re-organises the code to remove duplicate code
and make things into smaller more readable functions

thanks
john

-- 
"Faced with the prospect of rereading this book, I would rather have 
 my brains ripped out by a plastic fork."
        - Charles Cooper on "Business at the Speed of Thought" 
Index: src/ChangeLog
===================================================================
RCS file: /usr/local/lyx/cvsroot/lyx-devel/src/ChangeLog,v
retrieving revision 1.429
diff -u -r1.429 ChangeLog
--- src/ChangeLog       2001/12/03 13:17:01     1.429
+++ src/ChangeLog       2001/12/04 02:40:10
@@ -1,3 +1,8 @@
+2001-12-04  John Levon  <[EMAIL PROTECTED]>
+
+       * lyxtext.h:
+       * text.C: fix hfill at end of line, clean up
+ 
 2001-12-03  Juergen Vigna  <[EMAIL PROTECTED]>
 
        * text.C (rowLast): simplified code
Index: src/text.C
===================================================================
RCS file: /usr/local/lyx/cvsroot/lyx-devel/src/text.C,v
retrieving revision 1.205
diff -u -r1.205 text.C
--- src/text.C  2001/12/03 13:17:01     1.205
+++ src/text.C  2001/12/04 02:40:20
@@ -407,212 +407,243 @@
        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);
 
-void LyXText::draw(BufferView * bview, Row const * row,
-                   pos_type & vpos, int offset, float & x, bool cleared)
+       p.x += wid;
+}
+
+ 
+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;
                }
+       }
+       // 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;
 
-               return;
+       // 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);
+}
 
-       // usual characters, no insets
+ 
+void LyXText::draw(DrawRowParams & p, pos_type & vpos)
+{
+       pos_type const pos = vis2log(vpos);
+       Paragraph * par = p.row->par();
 
-       // Collect character that we can draw in one command
+       LyXFont const & orig_font = getFont(p.bv->buffer(), par, pos);
 
-       // 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;
+       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;
+       }
 
-       pos_type const last = rowLastPrintable(row);
+       // usual characters, no insets
 
-       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);
+       // 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) ||
@@ -620,17 +651,6 @@
                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?
 }
 
 
@@ -1160,8 +1180,16 @@
                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
@@ -1857,11 +1885,13 @@
        }
    
        // 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();
@@ -3562,7 +3593,7 @@
                                p.x += p.separator;
                        ++vpos;
                } else {
-                       draw(p.bv, p.row, vpos, p.yo, p.x, p.cleared);
+                       draw(p, vpos);
                }
        }
 }
Index: src/lyxtext.h
===================================================================
RCS file: /usr/local/lyx/cvsroot/lyx-devel/src/lyxtext.h,v
retrieving revision 1.99
diff -u -r1.99 lyxtext.h
--- src/lyxtext.h       2001/11/29 13:43:11     1.99
+++ src/lyxtext.h       2001/12/04 02:40:20
@@ -560,9 +565,9 @@
                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 +632,23 @@
        ///
        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;

Reply via email to