]> git.lyx.org Git - features.git/commitdiff
new painter,workarea and lcolor. Read the diff/sources and ChangeLog...
authorLars Gullik Bjønnes <larsbj@gullik.org>
Thu, 10 Feb 2000 17:53:36 +0000 (17:53 +0000)
committerLars Gullik Bjønnes <larsbj@gullik.org>
Thu, 10 Feb 2000 17:53:36 +0000 (17:53 +0000)
git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/trunk@550 a592a061-630c-0410-9148-cb99ea01b6c8

64 files changed:
ChangeLog
po/POTFILES.in
src/BufferView.C
src/BufferView.h
src/FontLoader.C
src/LColor.C [new file with mode: 0644]
src/LColor.h [new file with mode: 0644]
src/LyXView.C
src/Makefile.am
src/Painter.C [new file with mode: 0644]
src/Painter.h [new file with mode: 0644]
src/PainterBase.C [new file with mode: 0644]
src/PainterBase.h [new file with mode: 0644]
src/WorkArea.C [new file with mode: 0644]
src/WorkArea.h [new file with mode: 0644]
src/bmtable.c
src/insets/figinset.C
src/insets/figinset.h
src/insets/insetbib.C
src/insets/insetbib.h
src/insets/insetcommand.C
src/insets/insetcommand.h
src/insets/inseterror.C
src/insets/inseterror.h
src/insets/insetinfo.C
src/insets/insetinfo.h
src/insets/insetlatexaccent.C
src/insets/insetlatexaccent.h
src/insets/insetquotes.C
src/insets/insetquotes.h
src/insets/insetspecialchar.C
src/insets/insetspecialchar.h
src/insets/inseturl.h
src/insets/lyxinset.h
src/lyx_cb.C
src/lyx_gui.C
src/lyxdraw.C
src/lyxdraw.h
src/lyxfont.C
src/lyxfont.h
src/lyxfr1.C
src/lyxfunc.C
src/lyxscreen.h
src/lyxtext.h
src/mathed/formula.C
src/mathed/formula.h
src/mathed/formulamacro.C
src/mathed/formulamacro.h
src/mathed/math_cursor.C
src/mathed/math_cursor.h
src/mathed/math_defs.h
src/mathed/math_delim.C
src/mathed/math_draw.C
src/mathed/math_inset.C
src/mathed/math_inset.h
src/mathed/math_macro.C
src/mathed/math_macro.h
src/mathed/math_root.C
src/mathed/math_root.h
src/minibuffer.C
src/paragraph.C
src/screen.C
src/text.C
src/text2.C

index 165ee0f5c130aa5ef9f1294eda349183b3aa30df..b05ab52d4539626164331024ee36c193d90ccf46 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,14 @@
+2000-02-10  Lars Gullik Bjønnes  <larsbj@lyx.org>
+
+       * a lot of files: The Painter, LColor and WorkArea from the old
+       devel branch has been ported to lyx-devel. Some new files and a
+       lot of #ifdeffed code. The new workarea is enabled by default, but
+       if you want to test the new Painter and LColor you have to compile
+       with USE_PAINTER defined (do this in config.h f.ex.) There are
+       still some rought edges, and I'd like some help to clear those
+       out. It looks stable (loads and displays the Userguide very well).
+       
+
 2000-02-10  Jean-Marc Lasgouttes  <Jean-Marc.Lasgouttes@inria.fr>
 
        * src/buffer.C (pop_tag): revert to the previous implementation
index b41b7f4c2ed3b96f923721f4d11dc20bd779dcc2..7f6a48b17b17199b317390536da7731df82bc297 100644 (file)
@@ -49,6 +49,7 @@ src/LaTeXLog.C
 src/latexoptions.C
 src/layout.C
 src/layout_forms.C
+src/LColor.C
 src/Literate.C
 src/LyXAction.C
 src/lyx.C
@@ -74,6 +75,7 @@ src/mathed/math_panel.C
 src/menus.C
 src/minibuffer.C
 src/minibuffer.h
+src/Painter.C
 src/PaperLayout.C
 src/paragraph.C
 src/ParagraphExtra.C
index 66ac7d4bf611ff0b968aa2234e65881646e8b08f..0cb2be39dbe55c408aabcc2a764b38878d3da90b 100644 (file)
@@ -34,8 +34,12 @@ using std::for_each;
 #include "insets/lyxinset.h"
 #include "minibuffer.h"
 #include "lyxscreen.h"
+
+#ifndef NEW_WA
 #include "up.xpm"
 #include "down.xpm"
+#endif
+
 #include "debug.h"
 #include "lyxdraw.h"
 #include "lyx_gui_misc.h"
@@ -48,6 +52,7 @@ using std::for_each;
 #include "intl.h"
 #include "lyxrc.h"
 #include "lyxrow.h"
+#include "WorkArea.h"
 
 using std::find_if;
 
@@ -65,8 +70,10 @@ extern InsetUpdateStruct * InsetUpdateList;
 extern void UpdateInsetUpdateList();
 extern void FreeUpdateTimer();
 
+#ifndef NEW_WA
 // This is _very_ temporary
 FL_OBJECT * figinset_canvas;
+#endif
 
 BufferView::BufferView(LyXView * o, int xpos, int ypos,
                       int width, int height)
@@ -75,17 +82,25 @@ BufferView::BufferView(LyXView * o, int xpos, int ypos,
        buffer_ = 0;
        text = 0;
        screen = 0;
-       work_area = 0;
+#ifdef NEW_WA
+       workarea = new WorkArea(this, xpos, ypos, width, height);
+#else
        figinset_canvas = 0;
+       work_area = 0;
        scrollbar = 0;
        button_down = 0;
        button_up = 0;
+#endif
        timer_cursor = 0;
-       current_scrollbar_value = 0;
        create_view(xpos, ypos, width, height);
+       current_scrollbar_value = 0;
        // Activate the timer for the cursor 
        fl_set_timer(timer_cursor, 0.4);
+#ifdef NEW_WA
+       workarea->setFocus();
+#else
        fl_set_focus_object(owner_->getForm(), work_area);
+#endif
        work_area_focus = true;
        lyx_focus = false;
        the_locking_inset = 0;
@@ -98,7 +113,15 @@ BufferView::~BufferView()
        delete text;
 }
 
-             
+
+#ifdef USE_PAINTER
+Painter & BufferView::painter() 
+{
+       return workarea->getPainter();
+}
+#endif
+
+
 void BufferView::buffer(Buffer * b)
 {
        lyxerr[Debug::INFO] << "Setting buffer in BufferView ("
@@ -150,7 +173,11 @@ void BufferView::buffer(Buffer * b)
                lyxerr[Debug::INFO] << "  No Buffer!" << endl;
                owner_->getMenus()->hideMenus();
                updateScrollbar();
+#ifdef NEW_WA
+               workarea->redraw();
+#else
                fl_redraw_object(work_area);
+#endif
 
                // Also remove all remaining text's from the testcache.
                // (there should not be any!) (if there is any it is a
@@ -170,13 +197,34 @@ void BufferView::updateScreen()
 {
        // Regenerate the screen.
        delete screen;
+#ifdef NEW_WA
+       screen = new LyXScreen(this,
+                              workarea->getWin(),
+                              workarea->getPixmap(),
+                              workarea->workWidth(),
+                              workarea->height(),
+                              workarea->xpos(),
+                              workarea->ypos(),
+                              text);
+#else
        screen = new LyXScreen(FL_ObjWin(work_area),
                               work_area->w,
                               work_area->h,
                               work_area->x,
                               work_area->y,
                               text);
+#endif
+}
+
+
+#ifdef NEW_WA
+void BufferView::resize(int xpos, int ypos, int width, int height)
+{
+       workarea->resize(xpos, ypos, width, height);
+       update(3);
+       redraw();
 }
+#endif
 
 
 void BufferView::resize()
@@ -187,23 +235,30 @@ void BufferView::resize()
 }
 
 
+#ifndef NEW_WA
 static bool lgb_hack = false;
+#endif
 
 void BufferView::redraw()
 {
        lyxerr[Debug::INFO] << "BufferView::redraw()" << endl;
+#ifdef NEW_WA
+       workarea->redraw();
+#else
        lgb_hack = true;
        fl_redraw_object(work_area);
        fl_redraw_object(scrollbar);
        fl_redraw_object(button_down);
        fl_redraw_object(button_up);
        lgb_hack = false;
+#endif
 }
 
 
 void BufferView::fitCursor()
 {
        if (screen) screen->FitCursor();
+       updateScrollbar();
 }
 
 
@@ -220,8 +275,12 @@ void BufferView::updateScrollbar()
         * be possible */
 
        if (!buffer_) {
+#ifdef NEW_WA
+               workarea->setScrollbar(0, 1.0);
+#else
                fl_set_slider_value(scrollbar, 0);
                fl_set_slider_size(scrollbar, scrollbar->h);
+#endif
                return;
        }
        
@@ -237,27 +296,65 @@ void BufferView::updateScrollbar()
                cbsf = screen->first;
 
        // check if anything has changed.
+#ifdef NEW_WA
+       if (max2 == cbth &&
+           height2 == workarea->height() &&
+           current_scrollbar_value == cbsf)
+               return; // no
+       max2 = cbth;
+       height2 = workarea->height();
+       current_scrollbar_value = cbsf;
+#else
        if (max2 == cbth &&
            height2 == work_area->h &&
            current_scrollbar_value == cbsf)
                return;       // no
-       
        max2 = cbth;
        height2 = work_area->h;
        current_scrollbar_value = cbsf;
+#endif
 
        if (cbth <= height2) { // text is smaller than screen
+#ifdef NEW_WA
+               workarea->setScrollbar(0, 1.0); // right?
+#else
                fl_set_slider_size(scrollbar, scrollbar->h);
+#endif
                return;
        }
-       
+
+#ifdef NEW_WA
+       long maximum_height = workarea->height() * 3 / 4 + cbth;
+#else
        long maximum_height = work_area->h * 3 / 4 + cbth;
+#endif
        long value = cbsf;
 
        // set the scrollbar
+#ifdef NEW_WA
+       double hfloat = workarea->height();
+#else
        double hfloat = work_area->h;
+#endif
        double maxfloat = maximum_height;
-   
+
+#ifdef NEW_WA
+       float slider_size = 0.0;
+       int slider_value = value;
+
+       workarea->setScrollbarBounds(0, text->height - workarea->height());
+       double lineh = text->DefaultHeight();
+       workarea->setScrollbarIncrements(lineh);
+       if (maxfloat > 0.0) {
+               if ((hfloat / maxfloat) * float(height2) < 3)
+                       slider_size = 3.0/float(height2);
+               else
+                       slider_size = hfloat / maxfloat;
+       } else
+               slider_size = hfloat;
+
+       workarea->setScrollbar(slider_value, slider_size / workarea->height());
+#else
        fl_set_slider_value(scrollbar, value);
        fl_set_slider_bounds(scrollbar, 0,
                             maximum_height - work_area->h);
@@ -275,6 +372,7 @@ void BufferView::updateScrollbar()
        } else
                fl_set_slider_size(scrollbar, hfloat);
        fl_set_slider_precision(scrollbar, 0);
+#endif
 }
 
 
@@ -315,11 +413,19 @@ int BufferView::resizeCurrentBuffer()
                selection = text->selection;
                mark_set = text->mark_set;
                delete text;
+#ifdef NEW_WA
+               text = new LyXText(this, workarea->workWidth(), buffer_);
+#else
                text = new LyXText(work_area->w, buffer_);
+#endif
        } else {
                // See if we have a text in TextCache that fits
                // the new buffer_ with the correct width.
+#ifdef NEW_WA
+               text = textcache.findFit(buffer_, workarea->workWidth());
+#else
                text = textcache.findFit(buffer_, work_area->w);
+#endif
                if (text) {
                        if (lyxerr.debugging()) {
                                lyxerr << "Found a LyXText that fits:\n";
@@ -328,7 +434,11 @@ int BufferView::resizeCurrentBuffer()
                        if (lyxerr.debugging())
                                textcache.show(lyxerr, "resizeCurrentBuffer");
                } else {
+#ifdef NEW_WA
+                       text = new LyXText(this, workarea->workWidth(), buffer_);
+#else
                        text = new LyXText(work_area->w, buffer_);
+#endif
                }
        }
        updateScreen();
@@ -399,6 +509,14 @@ void BufferView::gotoError()
 }
 
 
+#ifdef NEW_WA
+extern "C" {
+       void C_BufferView_CursorToggleCB(FL_OBJECT * ob, long buf)
+       {
+               BufferView::CursorToggleCB(ob, buf);
+       }
+}
+#else
 extern "C" {
 // Just a bunch of C wrappers around static members of BufferView
        void C_BufferView_UpCB(FL_OBJECT * ob, long buf)
@@ -433,11 +551,13 @@ extern "C" {
                                                     0, 0, key, xev);
        }
 }
+#endif
 
 
 void BufferView::create_view(int xpos, int ypos, int width, int height)
 {
        FL_OBJECT * obj;
+#ifndef NEW_WA
        int const bw = abs(fl_get_border_width());
 
        // a hack for the figinsets (Matthias)
@@ -523,7 +643,7 @@ void BufferView::create_view(int xpos, int ypos, int width, int height)
 
        // Remove the blue feedback rectangle
        fl_set_pixmapbutton_focus_outline(obj, 0);
-
+#endif
        //
        // TIMERS
        //
@@ -537,6 +657,24 @@ void BufferView::create_view(int xpos, int ypos, int width, int height)
 
 
 // Callback for scrollbar up button
+#ifdef NEW_WA
+void BufferView::UpCB(long time, int button)
+{
+       if (buffer_ == 0) return;
+
+       switch (button) {
+       case 3:
+               ScrollUpOnePage();
+               break;
+       case 2:
+               ScrollDownOnePage();
+               break;
+       default:
+               ScrollUp(time);
+               break;
+       }
+}
+#else
 void BufferView::UpCB(FL_OBJECT * ob, long)
 {
        BufferView * view = static_cast<BufferView*>(ob->u_vdata);
@@ -557,6 +695,7 @@ void BufferView::UpCB(FL_OBJECT * ob, long)
                view->ScrollUp(time++); break;
        }
 }
+#endif
 
 
 static inline
@@ -567,6 +706,41 @@ void waitForX()
 
 
 // Callback for scrollbar slider
+#ifdef NEW_WA
+void BufferView::ScrollCB(double value)
+{
+       extern bool cursor_follows_scrollbar;
+       
+       if (buffer_ == 0) return;
+
+       current_scrollbar_value = long(value);
+       if (current_scrollbar_value < 0)
+               current_scrollbar_value = 0;
+   
+       if (!screen)
+               return;
+
+       screen->Draw(current_scrollbar_value);
+
+       if (cursor_follows_scrollbar) {
+               LyXText * vbt = text;
+               int height = vbt->DefaultHeight();
+               
+               if (vbt->cursor.y < screen->first + height) {
+                       vbt->SetCursorFromCoordinates(0,
+                                                     screen->first +
+                                                     height);
+               } else if (vbt->cursor.y >
+                          screen->first + workarea->height() - height) {
+                       vbt->SetCursorFromCoordinates(0,
+                                                     screen->first +
+                                                     workarea->height()  -
+                                                     height);
+               }
+       }
+       waitForX();
+}
+#else
 void BufferView::ScrollCB(FL_OBJECT * ob, long)
 {
        BufferView * view = static_cast<BufferView*>(ob->u_vdata);
@@ -602,9 +776,28 @@ void BufferView::ScrollCB(FL_OBJECT * ob, long)
        }
        waitForX();
 }
+#endif
 
 
 // Callback for scrollbar down button
+#ifdef NEW_WA
+void BufferView::DownCB(long time, int button)
+{
+       if (buffer_ == 0) return;
+       
+       switch (button) {
+       case 2:
+               ScrollUpOnePage();
+               break;
+       case 3:
+               ScrollDownOnePage();
+               break;
+       default:
+               ScrollDown(time);
+               break;
+       }
+}
+#else
 void BufferView::DownCB(FL_OBJECT * ob, long)
 {
        BufferView * view = static_cast<BufferView*>(ob->u_vdata);
@@ -626,8 +819,37 @@ void BufferView::DownCB(FL_OBJECT * ob, long)
                view->ScrollDown(time++); break;
        }
 }
+#endif
+
+
+#ifdef NEW_WA
+int BufferView::ScrollUp(long time)
+{
+       if (buffer_ == 0) return 0;
+       if (!screen) return 0;
+   
+       double value = workarea->getScrollbarValue();
+   
+       if (value == 0) return 0;
 
+       float add_value =  (text->DefaultHeight()
+                           + float(time) * float(time) * 0.125);
+   
+       if (add_value > workarea->height())
+               add_value = float(workarea->height() -
+                                 text->DefaultHeight());
+   
+       value -= add_value;
 
+       if (value < 0)
+               value = 0;
+   
+       workarea->setScrollbarValue(value);
+   
+       ScrollCB(value); 
+       return 0;
+}
+#else
 int BufferView::ScrollUp(long time)
 {
        if (buffer_ == 0) return 0;
@@ -654,8 +876,39 @@ int BufferView::ScrollUp(long time)
        ScrollCB(scrollbar, 0); 
        return 0;
 }
+#endif
+
+
+#ifdef NEW_WA
+int BufferView::ScrollDown(long time)
+{
+       if (buffer_ == 0) return 0;
+       if (!screen) return 0;
+   
+       double value= workarea->getScrollbarValue();
+       pair<double, double> p = workarea->getScrollbarBounds();
+       double max = p.second;
+       
+       if (value == max) return 0;
 
+       float add_value =  (text->DefaultHeight()
+                           + float(time) * float(time) * 0.125);
+   
+       if (add_value > workarea->height())
+               add_value = float(workarea->height() -
+                                 text->DefaultHeight());
+   
+       value += add_value;
+   
+       if (value > max)
+               value = max;
 
+       workarea->setScrollbarValue(value);
+       
+       ScrollCB(value); 
+       return 0;
+}
+#else
 int BufferView::ScrollDown(long time)
 {
        if (buffer_ == 0) return 0;
@@ -684,8 +937,28 @@ int BufferView::ScrollDown(long time)
        ScrollCB(scrollbar, 0); 
        return 0;
 }
+#endif
+
+
+#ifdef NEW_WA
+void BufferView::ScrollUpOnePage()
+{
+       if (buffer_ == 0) return;
+       if (!screen) return;
+   
+       long y = screen->first;
 
+       if (!y) return;
+
+       Row * row = text->GetRowNearY(y);
+
+       y = y - workarea->height() + row->height;
 
+       workarea->setScrollbarValue(y);
+       
+       ScrollCB(y); 
+}
+#else
 void BufferView::ScrollUpOnePage(long /*time*/)
 {
        if (buffer_ == 0) return;
@@ -703,8 +976,28 @@ void BufferView::ScrollUpOnePage(long /*time*/)
    
        ScrollCB(scrollbar, 0); 
 }
+#endif
+
 
+#ifdef NEW_WA
+void BufferView::ScrollDownOnePage()
+{
+       if (buffer_ == 0) return;
+       if (!screen) return;
+   
+       long y = screen->first;
+
+       if (y > text->height - workarea->height())
+               return;
+   
+       y += workarea->height();
+       text->GetRowNearY(y);
 
+       workarea->setScrollbarValue(y);
+       
+       ScrollCB(y); 
+}
+#else
 void BufferView::ScrollDownOnePage(long /*time*/)
 {
        if (buffer_ == 0) return;
@@ -724,8 +1017,10 @@ void BufferView::ScrollDownOnePage(long /*time*/)
    
        ScrollCB(scrollbar, 0); 
 }
+#endif
 
 
+#ifndef NEW_WA
 int BufferView::work_area_handler(FL_OBJECT * ob, int event,
                                  FL_Coord, FL_Coord ,
                                  int /*key*/, void * xev)
@@ -827,7 +1122,47 @@ int BufferView::work_area_handler(FL_OBJECT * ob, int event,
        }
        return 1;
 }
+#endif
+
+
+#ifdef NEW_WA
+void BufferView::WorkAreaMotionNotify(int x, int y, unsigned int state)
+{
+       if (buffer_ == 0 || !screen) return;
+
+       // Check for inset locking
+       if (the_locking_inset) {
+               LyXCursor cursor = text->cursor;
+               the_locking_inset->
+                       InsetMotionNotify(x - cursor.x,
+                                         y - cursor.y,
+                                         state);
+               return;
+       }
+
+       // Only use motion with button 1
+       if (!state & Button1MotionMask)
+               return; 
+   
+       /* The selection possible is needed, that only motion events are 
+        * used, where the bottom press event was on the drawing area too */
+       if (selection_possible) {
+               screen->HideCursor();
 
+               text->SetCursorFromCoordinates(x, y + screen->first);
+      
+               if (!text->selection)
+                       update(-3); // Maybe an empty line was deleted
+      
+               text->SetSelection();
+               screen->ToggleToggle();
+               if (screen->FitCursor())
+                       updateScrollbar(); 
+               screen->ShowCursor();
+       }
+       return;
+}
+#else
 int BufferView::WorkAreaMotionNotify(FL_OBJECT * ob, Window,
                                     int /*w*/, int /*h*/,
                                     XEvent * ev, void * /*d*/)
@@ -870,52 +1205,190 @@ int BufferView::WorkAreaMotionNotify(FL_OBJECT * ob, Window,
        }
        return 0;
 }
+#endif
 
-
+#ifdef USE_PAINTER
+extern int bibitemMaxWidth(Painter &, LyXFont const &);
+#else
 extern int bibitemMaxWidth(LyXFont const &);
+#endif
 
 // Single-click on work area
-int BufferView::WorkAreaButtonPress(FL_OBJECT * ob, Window,
-                                   int /*w*/, int /*h*/,
-                                   XEvent * ev, void */*d*/)
+#ifdef NEW_WA
+void BufferView::WorkAreaButtonPress(int xpos, int ypos, unsigned int button)
 {
        last_click_x = -1;
        last_click_y = -1;
 
-       if (buffer_ == 0) return 0;
-       if (!screen) return 0;
+       if (buffer_ == 0 || !screen) return;
 
-       int const x = ev->xbutton.x - ob->x;
-       int const y = ev->xbutton.y - ob->y;
-       // If we hit an inset, we have the inset coordinates in these
-       // and inset_hit points to the inset.  If we do not hit an
-       // inset, inset_hit is 0, and inset_x == x, inset_y == y.
-       int inset_x = x;
-       int inset_y = y;
-       Inset * inset_hit = checkInsetHit(inset_x, inset_y);
+       Inset * inset_hit = checkInsetHit(xpos, ypos);
 
        // ok ok, this is a hack.
-       int button = ev->xbutton.button;
-       if (button == 4 || button == 5) goto wheel;
-
-       {
-               if (the_locking_inset) {
-                       // We are in inset locking mode
+       if (button == 4 || button == 5) {
+               switch (button) {
+               case 4:
+                       ScrollUp(100); // This number is only temporary
+                       break;
+               case 5:
+                       ScrollDown(100);
+                       break;
+               }
+       }
+       
+       if (the_locking_inset) {
+               // We are in inset locking mode
                
-                       /* Check whether the inset was hit. If not reset mode,
-                          otherwise give the event to the inset */
-                       if (inset_hit != 0) {
-                               the_locking_inset->
-                                       InsetButtonPress(inset_x, inset_y,
-                                                        button);
-                               return 0;
-                       } else {
-                               unlockInset(the_locking_inset);
-                       }
+               /* Check whether the inset was hit. If not reset mode,
+                  otherwise give the event to the inset */
+               if (inset_hit) {
+                       the_locking_inset->
+                               InsetButtonPress(xpos, ypos,
+                                                button);
+                       return;
+               } else {
+                       unlockInset(the_locking_inset);
                }
-
-               selection_possible = true;
-               screen->HideCursor();
+       }
+       
+       selection_possible = true;
+       screen->HideCursor();
+       
+       // Right button mouse click on a table
+       if (button == 3 &&
+           (text->cursor.par->table ||
+            text->MouseHitInTable(xpos, ypos + screen->first))) {
+               // Set the cursor to the press-position
+               text->SetCursorFromCoordinates(xpos, ypos + screen->first);
+               bool doit = true;
+               
+               // Only show the table popup if the hit is in
+               // the table, too
+               if (!text->HitInTable(text->cursor.row, xpos))
+                       doit = false;
+               
+               // Hit above or below the table?
+               if (doit) {
+                       if (!text->selection) {
+                               screen->ToggleSelection();
+                               text->ClearSelection();
+                               text->FullRebreak();
+                               screen->Update();
+                               updateScrollbar();
+                       }
+                       // Popup table popup when on a table.
+                       // This is obviously temporary, since we
+                       // should be able to popup various
+                       // context-sensitive-menus with the
+                       // the right mouse. So this should be done more
+                       // general in the future. Matthias.
+                       selection_possible = false;
+                       owner_->getLyXFunc()
+                               ->Dispatch(LFUN_LAYOUT_TABLE,
+                                          "true");
+                       return;
+               }
+       }
+       
+       int screen_first = screen->first;
+       
+       // Middle button press pastes if we have a selection
+       bool paste_internally = false;
+       if (button == 2
+           && text->selection) {
+               owner_->getLyXFunc()->Dispatch(LFUN_COPY);
+               paste_internally = true;
+       }
+       
+       // Clear the selection
+       screen->ToggleSelection();
+       text->ClearSelection();
+       text->FullRebreak();
+       screen->Update();
+       updateScrollbar();
+       
+       // Single left click in math inset?
+       if (inset_hit != 0 && inset_hit->Editable() == 2) {
+               // Highly editable inset, like math
+               selection_possible = false;
+               owner_->updateLayoutChoice();
+               owner_->getMiniBuffer()->Set(inset_hit->EditMessage());
+               inset_hit->Edit(xpos, ypos);
+               return;
+       } 
+       
+       // Right click on a footnote flag opens float menu
+       if (button == 3) { 
+               selection_possible = false;
+               return;
+       }
+       
+       text->SetCursorFromCoordinates(xpos, ypos + screen_first);
+       text->FinishUndo();
+       text->sel_cursor = text->cursor;
+       text->cursor.x_fix = text->cursor.x;
+       
+       owner_->updateLayoutChoice();
+       if (screen->FitCursor()){
+               updateScrollbar();
+               selection_possible = false;
+       }
+       
+       // Insert primary selection with middle mouse
+       // if there is a local selection in the current buffer,
+       // insert this
+       if (button == 2) {
+               if (paste_internally)
+                       owner_->getLyXFunc()->Dispatch(LFUN_PASTE);
+               else
+                       owner_->getLyXFunc()->Dispatch(LFUN_PASTESELECTION,
+                                                      "paragraph");
+               selection_possible = false;
+               return;
+       }
+}
+#else
+int BufferView::WorkAreaButtonPress(FL_OBJECT * ob, Window,
+                                   int /*w*/, int /*h*/,
+                                   XEvent * ev, void */*d*/)
+{
+       last_click_x = -1;
+       last_click_y = -1;
+
+       if (buffer_ == 0) return 0;
+       if (!screen) return 0;
+
+       int const x = ev->xbutton.x - ob->x;
+       int const y = ev->xbutton.y - ob->y;
+       // If we hit an inset, we have the inset coordinates in these
+       // and inset_hit points to the inset.  If we do not hit an
+       // inset, inset_hit is 0, and inset_x == x, inset_y == y.
+       int inset_x = x;
+       int inset_y = y;
+       Inset * inset_hit = checkInsetHit(inset_x, inset_y);
+
+       // ok ok, this is a hack.
+       int button = ev->xbutton.button;
+       if (button == 4 || button == 5) goto wheel;
+
+       {
+               if (the_locking_inset) {
+                       // We are in inset locking mode
+               
+                       /* Check whether the inset was hit. If not reset mode,
+                          otherwise give the event to the inset */
+                       if (inset_hit != 0) {
+                               the_locking_inset->
+                                       InsetButtonPress(inset_x, inset_y,
+                                                        button);
+                               return 0;
+                       } else {
+                               unlockInset(the_locking_inset);
+                       }
+               }
+
+               selection_possible = true;
+               screen->HideCursor();
        
                // Right button mouse click on a table
                if (button == 3 &&
@@ -1039,8 +1512,164 @@ int BufferView::WorkAreaButtonPress(FL_OBJECT * ob, Window,
        
        return 0;
 }
+#endif
+
+
+#ifdef NEW_WA
+void BufferView::WorkAreaButtonRelease(int x, int y, unsigned int button)
+{
+       if (buffer_ == 0 || screen == 0) return;
 
+       // If we hit an inset, we have the inset coordinates in these
+       // and inset_hit points to the inset.  If we do not hit an
+       // inset, inset_hit is 0, and inset_x == x, inset_y == y.
+       Inset * inset_hit = checkInsetHit(x, y);
+
+       if (the_locking_inset) {
+               // We are in inset locking mode.
 
+               /* LyX does a kind of work-area grabbing for insets.
+                  Only a ButtonPress Event outside the inset will 
+                  force a InsetUnlock. */
+               the_locking_inset->
+                       InsetButtonRelease(x, x, button);
+               return;
+       }
+       
+       selection_possible = false;
+        if (text->cursor.par->table) {
+                int cell = text->
+                        NumberOfCell(text->cursor.par,
+                                     text->cursor.pos);
+                if (text->cursor.par->table->IsContRow(cell) &&
+                    text->cursor.par->table->
+                    CellHasContRow(text->cursor.par->table->
+                                   GetCellAbove(cell))<0) {
+                        text->CursorUp();
+                }
+        }
+       
+       if (button >= 2) return;
+
+       SetState();
+       owner_->getMiniBuffer()->Set(CurrentState());
+
+       // Did we hit an editable inset?
+       if (inset_hit != 0) {
+               // Inset like error, notes and figures
+               selection_possible = false;
+#ifdef WITH_WARNINGS
+#warning fix this proper in 0.13
+#endif
+               // Following a ref shouldn't issue
+               // a push on the undo-stack
+               // anylonger, now that we have
+               // keybindings for following
+               // references and returning from
+               // references.  IMHO though, it
+               // should be the inset's own business
+               // to push or not push on the undo
+               // stack. They don't *have* to
+               // alter the document...
+               // (Joacim)
+               // ...or maybe the SetCursorParUndo()
+               // below isn't necessary at all anylonger?
+               if (inset_hit->LyxCode() == Inset::REF_CODE) {
+                       text->SetCursorParUndo();
+               }
+
+               owner_->getMiniBuffer()->Set(inset_hit->EditMessage());
+               inset_hit->Edit(x, y);
+               return;
+       }
+
+       // check whether we want to open a float
+       if (text) {
+               bool hit = false;
+               char c = ' ';
+               if (text->cursor.pos <
+                   text->cursor.par->Last()) {
+                       c = text->cursor.par->
+                               GetChar(text->cursor.pos);
+               }
+               if (c == LyXParagraph::META_FOOTNOTE
+                   || c == LyXParagraph::META_MARGIN
+                   || c == LyXParagraph::META_FIG
+                   || c == LyXParagraph::META_TAB
+                   || c == LyXParagraph::META_WIDE_FIG
+                   || c == LyXParagraph::META_WIDE_TAB
+                    || c == LyXParagraph::META_ALGORITHM){
+                       hit = true;
+               } else if (text->cursor.pos - 1 >= 0) {
+                       c = text->cursor.par->
+                               GetChar(text->cursor.pos - 1);
+                       if (c == LyXParagraph::META_FOOTNOTE
+                           || c == LyXParagraph::META_MARGIN
+                           || c == LyXParagraph::META_FIG
+                           || c == LyXParagraph::META_TAB
+                           || c == LyXParagraph::META_WIDE_FIG 
+                           || c == LyXParagraph::META_WIDE_TAB
+                           || c == LyXParagraph::META_ALGORITHM){
+                               // We are one step too far to the right
+                               text->CursorLeft();
+                               hit = true;
+                       }
+               }
+               if (hit == true) {
+                       toggleFloat();
+                       selection_possible = false;
+                       return;
+               }
+       }
+
+       // Do we want to close a float? (click on the float-label)
+       if (text->cursor.row->par->footnoteflag == 
+           LyXParagraph::OPEN_FOOTNOTE
+           //&& text->cursor.pos == 0
+           && text->cursor.row->previous &&
+           text->cursor.row->previous->par->
+           footnoteflag != LyXParagraph::OPEN_FOOTNOTE){
+               LyXFont font (LyXFont::ALL_SANE);
+               font.setSize(LyXFont::SIZE_FOOTNOTE);
+
+               int box_x = 20; // LYX_PAPER_MARGIN;
+               box_x += font.textWidth(" wide-tab ", 10);
+
+               int screen_first = screen->first;
+
+               if (x < box_x
+                   && y + screen_first > text->cursor.y -
+                   text->cursor.row->baseline
+                   && y + screen_first < text->cursor.y -
+                   text->cursor.row->baseline
+                   + font.maxAscent() * 1.2 + font.maxDescent() * 1.2) {
+                       toggleFloat();
+                       selection_possible = false;
+                       return;
+               }
+       }
+
+       // Maybe we want to edit a bibitem ale970302
+#ifdef USE_PAINTER
+       if (text->cursor.par->bibkey && x < 20 + 
+           bibitemMaxWidth(painter(),
+                           textclasslist
+                           .TextClass(buffer_->
+                                      params.textclass).defaultfont())) {
+               text->cursor.par->bibkey->Edit(0, 0);
+       }
+#else
+       if (text->cursor.par->bibkey && x < 20 + 
+           bibitemMaxWidth(textclasslist
+                           .TextClass(buffer_->
+                                      params.textclass).defaultfont())) {
+               text->cursor.par->bibkey->Edit(0, 0);
+       }
+#endif
+
+       return;
+}
+#else
 int BufferView::WorkAreaButtonRelease(FL_OBJECT * ob, Window ,
                                      int /*w*/, int /*h*/,
                                      XEvent * ev, void * /*d*/)
@@ -1198,13 +1827,81 @@ int BufferView::WorkAreaButtonRelease(FL_OBJECT * ob, Window ,
 
        return 0;
 }
-
+#endif
 
 /* 
  * Returns an inset if inset was hit. 0 otherwise.
  * If hit, the coordinates are changed relative to the inset. 
  * Otherwise coordinates are not changed, and false is returned.
  */
+#ifdef USE_PAINTER
+Inset * BufferView::checkInsetHit(int & x, int & y)
+{
+       if (!getScreen())
+               return 0;
+  
+       int y_tmp = y + getScreen()->first;
+  
+       LyXCursor & cursor = text->cursor;
+       LyXDirection direction = text->real_current_font.getFontDirection();
+
+       if (cursor.pos < cursor.par->Last()
+           && cursor.par->GetChar(cursor.pos) == LyXParagraph::META_INSET
+           && cursor.par->GetInset(cursor.pos)
+           && cursor.par->GetInset(cursor.pos)->Editable()) {
+
+               // Check whether the inset really was hit
+               Inset * tmpinset = cursor.par->GetInset(cursor.pos);
+               LyXFont font = text->GetFont(cursor.par, cursor.pos);
+               int start_x, end_x;
+               if (direction == LYX_DIR_LEFT_TO_RIGHT) {
+                       start_x = cursor.x;
+                       end_x = cursor.x + tmpinset->width(painter(), font);
+               } else {
+                       start_x = cursor.x - tmpinset->width(painter(), font);
+                       end_x = cursor.x;
+               }
+
+               if (x > start_x && x < end_x
+                   && y_tmp > cursor.y - tmpinset->ascent(painter(), font)
+                   && y_tmp < cursor.y + tmpinset->descent(painter(), font)) {
+                       x = x - start_x;
+                       // The origin of an inset is on the baseline
+                       y = y_tmp - (cursor.y); 
+                       return tmpinset;
+               }
+       }
+
+       if (cursor.pos - 1 >= 0
+                  && cursor.par->GetChar(cursor.pos - 1) == LyXParagraph::META_INSET
+                  && cursor.par->GetInset(cursor.pos - 1)
+                  && cursor.par->GetInset(cursor.pos - 1)->Editable()) {
+               text->CursorLeft();
+               Inset * tmpinset = cursor.par->GetInset(cursor.pos);
+               LyXFont font = text->GetFont(cursor.par, cursor.pos);
+               int start_x, end_x;
+               if (direction == LYX_DIR_LEFT_TO_RIGHT) {
+                       start_x = cursor.x;
+                       end_x = cursor.x + tmpinset->width(painter(), font);
+               } else {
+                       start_x = cursor.x - tmpinset->width(painter(), font);
+                       end_x = cursor.x;
+               }
+               if (x > start_x && x < end_x
+                   && y_tmp > cursor.y - tmpinset->ascent(painter(), font)
+                   && y_tmp < cursor.y + tmpinset->descent(painter(), font)) {
+                       x = x - start_x;
+                       // The origin of an inset is on the baseline
+                       y = y_tmp - (cursor.y); 
+                       return tmpinset;
+               } else {
+                       text->CursorRight();
+                       return 0;
+               }
+       }
+       return 0;
+}
+#else
 Inset * BufferView::checkInsetHit(int & x, int & y)
 {
        if (!getScreen())
@@ -1271,8 +1968,65 @@ Inset * BufferView::checkInsetHit(int & x, int & y)
        }
        return 0;
 }
+#endif
+
+#ifdef NEW_WA
+void BufferView::workAreaExpose()
+{
+       // this is a hack to ensure that we only call this through
+       // BufferView::redraw().
+       //if (!lgb_hack) {
+       //      redraw();
+       //}
+       
+       static int work_area_width = -1;
+       static int work_area_height = -1;
+
+       bool widthChange = workarea->workWidth() != work_area_width;
+       bool heightChange = workarea->height() != work_area_height;
+
+       // update from work area
+       work_area_width = workarea->workWidth();
+       work_area_height = workarea->height();
+       if (buffer_ != 0) {
+               if (widthChange) {
+                       // All buffers need a resize
+                       bufferlist.resize();
+
+                       // Remove all texts from the textcache
+                       // This is not _really_ what we want to do. What
+                       // we really want to do is to delete in textcache
+                       // that does not have a BufferView with matching
+                       // width, but as long as we have only one BufferView
+                       // deleting all gives the same result.
+                       if (lyxerr.debugging())
+                               textcache.show(lyxerr, "Expose delete all");
+                       textcache.clear();
+               } else if (heightChange) {
+                       // Rebuild image of current screen
+                       updateScreen();
+                       // fitCursor() ensures we don't jump back
+                       // to the start of the document on vertical
+                       // resize
+                       fitCursor();
+
+                       // The main window size has changed, repaint most stuff
+                       redraw();
+                       // ...including the minibuffer
+                       owner_->getMiniBuffer()->Init();
 
+               } else if (screen) screen->Redraw();
+       } else {
+               // Grey box when we don't have a buffer
+               workarea->greyOut();
+       }
 
+       // always make sure that the scrollbar is sane.
+       updateScrollbar();
+       owner_->updateLayoutChoice();
+       return;
+}
+#else
 int BufferView::workAreaExpose()
 {
        if (!work_area || !work_area->form->visible) 
@@ -1333,6 +2087,7 @@ int BufferView::workAreaExpose()
        owner_->updateLayoutChoice();
        return 1;
 }
+#endif
 
 
 // Callback for cursor timer
@@ -1440,6 +2195,83 @@ void BufferView::CursorToggleCB(FL_OBJECT * ob, long)
 }
 
 
+#ifdef NEW_WA
+static
+string fromClipboard(Window win, XEvent * event)
+{
+       string strret;
+       if (event->xselection.type == XA_STRING
+           && event->xselection.property) {
+               Atom tmpatom;
+               unsigned long ul1;
+               unsigned long ul2;
+               unsigned char * uc = 0;
+               int tmpint;
+               if (XGetWindowProperty(
+                       event->xselection.display,  // display
+                       win,                        // w
+                       event->xselection.property, // property
+                       0,                          // long_offset      
+                       0,                          // logn_length      
+                       False,                      // delete   
+                       XA_STRING,                  // req_type 
+                       &tmpatom,                   // actual_type_return
+                       &tmpint,                    // actual_format_return
+                       &ul1,
+                       &ul2,
+                       &uc                         // prop_return      
+                       ) != Success) {
+                       return strret;
+               }
+               if (uc) {
+                       free(uc);
+                       uc = 0;
+               }
+               if (XGetWindowProperty(
+                       event->xselection.display,             // display
+                       win,                        // w
+                       event->xselection.property, // property
+                       0,                          // long_offset
+                       ul2/4+1,                    // long_length
+                       True,                       // delete
+                       XA_STRING,                  // req_type
+                       &tmpatom,                   // actual_type_return
+                       &tmpint,                    // actual_format_return
+                       &ul1,                       // nitems_return
+                       &ul2,                       // bytes_after_return
+                       &uc                         // prop_return */
+                       ) != Success) {
+                       return strret;
+               }
+               if (uc) {
+                       strret = reinterpret_cast<char*>(uc);
+                       free(uc); // yes free!
+                       uc = 0;
+               }
+       }
+       return strret;
+}
+
+
+void BufferView::WorkAreaSelectionNotify(Window win, XEvent * event)
+{
+       if (buffer_ == 0) return;
+
+       screen->HideCursor();
+       beforeChange();
+       string clb = fromClipboard(win, event);
+       if (!clb.empty()) {
+               if (!ascii_type)
+                       text->InsertStringA(clb.c_str());
+               else
+                       text->InsertStringB(clb.c_str());
+
+               update(1);
+               
+       }
+}
+
+#else
 int BufferView::WorkAreaSelectionNotify(FL_OBJECT *, Window win,
                                        int /*w*/, int /*h*/,
                                        XEvent * event, void */*d*/)
@@ -1513,8 +2345,29 @@ int BufferView::WorkAreaSelectionNotify(FL_OBJECT *, Window win,
        }
        return 0;
 }
+#endif
 
 
+#ifdef NEW_WA
+void BufferView::cursorPrevious()
+{
+       if (!text->cursor.row->previous) return;
+       
+       long y = getScreen()->first;
+       Row * cursorrow = text->cursor.row;
+       text->SetCursorFromCoordinates(text->cursor.x_fix, y);
+       text->FinishUndo();
+       // This is to allow jumping over large insets
+       if ((cursorrow == text->cursor.row))
+               text->CursorUp();
+       
+       if (text->cursor.row->height < workarea->height())
+               getScreen()->Draw(text->cursor.y
+                                 - text->cursor.row->baseline
+                                 + text->cursor.row->height
+                                 - workarea->height() + 1 );
+}
+#else
 void BufferView::cursorPrevious()
 {
        if (!text->cursor.row->previous) return;
@@ -1533,8 +2386,29 @@ void BufferView::cursorPrevious()
                                  + text->cursor.row->height
                                  - work_area->h +1 );
 }
+#endif
 
 
+#ifdef NEW_WA
+void BufferView::cursorNext()
+{
+       if (!text->cursor.row->next) return;
+       
+       long y = getScreen()->first;
+       text->GetRowNearY(y);
+       Row * cursorrow = text->cursor.row;
+       text->SetCursorFromCoordinates(text->cursor.x_fix, y
+                                      + workarea->height());
+       text->FinishUndo();
+       // This is to allow jumping over large insets
+       if ((cursorrow == text->cursor.row))
+               text->CursorDown();
+       
+       if (text->cursor.row->height < workarea->height())
+               getScreen()->Draw(text->cursor.y
+                                 - text->cursor.row->baseline);
+}
+#else
 void BufferView::cursorNext()
 {
        if (!text->cursor.row->next) return;
@@ -1552,6 +2426,7 @@ void BufferView::cursorNext()
                getScreen()->Draw(text->cursor.y
                                  - text->cursor.row->baseline);
 }
+#endif
 
 
 bool BufferView::available() const
@@ -1692,3 +2567,21 @@ void BufferView::insetUnlock()
                inset_slept = false;
        }
 }
+
+
+bool BufferView::focus() const
+{
+       return workarea->hasFocus();
+}
+
+
+void BufferView::focus(bool f)
+{
+       if (f) workarea->setFocus();
+}
+
+
+bool BufferView::active() const
+{
+       return workarea->active();
+}
index fee341f300a5b8b4b22f5888b0881c3c850448df..abbc288d0d8d99e828d4e1adf1ca1f461db71647 100644 (file)
 #include "LaTeX.h"
 #include "undo.h"
 
+#define NEW_WA 1
+
 class LyXView;
 class Buffer;
 class LyXScreen;
 class Inset;
 class LyXText;
+class WorkArea;
 
 ///
 class BufferView {
@@ -36,10 +39,23 @@ public:
        ~BufferView();
        ///
        Buffer * buffer() const { return buffer_; }
+#ifdef USE_PAINTER
+       ///
+       Painter & painter();
+#endif
+#ifdef NEW_WA
+       ///
+       WorkArea * getWorkArea() { return workarea; }
+#else
        ///
        FL_OBJECT * getWorkArea() { return work_area; }
+#endif
        ///
        void buffer(Buffer * b);
+#ifdef NEW_WA
+       ///
+       void resize(int, int, int, int);
+#endif
        ///
        void resize();
        ///
@@ -175,10 +191,25 @@ public:
        ///
        void lockedInsetStoreUndo(Undo::undo_kind kind);
 private:
+       friend class WorkArea;
+       
        /// Update pixmap of screen
        void updateScreen();
+#ifdef NEW_WA
+       ///
+       void workAreaExpose();
+       ///
+       void ScrollUpOnePage();
+       ///
+       void ScrollDownOnePage();
+#else
        ///
        int workAreaExpose();
+       ///
+       void ScrollUpOnePage(long /*time*/);
+       ///
+       void ScrollDownOnePage(long /*time*/);
+#endif
        ///
        void create_view(int, int, int, int);
        ///
@@ -187,20 +218,31 @@ private:
        int ScrollUp(long time);
        ///
        int ScrollDown(long time);
-       ///
-       void ScrollUpOnePage(long /*time*/);
-       ///
-       void ScrollDownOnePage(long /*time*/);
 
 public:
+
+#ifdef NEW_WA
+       ///
+       bool focus() const;
+       ///
+       void focus(bool);
+       ///
+       bool active() const;
+       /// A callback for the up arrow in the scrollbar.
+       void UpCB(long time, int button);
+       /// A callback for the slider in the scrollbar.
+       void ScrollCB(double);
+       /// A callback for the down arrow in the scrollbar.
+       void DownCB(long time, int button);
+#else
        /// A callback for the up arrow in the scrollbar.
        static void UpCB(FL_OBJECT * ob, long);
-
        /// A callback for the slider in the scrollbar.
        static void ScrollCB(FL_OBJECT * ob, long);
 
        /// A callback for the down arrow in the scrollbar.
        static void DownCB(FL_OBJECT * ob, long);
+#endif
 
        ///
        static void CursorToggleCB(FL_OBJECT * ob, long);
@@ -213,16 +255,22 @@ public:
        void SetState();
 
 private:
+#ifdef NEW_WA
+       ///
+       void WorkAreaMotionNotify(int x, int y, unsigned int state);
+       ///
+       void WorkAreaButtonPress(int x, int y, unsigned int button);
+       ///
+       void WorkAreaButtonRelease(int x, int y, unsigned int button);
+       ///
+       void WorkAreaSelectionNotify(Window win, XEvent * event);
+#else
        ///
        int WorkAreaMotionNotify(FL_OBJECT * ob,
                                 Window win,
                                 int w, int h,
                                 XEvent * ev, void * d);
        ///
-       int WorkAreaSelectionNotify(FL_OBJECT *, Window win,
-                                   int /*w*/, int /*h*/,
-                                   XEvent * event, void * /*d*/);
-       ///
        int WorkAreaButtonPress(FL_OBJECT * ob,
                                Window win,
                                int w, int h,
@@ -233,6 +281,11 @@ private:
                                  int w, int h,
                                  XEvent * ev, void * d);
        ///
+       int WorkAreaSelectionNotify(FL_OBJECT *, Window win,
+                                   int /*w*/, int /*h*/,
+                                   XEvent * event, void * /*d*/);
+#endif
+       ///
        LyXView * owner_;
        ///
        Buffer * buffer_;
@@ -244,22 +297,28 @@ private:
        bool lyx_focus;
        ///
        bool work_area_focus;
+#ifndef NEW_WA
        ///
        FL_OBJECT * work_area;
        ///
-       FL_OBJECT * figinset_canvas;
-       ///
        FL_OBJECT * scrollbar;
        ///
        FL_OBJECT * button_down;
        ///
        FL_OBJECT * button_up;
+#endif
+       ///
+       FL_OBJECT * figinset_canvas;
        ///
        FL_OBJECT * timer_cursor;
         ///
         BackStack backstack;
        ///
        int last_click_x, last_click_y;
+#ifdef NEW_WA
+       ///
+       WorkArea * workarea;
+#endif
 };
 
 #endif
index befabfb29071151a47f56b3af9919ac77834f337..bc93386963268633cfe06efddfab26c6af90fc9d 100644 (file)
@@ -240,7 +240,11 @@ XFontStruct * FontLoader::doLoad(LyXFont::FONT_FAMILY family,
                        f.setUnderbar(LyXFont::INHERIT);
                        f.setNoun(LyXFont::INHERIT);
                        f.setLatex(LyXFont::INHERIT);
+#ifdef USE_PAINTER
+                       f.setColor(LColor::inherit);
+#else
                        f.setColor(LyXFont::INHERIT_COLOR);
+#endif
                        lyxerr << "Font '" << f.stateText() 
                               << "' matched by\n" << font << endl;
                }
diff --git a/src/LColor.C b/src/LColor.C
new file mode 100644 (file)
index 0000000..7dc85d2
--- /dev/null
@@ -0,0 +1,176 @@
+// -*- C++ -*-
+/* This file is part of
+ * ======================================================
+ * 
+ *           LyX, The Document Processor
+ *      
+ *         Copyright 1998-2000 The LyX Team
+ *
+ *======================================================*/
+
+#include <config.h>
+
+#ifdef USE_PAINTER
+
+#ifdef __GNUG__
+#pragma implementation
+#endif
+
+#include <X11/Xlib.h>
+
+#include "debug.h"
+#include "LColor.h"
+#include "support/LAssert.h"
+#include "gettext.h"
+#include "support/lstrings.h"
+
+
+void LColor::fill(LColor::color col, string const & gui,
+                 string const & latex, string const & x11,
+                 string const & lyx) {
+       information in;
+       in.guiname = gui;
+       in.latexname = latex;
+       in.x11name = x11;
+       in.lyxname = lyx;
+
+       infotab[col] = in;
+}
+
+
+LColor::LColor()
+{
+       //  LColor::color, gui, latex, x11, lyx
+       fill(none, _("none"), "none", "black", "none");
+       fill(black, _("black"), "black", "black", "black");
+       fill(white, _("white"), "white", "white", "white");
+       fill(red, _("red"), "red", "red", "red");
+       fill(green, _("green"), "green", "green", "green");
+       fill(blue, _("blue"), "blue", "blue", "blue");
+       fill(cyan, _("cyan"), "cyan", "cyan", "cyan");
+       fill(magenta, _("magenta"), "magenta", "magenta", "magenta");
+       fill(yellow, _("yellow"), "yellow", "yellow", "yellow");
+       fill(background, _("background"), "background", "linen", "background");
+       fill(foreground, _("foreground"), "foreground", "black", "foreground");
+       fill(selection, _("selection"), "selection", "LightBlue", "selection");
+       fill(latex, _("latex"), "latex", "DarkRed", "latex");
+       fill(floats, _("floats"), "floats", "red", "floats");
+       fill(note, _("note"), "note", "black", "note");
+       fill(notebg, _("note background"), "notebg", "yellow", "notebg");
+       fill(noteframe, _("note frame"), "noteframe", "black", "noteframe");
+       fill(command, _("command-inset"), "command", "black", "command");
+       fill(commandbg, _("command-inset background"), "commandbg", "grey50", "commandbg");
+       fill(commandframe, _("inset frame"), "commandframe", "black", "commandframe");
+       fill(accent, _("accent"), "accent", "black", "accent");
+       fill(accentbg, _("accent background"), "accentbg", "offwhite", "accentbg");
+       fill(accentframe, _("accent frame"), "accentframe", "linen", "accentframe");
+       fill(minipageline, _("minipage line"), "minipageline", "violet", "minipageline");
+       fill(special, _("special char"), "special", "RoyalBlue", "special");
+       fill(math, _("math"), "math", "DarkBlue", "math");
+       fill(mathbg, _("math background"), "mathbg", "AntiqueWhite", "mathbg");
+       fill(mathframe, _("math frame"), "mathframe", "Magenta", "mathframe");
+       fill(mathcursor, _("math cursor"), "mathcursor", "black", "mathcursor");
+       fill(mathline, _("math line"), "mathline", "Blue", "mathline");
+       fill(footnote, _("footnote"), "footnote", "DarkRed", "footnote");
+       fill(footnotebg, _("footnote background"), "footnotebg", "grey40", "footnotebg");
+       fill(footnoteframe, _("footnote frame"), "footnoteframe", "IndianRed", "footnoteframe");
+       fill(ert, _("ert"), "ert", "DarkRed", "ert");
+       fill(inset, _("inset"), "inset", "black", "inset");
+       fill(insetbg, _("inset background"), "insetbg", "grey40", "insetbg");
+       fill(insetframe, _("inset frame"), "insetframe", "IndianRed", "insetframe");
+       fill(error, _("error"), "error", "Red", "error");
+       fill(eolmarker, _("end-of-line marker"), "eolmarker", "Brown", "eolmarker");
+       fill(appendixline, _("appendix line"), "appendixline", "Brown", "appendixline");
+       fill(vfillline, _("vfill line"), "vfillline", "Brown", "vfillline");
+       fill(topline, _("top/bottom line"), "topline", "Brown", "topline");
+       fill(tableline, _("table line"), "tableline", "black", "tableline");
+       fill(bottomarea, _("bottom area"), "bottomarea", "grey40", "bottomarea");
+       fill(pagebreak, _("page break"), "pagebreak", "RoyalBlue", "pagebreak");
+       fill(top, _("top of button"), "top", "grey80", "top");
+       fill(bottom, _("bottom of button"), "bottom", "grey40", "bottom");
+       fill(left, _("left of button"), "left", "grey80", "left");
+       fill(right, _("right of button"), "right", "grey40", "right");
+       fill(buttonbg, _("button background"), "buttonbg", "grey60", "buttonbg");
+       fill(inherit, _("inherit"), "inherit", "black", "inherit");
+       fill(ignore, _("ignore"), "ignore", "black", "ignore");
+}
+
+
+string LColor::getGUIName(LColor::color c) const
+{
+       InfoTab::const_iterator ici = infotab.find(c);
+       if (ici != infotab.end())
+               return (*ici).second.guiname;
+
+       return "none";
+}
+
+
+string LColor::getX11Name(LColor::color c) const
+{
+       InfoTab::const_iterator ici = infotab.find(c);
+       if (ici != infotab.end()) 
+               return (*ici).second.x11name;
+
+       lyxerr << "LyX internal error: Missing color"
+               " entry in LColor.C for " << int(c) << '\n';
+       lyxerr << "Using black.\n";
+       return "black";
+}
+
+
+string LColor::getLaTeXName(LColor::color c) const
+{
+       InfoTab::const_iterator ici = infotab.find(c);
+       if (ici != infotab.end())
+               return (*ici).second.latexname;
+       return "black";
+}
+
+
+string LColor::getLyXName(LColor::color c) const
+{
+       InfoTab::const_iterator ici = infotab.find(c);
+       if (ici != infotab.end())
+               return (*ici).second.lyxname;
+       return "black";
+}
+
+
+void LColor::setColor(LColor::color col, string const & x11name)
+{
+       InfoTab::iterator iti = infotab.find(col);
+       if (iti != infotab.end()) {
+               (*iti).second.x11name = x11name;
+               return;
+       }
+       lyxerr << "LyX internal error: color and such.\n";
+       Assert(false);
+}
+
+
+LColor::color LColor::getFromGUIName(string const & guiname) const
+{
+       InfoTab::const_iterator ici = infotab.begin();
+       for (; ici != infotab.end(); ++ici) {
+               if (!compare_no_case((*ici).second.guiname, guiname))
+                       return (*ici).first;
+       }
+       return LColor::ignore;
+}
+
+
+LColor::color LColor::getFromLyXName(string const & lyxname) const
+{
+       InfoTab::const_iterator ici = infotab.begin();
+       for (; ici != infotab.end(); ++ici) {
+               if (!compare_no_case((*ici).second.lyxname, lyxname))
+                       return (*ici).first;
+       }
+       return LColor::ignore;
+}
+
+// The evil global LColor instance
+LColor lcolor;
+
+#endif
diff --git a/src/LColor.h b/src/LColor.h
new file mode 100644 (file)
index 0000000..848a29c
--- /dev/null
@@ -0,0 +1,208 @@
+// -*- C++ -*-
+/* This file is part of
+ * ======================================================
+ * 
+ *           LyX, The Document Processor
+ *      
+ *         Copyright 1998-2000 The LyX Team
+ *
+ *======================================================*/
+
+#ifdef USE_PAINTER
+
+#ifndef LCOLOR_H
+#define LCOLOR_H
+
+#ifdef __GNUG__
+#pragma interface
+#endif
+
+#include <map>
+
+#include "LString.h"
+
+/**
+  This is a stateless class. 
+
+  It has one basic purposes:
+  To serve as a color-namespace container (the Color enum).
+  
+  A color can be one of the following kinds:
+
+  - A real, predefined color, such as black, white, red or green.
+  - A logical color, such as no color, inherit, math
+
+  */
+
+class LColor {
+public:
+       /// Names of colors, including all logical colors
+       enum color {
+               /// No particular color---clear or default
+               none,
+               /// The different text colors
+               black,
+               ///
+               white,
+               ///
+               red,
+               ///
+               green,
+               ///
+               blue,
+               ///
+               cyan,
+               ///
+               magenta,
+               ///
+               yellow,
+
+               /// Needed interface colors
+
+               /// Background color
+               background,
+               /// Foreground color
+               foreground,
+               /// Background color of selected text
+               selection,
+               /// Text color in LaTeX mode
+               latex,
+               /// Titles color of floats
+               floats,
+
+               /// Text color for notes
+               note,
+               /// Background color of notes
+               notebg,
+               /// Frame color for notes
+               noteframe,
+
+
+               /// Text color for command insets
+               command,
+               /// Background color for command insets
+               commandbg,
+               /// Frame color for command insets
+               commandframe,
+
+               /// Text color for accents we can't handle nicely
+               accent,
+               ///
+               accentbg,
+               ///
+               accentframe,
+
+               /// Minipage line color
+               minipageline,
+
+               /// Special chars text color
+               special,
+
+               /// Math inset text color
+               math,
+               /// Math inset background color
+               mathbg,
+               /// Math inset frame color
+               mathframe,
+               /// Math cursor color
+               mathcursor,
+               /// Math line color
+               mathline,
+
+               /// Footnote marker text
+               footnote,
+               /// Footnote marker background color
+               footnotebg,
+               /// Footnote line color
+               footnoteframe,
+
+               /// ERT marker text
+               ert,
+               
+               /// Text color for inset marker
+               inset,
+               /// Inset marker background color
+               insetbg,
+               /// Inset marker frame color
+               insetframe,
+
+               /// Error box text color
+               error,
+               /// EOL marker color
+               eolmarker,
+               /// Appendix line color
+               appendixline,
+               /// VFill line color
+               vfillline,
+               /// Top and bottom line color
+               topline,
+               /// Table line color
+               tableline,
+               /// Bottom area color
+               bottomarea,
+               /// Page break color
+               pagebreak,
+
+               /// Color used for top of boxes
+               top,
+               /// Color used for bottom of boxes
+               bottom,
+               /// Color used for left side of boxes
+               left,
+               /// Color used for right side of boxes
+               right,
+               /// Color used for bottom background
+               buttonbg,
+
+               /// Logical attributes
+
+               /// Color is inherited
+               inherit,
+               /// For ignoring updates of a color
+               ignore
+       };
+
+       ///
+       LColor();
+       ///
+       void setColor(LColor::color col, string const & x11name);
+       /// Get GUI name of color
+       string getGUIName(LColor::color c) const;
+
+       /// Get X11 name of color
+       string getX11Name(LColor::color c) const;
+
+       /// Get LaTeX name of color
+       string getLaTeXName(LColor::color c) const;
+
+       /// Get LyX name of color
+       string getLyXName(LColor::color c) const;
+       ///
+       LColor::color getFromGUIName(string const & guiname) const;
+       ///
+       LColor::color getFromLyXName(string const & lyxname) const;
+private:
+       ///
+       struct information {
+               string guiname;
+               string latexname;
+               string x11name;
+               string lyxname;
+       };
+
+       ///
+       void fill(LColor::color col, string const & gui,
+                 string const & latex, string const & x11,
+                 string const & lyx);
+
+       ///
+       typedef map<LColor::color, information, less<LColor::color> > InfoTab;
+
+       InfoTab infotab;
+};
+
+extern LColor lcolor;
+
+#endif
+
+#endif
index 148ff63ddabcd97d8c02116f1ba6309445894824..e083bb851f668ae72c20fad19c445ec61b285575 100644 (file)
@@ -351,8 +351,14 @@ int LyXView::KeyPressMask_raw_callback(FL_FORM * fl, void * xev)
        // also KeyRelease-events are passed through:-(
        // [It seems that XForms puts them in pairs... (JMarc)]
        if (static_cast<XEvent*>(xev)->type == KeyPress
+#ifdef NEW_WA
+           && view->bufferview->focus()
+           && view->bufferview->active())
+#else
            && view->bufferview->getWorkArea()->focus
-           && view->bufferview->getWorkArea()->active) {
+           && view->bufferview->getWorkArea()->active)
+#endif
+               {
 #ifdef USE_XSYNC
                last_time_pressed = xke->time;
                last_key_pressed = xke->keycode;
@@ -363,8 +369,14 @@ int LyXView::KeyPressMask_raw_callback(FL_FORM * fl, void * xev)
        }
 #ifdef USE_XSYNC
        else if (static_cast<XEvent*>(xev)->type == KeyRelease
+#ifdef NEW_WA
+                && view->bufferview->focus()
+                && view->bufferview->active())
+#else
                   && view->bufferview->getWorkArea()->focus
-                  && view->bufferview->getWorkArea()->active) {
+                  && view->bufferview->getWorkArea()->active)
+#endif
+{
                last_time_released = xke->time;
                last_key_released = xke->keycode;
                last_state_released = xke->state;
index b4f1f1c1141f20da9bea7a95057623bedc11d442..1e9d043a95f3d10f22efafe649557fa491e2a871 100644 (file)
@@ -28,6 +28,8 @@ lyx_SOURCES = \
        ImportLaTeX.h \
        ImportNoweb.C \
        ImportNoweb.h \
+       LColor.C \
+       LColor.h \
        LString.h \
        LaTeX.C \
        LaTeX.h \
@@ -42,6 +44,10 @@ lyx_SOURCES = \
        LyXView.C \
        LyXView.h \
        Makefile.in \
+       Painter.C \
+       Painter.h \
+       PainterBase.C \
+       PainterBase.h \
        PaperLayout.C \
        ParagraphExtra.C \
        Spacing.C \
@@ -49,6 +55,8 @@ lyx_SOURCES = \
        TableLayout.C \
        TextCache.C \
        TextCache.h \
+       WorkArea.C \
+       WorkArea.h \
        bibforms.h \
        bmtable.c \
        bmtable.h \
diff --git a/src/Painter.C b/src/Painter.C
new file mode 100644 (file)
index 0000000..d052f05
--- /dev/null
@@ -0,0 +1,456 @@
+// -*- C++ -*-
+/* This file is part of
+ * ======================================================
+ * 
+ *           LyX, The Document Processor
+ *      
+ *         Copyright 1998-2000 The LyX Team
+ *
+ *======================================================*/
+
+#include <config.h>
+
+#ifdef USE_PAINTER
+
+#ifdef __GNUG__
+#pragma implementation
+#endif
+
+#include <cmath>
+
+#ifdef USE_STL_MEMORY
+#include <memory>
+#endif
+
+#include FORMS_H_LOCATION
+#include "Painter.h"
+#include "LString.h"
+#include "debug.h"
+#include "lyxfont.h"
+#include "support/LAssert.h"
+#include "support/lstrings.h"
+
+Painter::Painter(WorkArea & wa)
+       : PainterBase(wa)
+{
+       colormap = fl_state[fl_get_vclass()].colormap;
+       // Clear the GC cache
+       for (int i=0; i <= LColor::ignore; ++i) {
+               colorGCcache[i] = 0;
+       }
+}
+
+
+Painter::~Painter() {
+       // Release all the registered GCs
+       for (int i=0; i <= LColor::ignore; ++i) {
+               if (colorGCcache[i] != 0) {
+                       XFreeGC(display, colorGCcache[i]);
+               }
+       }
+       // Iterate over the line cache and Free the GCs
+       LineGCCache::iterator lit = lineGCcache.begin();
+       for (; lit != lineGCcache.end(); ++lit) {
+               XFreeGC(display, (*lit).second);
+       }
+}
+
+
+/* Basic drawing routines */
+
+extern bool Lgb_bug_find_hack;
+
+Painter & Painter::point(int x, int y, LColor::color c)
+{
+       if (lyxerr.debugging()) {
+               if (!Lgb_bug_find_hack)
+                       lyxerr << "point not called from "
+                               "workarea::workhandler\n";
+               lyxerr.debug() << "Painter drawable: " << drawable << endl;
+       }
+       
+       XDrawPoint(display, drawable, getGCForeground(c), x, y);
+       return *this;
+}
+
+
+Painter & Painter::line(int x1, int y1, int x2, int y2,
+                       LColor::color col,
+                       enum line_style ls,
+                       enum line_width lw)
+{
+       if (lyxerr.debugging()) {
+               if (!Lgb_bug_find_hack)
+                       lyxerr << "line not called from "
+                               "workarea::workhandler\n";
+               lyxerr.debug() << "Painter drawable: " << drawable << endl;
+       }
+       
+       XDrawLine(display, drawable, 
+                 getGCLinepars(ls, lw, col), x1, y1, x2, y2);
+       return *this;
+}
+
+
+Painter & Painter::lines(int const * xp, int const * yp, int np,
+                       LColor::color col,
+                       enum line_style ls,
+                       enum line_width lw)
+{
+       if (lyxerr.debugging()) {
+               if (!Lgb_bug_find_hack)
+                       lyxerr << "lines not called from "
+                               "workarea::workhandler\n";
+               lyxerr.debug() << "Painter drawable: " << drawable << endl;
+       }
+       
+#ifndef HAVE_AUTO_PTR
+       XPoint * points = new XPoint[np];
+#else
+       auto_ptr<XPoint> points(new Xpoint[np]);
+#endif
+       for (int i=0; i<np; ++i) {
+               points[i].x = xp[i];
+               points[i].y = yp[i];
+       }
+
+        XDrawLines(display, drawable, getGCLinepars(ls, lw, col), 
+                  points, np, CoordModeOrigin);
+
+#ifndef HAVE_AUTO_PTR
+       delete[] points;
+#endif 
+       return *this;
+}      
+
+
+Painter & Painter::rectangle(int x, int y, int w, int h,
+                       LColor::color col,
+                       enum line_style ls,
+                       enum line_width lw)
+{
+       if (lyxerr.debugging()) {
+               if (!Lgb_bug_find_hack)
+                       lyxerr << "rectangle not called from "
+                               "workarea::workhandler\n";
+               lyxerr << "Painter drawable: " << drawable << endl;
+       }
+       
+       XDrawRectangle(display, drawable, getGCLinepars(ls, lw, col), 
+                      x, y, w, h);
+       return *this;
+}
+
+
+Painter & Painter::fillRectangle(int x, int y, int w, int h,
+                                LColor::color col)
+{
+       if (lyxerr.debugging()) {
+               if (!Lgb_bug_find_hack)
+                       lyxerr << "fillrectangle not called from "
+                               "workarea::workhandler\n";
+               lyxerr << "Painter drawable: " << drawable << endl;
+       }
+       
+       XFillRectangle(display, drawable, getGCForeground(col), x, y, w, h);
+       return *this;
+}
+
+
+Painter & Painter::fillPolygon(int const * xp, int const * yp, int np,
+                              LColor::color col)
+{
+       if (lyxerr.debugging()) {
+               if (!Lgb_bug_find_hack)
+                       lyxerr <<"fillpolygon not called from "
+                               "workarea::workhandler\n";
+               lyxerr << "Painter drawable: " << drawable << endl;
+       }
+       
+#ifndef HAVE_AUTO_PTR
+       XPoint * points = new XPoint[np];
+#else
+       auto_ptr<XPoint> points(new XPoint[np]);
+#endif
+       for (int i=0; i<np; ++i) {
+               points[i].x = xp[i];
+               points[i].y = yp[i];
+       }
+
+       XFillPolygon(display, drawable, getGCForeground(col), points, np, 
+                    Nonconvex, CoordModeOrigin);
+#ifndef HAVE_AUTO_PTR
+       delete[] points;
+#endif 
+       return *this;
+}      
+
+
+Painter & Painter::arc(int x, int y,
+                 unsigned int w, unsigned int h,
+                 int a1, int a2, LColor::color col)
+{
+       if (lyxerr.debugging()) {
+               if (!Lgb_bug_find_hack)
+                       lyxerr << "arc not called from "
+                               "workarea::workhandler\n";
+               lyxerr << "Painter drawable: " << drawable << endl;
+       }
+       
+        XDrawArc(display, drawable, getGCForeground(col),
+                 x, y, w, h, a1, a2);
+       return *this;
+}     
+
+
+/// Draw lines from x1,y1 to x2,y2. They are arrays
+Painter & Painter::segments(int const * x1, int const * y1, 
+                           int const * x2, int const * y2, int ns,
+                           LColor::color col,
+                           enum line_style ls, enum line_width lw)
+{
+       if (lyxerr.debugging()) {
+               if (!Lgb_bug_find_hack)
+                       lyxerr << "segments not called from "
+                               "workarea::workhandler\n";
+               lyxerr << "Painter drawable: " << drawable << endl;
+       }
+       
+#ifndef HAVE_AUTO_PTR
+       XSegment * s= new XSegment[ns];
+#else
+       auto_ptr<XSegment> s(new XSegment[ns]);
+#endif
+       for (int i=0; i<ns; ++i) {
+               s[i].x1 = x1[i];
+               s[i].y1 = y1[i];
+               s[i].x2 = x2[i];
+               s[i].y2 = y2[i];
+       }
+       XDrawSegments(display, drawable, getGCLinepars(ls, lw, col), s, ns);
+
+#ifndef HAVE_AUTO_PTR
+       delete [] s;
+#endif
+       return *this;
+}
+
+
+Painter & Painter::pixmap(int x, int y, Pixmap bitmap)
+{
+       if (lyxerr.debugging()) {
+               if (!Lgb_bug_find_hack)
+                       lyxerr << "workAreaExpose not called from "
+                               "workarea::workhandler\n";
+               lyxerr << "Painter drawable: " << drawable << endl;
+       }
+       
+       XGCValues val;
+       val.function = GXcopy;
+       GC gc = XCreateGC(display, drawable,
+                         GCFunction, &val);
+        int w = 0, h = 0;
+       XCopyArea(display, bitmap, drawable, gc,
+                 0, 0, w, h, x, y);
+       XFreeGC(display, gc);
+       return *this;
+}
+
+
+Painter & Painter::text(int x, int y, string const & s, LyXFont const & f)
+{
+       if (lyxerr.debugging()) {
+               if (!Lgb_bug_find_hack)
+                       lyxerr << "text not called from "
+                               "workarea::workhandler\n";
+               lyxerr << "Painter drawable: " << drawable << endl;
+       }
+       
+       GC gc = getGCForeground(f.realColor());
+       XSetFont(display, gc, f.getFontID());
+       XDrawString(display, drawable, gc, x, y, s.c_str(), s.length());
+       underline(f, x, y, this->width(s, f));
+       return *this;
+}
+
+
+Painter & Painter::text(int x, int y, char const * s, int ls,
+                       LyXFont const & f)
+{
+       if (lyxerr.debugging()) {
+               if (!Lgb_bug_find_hack)
+                       lyxerr << "text not called from "
+                               "workarea::workhandler\n";
+               lyxerr << "Painter drawable: " << drawable << endl;
+       }
+       
+       GC gc = getGCForeground(f.realColor());
+       XSetFont(display, gc, f.getFontID());
+       XDrawString(display, drawable, gc, x, y, s, ls);
+       underline(f, x, y, this->width(s, ls, f));
+       return *this;
+}
+
+
+Painter & Painter::text(int x, int y, char c, LyXFont const & f)
+{
+       if (lyxerr.debugging()) {
+               if (!Lgb_bug_find_hack)
+                       lyxerr << "text not called from "
+                               "workarea::workhandler\n";
+               lyxerr << "Painter drawable: " << drawable << endl;
+       }
+       
+       GC gc = getGCForeground(f.realColor());
+       XSetFont(display, gc, f.getFontID());
+       char s[2];
+       s[0] = c; s[1] = '\0';
+       XDrawString(display, drawable, gc, x, y, s, 1);
+       underline(f, x, y, this->width(c, f));
+       return *this;
+}
+
+
+void Painter::underline(LyXFont const & f, int x, int y, int width) {
+       // What about underbars?
+       if (f.underbar() == LyXFont::ON && f.latex() != LyXFont::ON) {
+               int below = f.maxDescent() / 2;
+               if (below < 2) below = 2;
+               int height = (f.maxDescent() / 4) - 1;
+               if (height < 0) height = 0;
+               fillRectangle(x, y + below, width, below + height, f.color());
+       }
+}
+
+
+// Gets GC according to color
+// Uses caching
+GC Painter::getGCForeground(LColor::color c)
+{
+       if (lyxerr.debugging()) {
+               lyxerr << "Painter drawable: " << drawable << endl;
+       }
+       
+       if (colorGCcache[c] != 0) return colorGCcache[c];
+
+       XColor xcol, ccol;
+       string s = lcolor.getX11Name(c);
+       XGCValues val;
+
+       // Look up the RGB values for the color, and an approximate
+       // color that we can hope to get on this display.
+        if (XLookupColor(display, colormap, s.c_str(), &xcol, &ccol) == 0) {
+               lyxerr << _("LyX: Unknown X11 color ") << s
+                      << _(" for ") << lcolor.getGUIName(c) << '\n'
+                      << _("     Using black instead, sorry!.") << endl;
+               unsigned long bla = BlackPixel(display,
+                                              DefaultScreen(display));
+               val.foreground = bla;
+       // Try the exact RGB values first, then the approximate.
+       } else if (XAllocColor(display, colormap, &xcol) != 0) {
+               lyxerr << _("LyX: X11 color ") << s
+                      << _(" allocated for ") 
+                      << lcolor.getGUIName(c) << endl;
+               val.foreground = xcol.pixel;
+       } else if (XAllocColor(display, colormap, &ccol)) {
+               lyxerr << _("LyX: Using approximated X11 color ") << s
+                      << _(" allocated for ")
+                      << lcolor.getGUIName(c) << endl;
+               val.foreground = xcol.pixel;
+       } else {
+               // Here we are traversing the current colormap to find
+               // the color closest to the one we want.
+               Visual * vi = DefaultVisual(display, DefaultScreen(display));
+
+               XColor * cmap = new XColor[vi->map_entries];
+
+               for(int i = 0; i < vi->map_entries; ++i) {
+                       cmap[i].pixel = i;
+               }
+               XQueryColors(display, colormap, cmap, vi->map_entries);
+
+               // Walk through the cmap and look for close colors.
+               int closest_pixel = 0;
+               double closest_distance = 1e20; // we want to minimize this
+               double distance = 0;
+               for(int t = 0; t < vi->map_entries; ++t) {
+                       // The Euclidean distance between two points in 
+                       // a three-dimensional space, the RGB color-cube,
+                       // is used as the distance measurement between two
+                       // colors.
+
+                       // Since square-root is monotonous, we don't have to
+                       // take the square-root to find the minimum, and thus 
+                       // we use the squared distance instead to be faster.
+
+                       // If we want to get fancy, we could convert the RGB
+                       // coordinates to a different color-cube, maybe HSV,
+                       // but the RGB cube seems to work great.  (Asger)
+                       distance = pow(cmap[t].red   - xcol.red,   2.0) +
+                                  pow(cmap[t].green - xcol.green, 2.0) +
+                                  pow(cmap[t].blue  - xcol.blue,  2.0);
+                       if (distance < closest_distance) {
+                               closest_distance = distance;
+                               closest_pixel = t;
+                       }
+               }
+               lyxerr << _("LyX: Couldn't allocate '") << s 
+                      << _("' for ") << lcolor.getGUIName(c)
+                      << _(" with (r,g,b)=(") 
+                      << xcol.red << "," << xcol.green << ","
+                      << xcol.blue << ").\n"
+                      << _("     Using closest allocated "
+                           "color with (r,g,b)=(") 
+                      << cmap[closest_pixel].red << ","
+                      << cmap[closest_pixel].green << ","
+                      << cmap[closest_pixel].blue << ") instead.\n"
+                      << "Pixel [" << closest_pixel << "] is used." << endl;
+               val.foreground = cmap[closest_pixel].pixel;
+               delete[] cmap;
+       }
+
+       val.function = GXcopy;
+       return colorGCcache[c] = XCreateGC(display, drawable,
+                                   GCForeground | GCFunction, &val);
+}
+
+
+// Gets GC for line
+GC Painter::getGCLinepars(enum line_style ls,
+                         enum line_width lw, LColor::color c)
+{
+       if (lyxerr.debugging()) {
+               lyxerr << "Painter drawable: " << drawable << endl;
+       }
+       
+       int index = lw + (ls << 1) + (c << 3);
+
+       if (lineGCcache.find(index) != lineGCcache.end())
+               return lineGCcache[index];
+
+       XGCValues val;
+       XGetGCValues(display, getGCForeground(c), GCForeground, &val);
+       
+       switch (lw) {
+       case line_thin:         val.line_width = 0; break;
+       case line_thick:        val.line_width = 2; break;
+       }
+       
+       switch (ls) {
+       case line_solid:        val.line_style = LineSolid; break;
+       case line_onoffdash:    val.line_style = LineOnOffDash; break;
+       case line_doubledash:   val.line_style = LineDoubleDash; break;
+       }
+
+
+       val.cap_style = CapRound;
+       val.join_style = JoinRound;
+       val.function = GXcopy;
+
+       return lineGCcache[index] =
+               XCreateGC(display, drawable, 
+                         GCForeground | GCLineStyle | GCLineWidth | 
+                         GCCapStyle | GCJoinStyle | GCFunction, &val);
+}
+
+#endif
diff --git a/src/Painter.h b/src/Painter.h
new file mode 100644 (file)
index 0000000..0c7ed2a
--- /dev/null
@@ -0,0 +1,140 @@
+// -*- C++ -*-
+/* This file is part of
+ * ======================================================
+ * 
+ *           LyX, The Document Processor
+ *      
+ *         Copyright 1999-2000 The LyX Team
+ *
+ * ======================================================*/
+
+#ifdef USE_PAINTER
+
+#ifndef PAINTER_H
+#define PAINTER_H
+
+#ifdef __GNUG__
+#pragma interface
+#endif
+
+#include "config.h"
+#include "LString.h"
+
+// This is only included to provide stuff for the non-public sections
+#include <X11/Xlib.h>
+
+#include <map>
+#include "PainterBase.h"
+#include "LColor.h"
+
+class LyXFont;
+class WorkArea;
+
+/** An inplementation for the X Window System. Xlib.
+  
+    Classes similar to this one can be made for gtk+, Qt, etc.
+ */
+class Painter : public PainterBase {
+public:
+       /// Constructor 
+       Painter(WorkArea &);
+
+       /// Destructor
+       ~Painter();
+    
+       /**@Basic drawing routines */
+       /// Draw a line from point to point
+       Painter & line(int x1, int y1, int x2, int y2, 
+                      LColor::color = LColor::foreground,
+                      enum line_style = line_solid,
+                      enum line_width = line_thin);
+
+       /// Here xp and yp are arrays of points
+       Painter & lines(int const * xp, int const * yp, int np,
+                       LColor::color = LColor::foreground,
+                       enum line_style = line_solid,
+                       enum line_width = line_thin);
+
+       /// Here xp and yp are arrays of points
+       Painter & fillPolygon(int const * xp, int const * yp, int np,
+                       LColor::color = LColor::foreground);
+
+       /// Draw lines from x1,y1 to x2,y2. They are arrays
+        Painter & segments(int const * x1, int const * y1, 
+                          int const * x2, int const * y2, int ns,
+                          LColor::color = LColor::foreground,
+                          enum line_style = line_solid,
+                          enum line_width = line_thin);
+
+       /// Draw a rectangle 
+       Painter & rectangle(int x, int y, int w, int h,
+                           LColor::color = LColor::foreground,
+                           enum line_style = line_solid,
+                           enum line_width = line_thin);
+
+       /// Draw an arc
+       Painter & arc(int x, int y, unsigned int w, unsigned int h, 
+                     int a1, int a2,
+                     LColor::color = LColor::foreground);
+       
+       /// Draw a pixel
+       Painter & point(int x, int y, LColor::color = LColor::foreground);
+       
+       /// Fill a rectangle
+       Painter & fillRectangle(int x, int y, int w, int h,
+                               LColor::color = LColor::background);
+       
+       /**@Image stuff */
+       
+       /// For the figure inset
+       Painter & pixmap(int x, int y, Pixmap bitmap);
+
+       /**@String functions */
+       
+       /// Draw a string at position x, y (y is the baseline)
+       Painter & text(int x, int y, string const & str, LyXFont const & f);
+
+       /** Draw a string at position x, y (y is the baseline)
+           This is just for fast drawing */
+       Painter & text(int x, int y, char const * str, int l,
+                      LyXFont const & f);
+
+       /// Draw a char at position x, y (y is the baseline)
+       Painter & text(int x, int y, char c, LyXFont const & f);
+       
+protected:
+       /**@Support for X only, by now */
+       friend class WorkArea;
+       ///
+       Painter & setDisplay(Display * d) { display = d; return *this; }
+
+       ///
+       Painter & setDrawable(Drawable d) { drawable = d; return *this; }
+
+       /// Get foreground color in ordinary GC
+       GC getGCForeground(LColor::color c);
+       
+       /// Set up GC according to line style
+       GC getGCLinepars(enum line_style, enum line_width, LColor::color c);
+
+       /// Check the font, and if set, draw an underline
+       void underline(LyXFont const & f, int x, int y, int width);
+
+       /**@Low level X parameters */
+       ///
+       Display * display;
+       ///
+       Drawable drawable;
+       ///
+       Colormap colormap;
+
+       /// Caching of ordinary color GCs
+       GC colorGCcache[LColor::ignore + 1];
+       /// Caching of GCs used for lines
+       typedef map<int, GC, less<int> > LineGCCache;
+       ///
+       LineGCCache lineGCcache;
+};
+#endif
+
+#endif
diff --git a/src/PainterBase.C b/src/PainterBase.C
new file mode 100644 (file)
index 0000000..30e1ea9
--- /dev/null
@@ -0,0 +1,145 @@
+/* This file is part of
+ * ======================================================
+ * 
+ *           LyX, The Document Processor
+ *      
+ *         Copyright 1998-2000 The LyX Team
+ *
+ *======================================================*/
+
+#include <config.h>
+
+#ifdef USE_PAINTER
+
+#ifdef __GNUG__
+#pragma implementation
+#endif
+
+#include "PainterBase.h"
+#include "lyxfont.h"
+#include "WorkArea.h"
+
+
+int PainterBase::dummy1 = 0;
+int PainterBase::dummy2 = 0;
+int PainterBase::dummy3 = 0;
+
+int PainterBase::paperMargin()
+{
+       return 20;
+}
+
+
+int PainterBase::paperWidth()
+{
+       return owner.workWidth();
+}
+
+
+int PainterBase::width(string const & s, LyXFont const & f)
+{
+       return f.stringWidth(s);
+}
+
+
+int PainterBase::width(char const * s, int l, LyXFont const & f)
+{
+       return f.textWidth(s, l);
+}
+
+
+int PainterBase::width(char c, LyXFont const & f)
+{
+       return f.width(c);
+}
+
+
+PainterBase & PainterBase::circle(int x, int y, unsigned int d,
+                                 LColor::color col = LColor::foreground)
+{
+       return ellipse(x, y, d, d, col);
+}
+
+
+PainterBase & PainterBase::ellipse(int x, int y,
+                                  unsigned int w, unsigned int h,
+                                  LColor::color col = LColor::foreground)
+{
+       return arc(x, y, w, h, 0, 0, col);
+}
+
+
+PainterBase & PainterBase::button(int x, int y, int w, int h)
+{
+       fillRectangle(x, y, w, h, LColor::buttonbg);
+       buttonFrame(x, y, w, h);
+       return * this;
+}
+
+
+PainterBase & PainterBase::buttonFrame(int x, int y, int w, int h)
+{
+       //  Width of a side of the button
+       int d = 2;
+
+       fillRectangle(x, y, w, d, LColor::top);
+       fillRectangle(x, (y+h-d), w, d, LColor::bottom);
+       // Now a couple of trapezoids
+       int x1[4], y1[4];
+       x1[0] = x+d;   y1[0] = y+d;
+       x1[1] = x+d;   y1[1] = (y+h-d);
+       x1[2] = x;     y1[2] = y+h;
+       x1[3] = x;     y1[3] = y;
+       fillPolygon(x1, y1, 4, LColor::left);
+
+       x1[0] = (x+w-d); y1[0] = y+d;
+       x1[1] = (x+w-d); y1[1] = (y+h-d);
+       x1[2] = x+w; y1[2] = (y+h-d);
+       x1[3] = x+w; y1[3] = y;
+       fillPolygon(x1, y1, 4, LColor::right);
+
+       return *this;
+}
+
+
+PainterBase & PainterBase::rectText(int x, int baseline, 
+                                   string const & str, 
+                                   LyXFont const & font,
+                                   LColor::color back,
+                                   LColor::color frame, bool draw,
+                                   int & width, int & ascent, int & descent)
+{
+       static int const d = 2;
+       width = this->width(str, font) + d * 2 + 2;
+       ascent = font.maxAscent() + d;
+       descent = font.maxDescent() + d;
+
+       if (!draw) return *this;
+
+       rectangle(x, baseline - ascent, width, ascent + descent, frame);
+       fillRectangle(x + 1, baseline - ascent + 1, width - 1, 
+                     ascent + descent - 1, back);
+       text(x + d, baseline, str, font);
+       return *this;
+}
+
+
+PainterBase & PainterBase::buttonText(int x, int baseline,
+                                     string const & str, 
+                                     LyXFont const & font, bool draw,
+                                     int & width, int & ascent, int & descent)
+{
+       width = this->width(str, font) + 8;
+       ascent = font.maxAscent() + 3;
+       descent = font.maxDescent() + 3;
+
+       if (!draw) return *this;
+
+       button(x, baseline - ascent, width, descent + ascent);
+       text(x + 4, baseline, str, font);
+       return *this;
+}
+
+#endif
diff --git a/src/PainterBase.h b/src/PainterBase.h
new file mode 100644 (file)
index 0000000..ab05dda
--- /dev/null
@@ -0,0 +1,206 @@
+// -*- C++ -*-
+/* This file is part of
+ * ======================================================
+ * 
+ *           LyX, The Document Processor
+ *      
+ *         Copyright 1998-2000 The LyX Team
+ *
+ *======================================================*/
+
+#ifdef USE_PAINTER
+
+#ifndef PAINTERBASE_H
+#define PAINTERBASE_H
+
+#ifdef __GNUG__
+#pragma interface
+#endif
+
+#include "LString.h"
+#include "LColor.h"
+
+class WorkArea;
+class LyXFont;
+class LyXScreen;
+
+/** A painter class to encapsulate all graphics parameters and operations
+   
+    Every graphics operation in LyX should be made by this class. It will 
+    be initialized and managed by the Screen class, and will be passed
+    as a parameter to inset.
+    It hides low level windows system parameters so insets and other
+    clients don't have to worry about them and we can control graphics and
+    GUI toolkit dependent drawing functions inside this single class.
+ */
+class PainterBase {
+protected:
+        ///
+       static int dummy1, dummy2, dummy3;
+public:
+       ///
+       enum line_width {
+               ///
+               line_thin,
+               ///
+               line_thick
+       };
+
+       ///
+       enum line_style {
+               ///
+               line_solid,
+               ///
+               line_doubledash,
+               ///
+               line_onoffdash
+       };
+
+       ///
+       PainterBase(WorkArea & wa) : owner(wa) {}
+       
+       ///
+       virtual ~PainterBase() {}
+
+       /** Screen geometry */
+       ///
+       int paperMargin();
+       ///
+       int paperWidth();
+       
+       /**@Basic drawing routines */
+       /// Draw a line from point to point
+       virtual PainterBase & line(
+               int x1, int y1, int x2, int y2, 
+               LColor::color = LColor::foreground,
+               enum line_style = line_solid,
+               enum line_width = line_thin) = 0;
+
+       /** Draw the lines between the lines in xp and yp.
+           xp and yp are arrays of points, and np is the
+           number of them. */
+       virtual PainterBase & lines(
+               int const * xp, int const * yp, int np,
+               LColor::color = LColor::foreground,
+               enum line_style = line_solid,
+               enum line_width = line_thin) = 0;
+
+       /// Here xp and yp are arrays of points
+       virtual PainterBase & fillPolygon(
+               int const * xp, int const * yp,
+               int np,
+               LColor::color =LColor::foreground) = 0;
+
+       /// Draw lines from x1,y1 to x2,y2. They are arrays
+        virtual PainterBase & segments(
+               int const * x1, int const * y1, 
+               int const * x2, int const * y2, int ns,
+               LColor::color = LColor::foreground,
+               enum line_style = line_solid,
+               enum line_width = line_thin) = 0;
+       
+       /// Draw a rectangle 
+       virtual PainterBase & rectangle(
+               int x, int y, int w, int h,
+               LColor::color = LColor::foreground,
+               enum line_style = line_solid,
+               enum line_width = line_thin) = 0;
+       
+       /// Draw a circle, d is the diameter, not the radious
+       virtual PainterBase & circle(
+               int x, int y, unsigned int d,
+               LColor::color = LColor::foreground);
+
+       /// Draw an ellipse
+       virtual PainterBase & ellipse(
+               int x, int y,
+               unsigned int w, unsigned int h,
+               LColor::color = LColor::foreground);
+       
+       /// Draw an arc
+       virtual PainterBase & arc(
+               int x, int y,
+               unsigned int w, unsigned int h, 
+               int a1, int a2,
+               LColor::color = LColor::foreground) = 0;
+       
+       /// Draw a pixel
+       virtual PainterBase & point(
+               int x, int y,
+               LColor::color = LColor::foreground) = 0;
+       
+       /// Fill a rectangle
+       virtual PainterBase & fillRectangle(
+               int x, int y, int w, int h,
+               LColor::color = LColor::background) = 0;
+       
+       /// A filled rectangle with the shape of a 3D button
+       virtual PainterBase & button(int x, int y, int w, int h);
+
+       /// 
+        virtual PainterBase & buttonFrame(int x, int y, int w, int h);
+       
+       /**@Image stuff */
+       
+       /// For the figure inset
+       // This can't be part of the base since we don't know what window
+       // system we will be useing, or if are going to use pixmaps at all.
+       //virtual PainterBase & pixmap(int x, int y, Pixmap bitmap)=0;
+
+       
+       /**@String functions */
+       
+       /// Draw a string at position x, y (y is the baseline)
+       virtual PainterBase & text(int x, int y,
+                                  string const &str, LyXFont const & f) = 0;
+
+       /** Draw a string at position x, y (y is the baseline)
+           This is just for fast drawing */
+       virtual PainterBase & text(int x, int y, char const * str, int l,
+                      LyXFont const & f) = 0;
+
+       /// Draw a char at position x, y (y is the baseline)
+       virtual PainterBase & text(int x, int y, char c, LyXFont const & f)=0;
+       
+       /// Get the width of text
+       int width(string const & s, LyXFont const & f);
+
+       /** Get the width of text
+           This is just for fast width */
+       int width(char const * s, int l, LyXFont const & f);
+
+       /// Get the width of text
+       int width(char c, LyXFont const & f);
+
+       /** Draws a string and encloses it inside a rectangle. Returns
+           the size of the rectangle. If draw is false, we only calculate
+           the size. */
+       virtual PainterBase & rectText(int x, int baseline, 
+                          string const & string, 
+                          LyXFont const & font,
+                          LColor::color back,
+                          LColor::color frame, bool draw = true,
+                          int & width = PainterBase::dummy1,
+                          int & ascent = PainterBase::dummy2, 
+                          int & descent = PainterBase::dummy3);
+
+       /** Draw a string and encloses it inside a button frame. Returns
+           the size of the frame. If draw is false, we only calculate
+           the size. */
+       virtual PainterBase & buttonText(int x, int baseline, string const & s,
+                            LyXFont const & font, bool draw = true,
+                            int & width = PainterBase::dummy1,
+                            int & ascent = PainterBase::dummy2, 
+                            int & descent = PainterBase::dummy3);
+       /// This is preliminary
+       //BufferView const * getOwner() const {  return &owner; }
+
+private:
+       WorkArea & owner;
+};
+
+#endif
+
+#endif
diff --git a/src/WorkArea.C b/src/WorkArea.C
new file mode 100644 (file)
index 0000000..68a62c5
--- /dev/null
@@ -0,0 +1,421 @@
+/* This file is part of
+ * ======================================================
+ * 
+ *           LyX, The Document Processor
+ *        
+ *           Copyright 1995 Matthias Ettrich
+ *           Copyright 1995-2000 The LyX Team.
+ *
+ * ====================================================== */
+
+#include <config.h>
+#include <cmath>
+
+#ifdef __GNUG__
+#pragma implementation
+#endif
+
+#include "WorkArea.h"
+#include "up.xpm"
+#include "down.xpm"
+#include "debug.h"
+#include "support/lstrings.h"
+#include "BufferView.h"
+
+#ifdef NEW_WA
+FL_OBJECT * figinset_canvas;
+#endif
+
+static inline
+void waitForX()
+{
+       XSync(fl_get_display(), 0);
+}
+
+
+WorkArea::WorkArea(BufferView * o, int xpos, int ypos, int width, int height)
+       : owner(o), workareapixmap(0)
+#ifdef USE_PAINTER
+       , painter_(*this)
+#endif
+{
+       fl_freeze_all_forms();
+
+       figinset_canvas = 0;
+       
+       lyxerr << "Creating work area: +"
+              << xpos << '+' << ypos << ' '
+              << width << 'x' << height << endl;
+       //
+       FL_OBJECT * obj;
+       const int bw = int(abs(float(fl_get_border_width())));
+
+       // We really want to get rid of figinset_canvas.
+       ::figinset_canvas = figinset_canvas = obj =
+                 fl_add_canvas(FL_NORMAL_CANVAS,
+                               xpos + 1, ypos + 1, 1, 1, "");
+       fl_set_object_boxtype(obj, FL_NO_BOX);
+       fl_set_object_resize(obj, FL_RESIZE_ALL);
+       fl_set_object_gravity(obj, NorthWestGravity, NorthWestGravity);
+       
+       // a box
+       lyxerr << "\tbackground box: +"
+              << xpos << '+' << ypos << ' '
+              << width - 15 << 'x' << height << endl;
+       backgroundbox = obj = fl_add_box(FL_BORDER_BOX,
+                                        xpos, ypos,
+                                        width - 15,
+                                        height,"");
+       fl_set_object_resize(obj, FL_RESIZE_ALL);
+       fl_set_object_gravity(obj, NorthWestGravity, SouthEastGravity);
+
+       //
+       // THE SCROLLBAR
+       //
+
+       // up - scrollbar button
+       fl_set_border_width(-1);
+
+       lyxerr << "\tup button: +"
+              << xpos + width - 15 << '+' << ypos << ' '
+              << 15 << 'x' << 15 << endl;
+       button_up = obj = fl_add_pixmapbutton(FL_TOUCH_BUTTON,
+                                             xpos + width - 15,
+                                             ypos,
+                                             15, 15, "");
+       fl_set_object_boxtype(obj,FL_UP_BOX);
+       fl_set_object_color(obj,FL_MCOL,FL_BLUE);
+       fl_set_object_resize(obj, FL_RESIZE_ALL);
+       fl_set_object_gravity(obj,NorthEastGravity, NorthEastGravity);
+       obj->u_vdata = this;
+       fl_set_object_callback(obj,up_cb, 0);
+       fl_set_pixmapbutton_data(obj, const_cast<char**>(up_xpm));
+
+       // Remove the blue feedback rectangle
+       fl_set_pixmapbutton_focus_outline(obj,0);
+
+       // the scrollbar slider
+       fl_set_border_width(-bw);
+       lyxerr << "\tscrollbar slider: +"
+              << xpos + width - 15 << '+' << ypos + 15 << ' '
+              << 15 << 'x' << height - 30 << endl;
+       scrollbar = obj = fl_add_slider(FL_VERT_SLIDER,
+                                       xpos + width - 15,
+                                       ypos + 15,
+                                       15, height - 30, "");
+       fl_set_object_color(obj,FL_COL1,FL_MCOL);
+       fl_set_object_boxtype(obj, FL_UP_BOX);
+       fl_set_object_resize(obj, FL_RESIZE_ALL);
+       fl_set_object_gravity(obj, NorthEastGravity, SouthEastGravity);
+       obj->u_vdata = this;
+       fl_set_object_callback(obj, scroll_cb, 0);
+       fl_set_slider_precision(obj, 0);
+       
+       // down - scrollbar button
+       fl_set_border_width(-1);
+
+       lyxerr << "\tdown button: +"
+              << xpos + width - 15 << '+' << ypos + height - 15 << ' '
+              << 15 << 'x' << 15 << endl;
+       button_down = obj = fl_add_pixmapbutton(FL_TOUCH_BUTTON,
+                                               xpos + width - 15,
+                                               ypos + height - 15,
+                                               15, 15, "");
+       fl_set_object_boxtype(obj,FL_UP_BOX);
+       fl_set_object_color(obj,FL_MCOL,FL_BLUE);
+       fl_set_object_resize(obj, FL_RESIZE_ALL);
+       fl_set_object_gravity(obj, SouthEastGravity, SouthEastGravity);
+       obj->u_vdata = this;
+       fl_set_object_callback(obj, down_cb, 0);
+       fl_set_pixmapbutton_data(obj, const_cast<char**>(down_xpm));
+
+       fl_set_border_width(-bw);
+
+       // Remove the blue feedback rectangle
+       fl_set_pixmapbutton_focus_outline(obj,0);
+
+       ///
+       /// The free object
+
+       // Create the workarea pixmap
+       createPixmap(width - 15 - 2 * bw, height - 2 * bw);
+#ifdef USE_PAINTER
+       // setup the painter
+       painter_.setDisplay(fl_display);
+       painter_.setDrawable(workareapixmap);
+#endif
+       
+       // We add this object as late as possible to avoit problems
+       // with drawing.
+       lyxerr << "\tfree object: +"
+              << xpos + bw << '+' << ypos + bw << ' '
+              << width - 15 - 2 * bw << 'x' << height - 2 * bw << endl;
+       work_area = obj = fl_add_free(FL_INPUT_FREE,
+                                     xpos + bw, ypos + bw,
+                                     width - 15 - 2 * bw, // scrollbarwidth
+                                     height - 2 * bw, "",
+                                     work_area_handler);
+       obj->wantkey = FL_KEY_TAB;
+       obj->u_vdata = this; /* This is how we pass the WorkArea
+                                      to the work_area_handler. */
+       fl_set_object_boxtype(obj,FL_DOWN_BOX);
+       fl_set_object_resize(obj, FL_RESIZE_ALL);
+       fl_set_object_gravity(obj, NorthWestGravity, SouthEastGravity);
+
+       fl_unfreeze_all_forms();
+}
+
+
+WorkArea::~WorkArea()
+{
+       if (workareapixmap)
+               XFreePixmap(fl_display, workareapixmap);
+}
+
+
+void WorkArea::resize(int xpos, int ypos, int width, int height)
+{
+       fl_freeze_all_forms();
+       
+       const int bw = int(abs(float(fl_get_border_width())));
+
+       // a box
+       fl_set_object_geometry(backgroundbox, xpos, ypos, width - 15, height);
+       
+       //
+       // THE SCROLLBAR
+       //
+
+       // up - scrollbar button
+       fl_set_object_geometry(button_up, xpos + width - 15,
+                              ypos,
+                              15, 15);
+       // the scrollbar slider
+       fl_set_object_geometry(scrollbar, xpos + width - 15,
+                              ypos + 15,
+                              15, height - 30);
+       // down - scrollbar button
+       fl_set_object_geometry(button_down, xpos + width - 15,
+                              ypos + height - 15,
+                              15, 15);
+
+       // Create the workarea pixmap
+       createPixmap(width - 15 - 2 * bw, height - 2 * bw);
+
+#ifdef USE_PAINTER
+       // reset the painter
+       painter_.setDrawable(workareapixmap);
+#endif
+       
+       // the free object
+       fl_set_object_geometry(work_area, xpos + bw, ypos + bw,
+                              width - 15 - 2 * bw,
+                              height - 2 * bw);
+
+       fl_unfreeze_all_forms();
+
+}
+
+
+void WorkArea::createPixmap(int width, int height)
+{
+       static int cur_width = -1;
+       static int cur_height = -1;
+
+       if (cur_width == width && cur_height == height && workareapixmap)
+               return;
+       
+       cur_width = width;
+       cur_height = height;
+
+       if (workareapixmap)
+               XFreePixmap(fl_display, workareapixmap);
+       
+       lyxerr << "Creating pixmap (" << width << 'x' << height << ")" << endl;
+       
+       workareapixmap = XCreatePixmap(fl_display,
+                                      RootWindow(fl_display, 0),
+                                      width,
+                                      height, 
+                                      fl_get_visual_depth());
+       lyxerr << "\tpixmap=" << workareapixmap << endl;
+}
+
+
+void WorkArea::greyOut() const
+{
+       fl_winset(FL_ObjWin(work_area));
+       fl_rectangle(1, work_area->x, work_area->y,
+                    work_area->w, work_area->h, FL_GRAY63);
+}
+
+
+void WorkArea::setFocus() const
+{
+       fl_set_focus_object(work_area->form, work_area);
+}
+
+
+void WorkArea::setScrollbar(double pos, double length_fraction) const
+{
+       fl_set_slider_value(scrollbar, pos);
+       fl_set_slider_size(scrollbar, scrollbar->h * length_fraction);
+}
+
+
+void WorkArea::setScrollbarBounds(double l1, double l2) const
+{
+       fl_set_slider_bounds(scrollbar, l1, l2);
+}
+
+
+void WorkArea::setScrollbarIncrements(float inc) const
+{
+       fl_set_slider_increment(scrollbar, work_area->h - inc, inc);
+}
+
+
+void WorkArea::up_cb(FL_OBJECT * ob, long)
+{
+       WorkArea * area = static_cast<WorkArea*>(ob->u_vdata);
+       XEvent const * ev2 = fl_last_event();
+       static long time = 0;
+       ev2 = fl_last_event();
+       if (ev2->type == ButtonPress || ev2->type == ButtonRelease) 
+               time = 0;
+       //area->up(time++, fl_get_button_numb(ob));
+       area->owner->UpCB(time++, fl_get_button_numb(ob));
+}
+
+
+void WorkArea::down_cb(FL_OBJECT * ob, long)
+{
+       WorkArea * area = static_cast<WorkArea*>(ob->u_vdata);
+       XEvent const * ev2 = fl_last_event();
+       static long time = 0;
+       if (ev2->type == ButtonPress || ev2->type == ButtonRelease)
+               time = 0;
+       //area->down(time++, fl_get_button_numb(ob));
+       area->owner->DownCB(time++, fl_get_button_numb(ob));
+}
+
+
+// Callback for scrollbar slider
+void WorkArea::scroll_cb(FL_OBJECT * ob, long)
+{
+       WorkArea * area = static_cast<WorkArea*>(ob->u_vdata);
+
+       //area->scroll(fl_get_slider_value(ob));
+       area->owner->ScrollCB(fl_get_slider_value(ob));
+       waitForX();
+}
+
+bool Lgb_bug_find_hack = false;
+
+int WorkArea::work_area_handler(FL_OBJECT * ob, int event,
+                                 FL_Coord, FL_Coord ,
+                                 int /*key*/, void * xev)
+{
+       static int x_old = -1;
+       static int y_old = -1;
+       static long scrollbar_value_old = -1;
+       
+       XEvent * ev = static_cast<XEvent*>(xev);
+       WorkArea * area = static_cast<WorkArea*>(ob->u_vdata);
+
+       if (!area) return 1;
+       
+       switch (event){   
+       case FL_DRAW:
+               if (!area->work_area ||
+                   !area->work_area->form->visible)
+                       return 1;
+               lyxerr.debug() << "Workarea event: DRAW" << endl;
+               area->createPixmap(area->workWidth(), area->height());
+               Lgb_bug_find_hack = true;
+               //area->expose();
+               area->owner->workAreaExpose();
+               Lgb_bug_find_hack = false;
+               break;
+       case FL_PUSH:
+               if (!ev) break;
+               // Should really have used xbutton.state
+               lyxerr.debug() << "Workarea event: PUSH" << endl;
+               //area->buttonPress(ev->xbutton.x - ob->x,
+               //                ev->xbutton.y - ob->y,
+               //                ev->xbutton.button);
+               area->owner->WorkAreaButtonPress(ev->xbutton.x - ob->x,
+                                          ev->xbutton.y - ob->y,
+                                          ev->xbutton.button);
+               break; 
+       case FL_RELEASE:
+               if (!ev) break;
+               // Should really have used xbutton.state
+               lyxerr.debug() << "Workarea event: RELEASE" << endl;
+               //area->buttonRelease(ev->xbutton.x - ob->x,
+               //                  ev->xbutton.y - ob->y,
+               //                  ev->xbutton.button);
+               area->owner->WorkAreaButtonRelease(ev->xbutton.x - ob->x,
+                                            ev->xbutton.y - ob->y,
+                                            ev->xbutton.button);
+               break;
+       case FL_MOUSE:
+               if (!ev || ! area->scrollbar) break;
+               if (ev->xmotion.x != x_old ||
+                   ev->xmotion.y != y_old ||
+                   fl_get_slider_value(area->scrollbar) != scrollbar_value_old) {
+                       lyxerr.debug() << "Workarea event: MOUSE" << endl;
+                       //area->motion(ev->xmotion.x - ob->x,
+                       //           ev->xmotion.y - ob->y,
+                       //           ev->xbutton.state);
+                       area->owner->WorkAreaMotionNotify(ev->xmotion.x - ob->x,
+                                                   ev->xmotion.y - ob->y,
+                                                   ev->xbutton.state);
+               }
+               break;
+       // Done by the raw callback:
+       //  case FL_KEYBOARD: WorkAreaKeyPress(ob, 0,0,0,ev,0); break;
+       case FL_FOCUS:
+               lyxerr.debug() << "Workarea event: FOCUS" << endl;
+               //area->focus();
+               break;
+       case FL_UNFOCUS:
+               lyxerr.debug() << "Workarea event: UNFOCUS" << endl;
+               //area->unfocus();
+               break;
+       case FL_ENTER:
+               lyxerr.debug() << "Workarea event: ENTER" << endl;
+               //area->enter();
+               break;
+       case FL_LEAVE:
+               lyxerr.debug() << "Workarea event: LEAVE" << endl;
+               //area->leave();
+               break;
+       case FL_DBLCLICK:
+               if (!ev) break;
+               lyxerr.debug() << "Workarea event: DBLCLICK" << endl;;
+               //area->doubleclick(ev->xbutton.x,
+               //                ev->xbutton.y,
+               //                ev->xbutton.button);
+               break;
+       case FL_TRPLCLICK:
+               if (!ev) break;
+               lyxerr.debug() << "Workarea event: TRPLCLICK" << endl;
+               //area->trippleclick(ev->xbutton.x,
+               //                 ev->xbutton.y,
+               //                 ev->xbutton.button);
+               break;
+       case FL_OTHER:
+               if (!ev) break;
+               if (ev->type == SelectionNotify) {
+                       lyxerr.debug() << "Workarea event: SELECTION" << endl;
+                       //area->selection(area->work_area->form->window, ev);
+                       area->owner->WorkAreaSelectionNotify(area->work_area->form->window, ev);
+               } else
+                       lyxerr.debug() << "Workarea event: OTHER" << endl;
+
+               break;
+       }
+  
+       return 1;
+}
diff --git a/src/WorkArea.h b/src/WorkArea.h
new file mode 100644 (file)
index 0000000..99cf3d5
--- /dev/null
@@ -0,0 +1,149 @@
+// -*- C++ -*-
+/* This file is part of
+ * ======================================================
+ * 
+ *           LyX, The Document Processor
+ *        
+ *           Copyright 1995 Matthias Ettrich
+ *           Copyright 1995-2000 The LyX Team.
+ *
+ * ======================================================*/
+
+#ifndef WORKAREA_H
+#define WORKAREA_H
+
+#ifdef __GNUG__
+#pragma interface
+#endif
+
+#include <utility>
+
+#include FORMS_H_LOCATION
+#include "Painter.h"
+
+class BufferView;
+
+class WorkArea {
+public:
+       ///
+       WorkArea(BufferView *, int xpos, int ypos, int width, int height);
+       ///
+       ~WorkArea();
+#ifdef USE_PAINTER
+       ///
+       Painter & getPainter() { return painter_; }
+#endif
+       ///
+       int workWidth() const { return work_area->w; }
+       ///
+       int width() const { return work_area->w + scrollbar->w; }
+       ///
+       int height() const { return work_area->h; }
+       ///
+       int xpos() const { return work_area->x; }
+       ///
+       int ypos() const { return work_area->y; }
+       ///
+       void resize(int xpos, int ypos, int width, int height);
+       ///
+       void redraw() const {
+               fl_redraw_object(work_area);
+               fl_redraw_object(scrollbar);
+               fl_redraw_object(button_down);
+               fl_redraw_object(button_up);
+       }
+       ///
+       void setFocus() const;
+       ///
+       Window getWin() const { return work_area->form->window; }
+       ///
+       bool hasFocus() const { return work_area->focus; }
+       ///
+       bool active() const { return work_area->active; }
+       ///
+       bool visible() const { return work_area->form->visible; }
+       ///
+       void greyOut() const;
+       ///
+       void setScrollbar(double pos, double length_fraction) const;
+       ///
+       void setScrollbarValue(double y) const { fl_set_slider_value(scrollbar, y); }
+       ///
+       void setScrollbarBounds(double, double) const;
+       ///
+       void setScrollbarIncrements(float inc) const;
+       ///
+       double getScrollbarValue() const {
+               return fl_get_slider_value(scrollbar);
+       }
+       ///
+       pair<double, double> getScrollbarBounds() const {
+               pair<double, double> p;
+               fl_get_slider_bounds(scrollbar, &p.first, &p.second);
+               return p;
+       }
+       ///
+       Pixmap getPixmap() const { return workareapixmap; }
+       ///
+       //Signal2<long, int> up;
+       ///
+       //Signal2<long, int> down;
+       ///
+       //Signal1<double> scroll;
+       ///
+       //Signal0 expose;
+       ///
+       //Signal3<int, int, unsigned int> buttonPress;
+       ///
+       //Signal3<int, int, unsigned int> buttonRelease;
+       ///
+       //Signal3<int, int, unsigned int> motion;
+       ///
+       //Signal0 focus;
+       ///
+       //Signal0 unfocus;
+       ///
+       //Signal0 enter;
+       ///
+       //Signal0 leave;
+       ///
+       //Signal3<int, int, unsigned int> doubleclick;
+       ///
+       //Signal3<int, int, unsigned int> trippleclick;
+       ///
+       //Signal2<Window, XEvent *> selection;
+private:
+       ///
+       void createPixmap(int, int);
+       /// xforms callback
+       static int work_area_handler(FL_OBJECT *, int event,
+                                    FL_Coord, FL_Coord,
+                                    int /*key*/, void * xev);
+       /// xforms callback
+       static void up_cb(FL_OBJECT *, long);
+       /// xforms callback
+       static void down_cb(FL_OBJECT *, long);
+       /// xforms callback
+       static void scroll_cb(FL_OBJECT *, long);
+       ///
+       FL_OBJECT * backgroundbox;
+       ///     
+       FL_OBJECT * work_area;
+       ///
+       FL_OBJECT * scrollbar;
+       ///
+       FL_OBJECT * button_down;
+       ///
+       FL_OBJECT * button_up;
+       ///
+       BufferView * owner;
+       /// The pixmap overlay on the workarea
+       Pixmap workareapixmap;
+#ifdef USE_PAINTER
+       ///
+       Painter painter_;
+#endif
+       ///
+       FL_OBJECT * figinset_canvas;
+};
+#endif
index 4e98d7a29b68d573d9f02f5b0efb363fe80bfb89..ae87405a255032985fbf28ee825b26124fb8234a 100644 (file)
@@ -253,10 +253,9 @@ void fl_set_bmtable_pixmap_data(FL_OBJECT * ob, int nx, int ny,
                        char ** pdata)
 {
        BMTABLE_SPEC * sp = (BMTABLE_SPEC *)ob->spec;
-       extern Colormap color_map;
        if (sp) {
                Pixmap dummy_shapemask = 0;
-               XpmAttributes dumb_attributes;
+               XpmAttributes dumb_attributes = { 0 };
                sp->nx = nx;
                sp->ny = ny; 
                sp->bx = FL_abs(ob->bw);
@@ -266,7 +265,7 @@ void fl_set_bmtable_pixmap_data(FL_OBJECT * ob, int nx, int ny,
                sp->i = -1;
                sp->maxi = sp->nx * sp->ny;
                sp->bdata = 0;
-               dumb_attributes.colormap = color_map;
+               dumb_attributes.colormap = fl_state[fl_get_vclass()].colormap;
                dumb_attributes.closeness = 30000;
                dumb_attributes.valuemask = XpmColormap | XpmCloseness;
                if (XCreatePixmapFromData(fl_display, fl_winget(), pdata,
@@ -279,7 +278,6 @@ void fl_set_bmtable_pixmap_data(FL_OBJECT * ob, int nx, int ny,
                                XFreePixmap(fl_display, dummy_shapemask);
                        }
                }
-               XFlush(fl_display);
        }
 }
 
@@ -315,11 +313,11 @@ void fl_set_bmtable_file(FL_OBJECT * ob, int nx, int ny, char const * filename)
 
 void fl_set_bmtable_pixmap_file(FL_OBJECT *ob, int nx, int ny, char const *filename)
 {      
-       extern Colormap color_map;
+  //extern Colormap color_map;
        BMTABLE_SPEC *sp = (BMTABLE_SPEC *)ob->spec;
        if (sp) {
                Pixmap dummy_shapemask = 0;
-               XpmAttributes dumb_attributes;
+               XpmAttributes dumb_attributes = { 0 };
                sp->nx = nx;
                sp->ny = ny; 
                sp->bx = FL_abs(ob->bw);
@@ -330,7 +328,7 @@ void fl_set_bmtable_pixmap_file(FL_OBJECT *ob, int nx, int ny, char const *filen
                sp->maxi = sp->nx * sp->ny;
                sp->bdata = 0;
 
-               dumb_attributes.colormap = color_map;
+               dumb_attributes.colormap = fl_state[fl_get_vclass()].colormap;
                dumb_attributes.closeness = 30000;
                dumb_attributes.valuemask = XpmColormap | XpmCloseness;
    
@@ -344,7 +342,7 @@ void fl_set_bmtable_pixmap_file(FL_OBJECT *ob, int nx, int ny, char const *filen
                                XFreePixmap(fl_display, dummy_shapemask);
                        }
                }
-               XFlush(fl_display);
+               //XFlush(fl_display);
        }
 }
 
index ff31fbf71ff06c853d11dfa2045d2c2e281dc69f..0c43edfb020f85aaa5e7f410428930f73fee3a3b 100644 (file)
@@ -65,6 +65,7 @@ using std::flush;
 #include "lyx_gui_misc.h" // CancelCloseBoxCB
 #include "support/FileInfo.h"
 #include "support/lyxlib.h"
+#include "Painter.h"
 
 extern BufferView * current_view;
 extern FL_OBJECT * figinset_canvas;
@@ -112,7 +113,29 @@ static int gs_allcolors;           // number of all colors
 
 static list<int> pidwaitlist; // pid wait list
 
-extern Colormap color_map;
+//extern Colormap color_map;
+
+
+
+static
+GC createGC()
+{
+       XGCValues val;
+       val.foreground = BlackPixel(fl_display, 
+                                   DefaultScreen(fl_display));
+       
+       val.function=GXcopy;
+       val.graphics_exposures = false;
+       val.line_style = LineSolid;
+       val.line_width = 0;
+       return XCreateGC(fl_display, RootWindow(fl_display, 0), 
+                        GCForeground | GCFunction | GCGraphicsExposures
+                        | GCLineWidth | GCLineStyle , &val);
+}
+
+static
+GC local_gc_copy;
+
 
 void addpidwait(int pid)
 {
@@ -158,11 +181,15 @@ extern "C" int GhostscriptMsg(FL_OBJECT *, Window, int, int,
                                //XColor * cmap;
                                XWindowAttributes wa;
                                register XImage * im;
-                               int i, y, wid1, spc1 = gs_spc-1,
-                                       spc2 = gs_spc * gs_spc, wid = p->wid,
-                                       forkstat;
+                               int i;
+                               int y;
+                               int wid1;
+                               int spc1 = gs_spc-1;
+                               int spc2 = gs_spc * gs_spc;
+                               int wid = p->wid;
+                               int forkstat;
                                Display * tmpdisp;
-                               GC gc = getGC(gc_copy);
+                               GC gc = local_gc_copy;
 
                                XGetWindowAttributes(fl_display,
                                                     fl_get_canvas_id(
@@ -212,7 +239,11 @@ extern "C" int GhostscriptMsg(FL_OBJECT *, Window, int, int,
                                // query current colormap
                                        XColor * cmap = new XColor[gs_allcolors];
                                        for (i = 0; i < gs_allcolors; ++i) cmap[i].pixel = i;
+#if 1
+                                       XQueryColors(tmpdisp, fl_state[fl_get_vclass()].colormap, cmap, gs_allcolors);
+#else
                                        XQueryColors(tmpdisp, color_map, cmap, gs_allcolors);
+#endif
                                        XFlush(tmpdisp);
                                        wid1 = p->wid - 1;
                                // now we process all the image
@@ -297,8 +328,10 @@ static void AllocColors(int num)
                xcol.green = 65535 * ((i / num) % num) / (num - 1);
                xcol.blue = 65535 * (i % num) / (num - 1);
                xcol.flags = DoRed | DoGreen | DoBlue;
-               if (!XAllocColor(fl_display, color_map, &xcol)) {
-                       if (i) XFreeColors(fl_display, color_map,
+               if (!XAllocColor(fl_display,
+                                fl_state[fl_get_vclass()].colormap, &xcol)) {
+                       if (i) XFreeColors(fl_display,
+                                          fl_state[fl_get_vclass()].colormap,
                                           gs_pixels, i, 0);
                        if(lyxerr.debugging()) {
                                lyxerr << "Cannot allocate color cube "
@@ -335,8 +368,10 @@ void AllocGrays(int num)
        for (int i = 0; i < num; ++i) {
                xcol.red = xcol.green = xcol.blue = 65535 * i / (num - 1);
                xcol.flags = DoRed | DoGreen | DoBlue;
-               if (!XAllocColor(fl_display, color_map, &xcol)) {
-                       if (i) XFreeColors(fl_display, color_map,
+               if (!XAllocColor(fl_display,
+                                fl_state[fl_get_vclass()].colormap, &xcol)) {
+                       if (i) XFreeColors(fl_display,
+                                          fl_state[fl_get_vclass()].colormap,
                                           gs_pixels, i, 0);
                        if (lyxerr.debugging()) {
                                lyxerr << "Cannot allocate grayscale " 
@@ -358,12 +393,8 @@ void InitFigures()
        bmparrsize = figarrsize = figallocchunk;
        typedef Figref * Figref_p;
        figures = new Figref_p[figallocchunk];
-       //figures = static_cast<Figref**>
-       //      (malloc(sizeof(Figref*) * figallocchunk));
        typedef figdata * figdata_p;
        bitmaps = new figdata_p[figallocchunk];
-       //bitmaps = static_cast<figdata**>
-       //(malloc(sizeof(figdata*) * figallocchunk));
 
        unsigned int k;
        for (unsigned int i = 0; i < 256; ++i) {
@@ -376,12 +407,15 @@ void InitFigures()
        fl_add_canvas_handler(figinset_canvas, ClientMessage,
                              GhostscriptMsg, current_view->owner()->getMainForm());
 
+#if 0
        // now we have to init color_map
        if (!color_map) color_map = DefaultColormap(fl_display,
                                                    DefaultScreen(fl_display));
+#endif
        // allocate color cube on pseudo-color display
        // first get visual
        gs_color = false;
+       local_gc_copy = createGC();
 
        Visual * vi = DefaultVisual(fl_display, DefaultScreen(fl_display));
        if (lyxerr.debugging()) {
@@ -410,8 +444,6 @@ void InitFigures()
 
 void DoneFigures()
 {
-       //free(figures);
-       //free(bitmaps);
        delete[] figures;
        delete[] bitmaps;
        figarrsize = 0;
@@ -422,12 +454,14 @@ void DoneFigures()
        fl_remove_canvas_handler(figinset_canvas, ClientMessage,
                                 GhostscriptMsg);
 
+#if 0
        if (gs_color) {
                lyxerr.debug() << "Freeing up the colors..." << endl;
                XFreeColors(fl_display, color_map, gs_pixels,
                            gs_num_pixels, 0);
                /******????????????????? what's planes in this case ??????***/
        }
+#endif
 }
 
 
@@ -609,6 +643,17 @@ static void runqueue()
                                break;
                        }
 
+#ifdef USE_PAINTER
+                       if (reverse_video) {
+                               sprintf(tbuf+1, " %ld %ld", WhitePixelOfScreen(
+                                       DefaultScreenOfDisplay(fl_display)),
+                                       fl_get_pixel(FL_BLACK));
+                       } else {
+                               sprintf(tbuf+1, " %ld %ld", BlackPixelOfScreen(
+                                       DefaultScreenOfDisplay(fl_display)),
+                                       fl_get_pixel(FL_WHITE));
+                       }
+#else
                        if (reverse_video) {
                                sprintf(tbuf+1, " %ld %ld", WhitePixelOfScreen(
                                        DefaultScreenOfDisplay(fl_display)),
@@ -618,6 +663,7 @@ static void runqueue()
                                        DefaultScreenOfDisplay(fl_display)),
                                        background_pixels);
                        }
+#endif
 
                        XChangeProperty(tempdisp, 
                                        fl_get_canvas_id(figinset_canvas),
@@ -638,8 +684,6 @@ static void runqueue()
                        while (environ[ne]) ++ne;
                        typedef char * char_p;
                        env = new char_p[ne + 2];
-                       //env = static_cast<char **>
-                       //      (malloc(sizeof(char*) * (ne + 2)));
                        env[0] = tbuf2;
                        memcpy(&env[1], environ, sizeof(char*) * (ne + 1));
                        environ = env;
@@ -735,12 +779,9 @@ static figdata * getfigdata(int wid, int hgh, string const & fname,
                bmparrsize += figallocchunk;
                typedef figdata * figdata_p;
                figdata ** tmp = new figdata_p[bmparrsize];
-               //figdata ** tmp = static_cast<figdata**>
-               //      (malloc(sizeof(figdata*) * bmparrsize));
                memcpy(tmp, bitmaps,
                       sizeof(figdata*) * (bmparrsize - figallocchunk));
                delete[] bitmaps;
-               //free(bitmaps);
                bitmaps = tmp;
        }
        figdata * p = new figdata;
@@ -799,7 +840,6 @@ static void makeupdatelist(figdata * p)
                                       << figures[i]->inset
                                       << endl;
                        }
-                       //UpdateInset(figures[i]->inset);
                        // add inset figures[i]->inset into to_update list
                        PutInsetIntoInsetUpdateList(figures[i]->inset);
                }
@@ -907,12 +947,9 @@ static void RegisterFigure(InsetFig * fi)
                figarrsize += figallocchunk;
                typedef Figref * Figref_p;
                Figref ** tmp = new Figref_p[figarrsize];
-               //Figref ** tmp = static_cast<Figref**>
-               //      (malloc(sizeof(Figref*)*figarrsize));
                memcpy(tmp, figures,
                       sizeof(Figref*)*(figarrsize-figallocchunk));
                delete[] figures;
-               //free(figures);
                figures = tmp;
        }
        Figref * tmpfig = new Figref;
@@ -1013,24 +1050,98 @@ InsetFig::~InsetFig()
 }
 
 
+#ifdef USE_PAINTER
+int InsetFig::ascent(Painter &, LyXFont const &) const
+{
+       return hgh + 3;
+}
+#else
 int InsetFig::Ascent(LyXFont const &) const
 {
        return hgh + 3;
 }
+#endif
 
 
+#ifdef USE_PAINTER
+int InsetFig::descent(Painter &, LyXFont const &) const
+{
+       return 1;
+}
+#else
 int InsetFig::Descent(LyXFont const &) const
 {
        return 1;
 }
+#endif
 
 
+#ifdef USE_PAINTER
+int InsetFig::width(Painter &, LyXFont const &) const
+{
+       return wid + 2;
+}
+#else
 int InsetFig::Width(LyXFont const &) const
 {
        return wid + 2;
 }
+#endif
+
+
+#ifdef USE_PAINTER
+void InsetFig::draw(Painter & pain, LyXFont const & f,
+                   int baseline, float & x) const
+{
+       LyXFont font(f);
+       
+       if (bitmap_waiting) getbitmaps();
+       
+       // I wish that I didn't have to use this
+       // but the figinset code is so complicated so
+       // I don't want to fiddle with it now.
 
+#if 0
+       unsigned long pm = pain.getScreen()->getForeground();
+       if (figure && figure->data && figure->data->bitmap &&
+           !figure->data->reading && !figure->data->broken) {
+               // draw the bitmap
+               XCopyArea(fl_display, figure->data->bitmap, pm, getGC(gc_copy),
+                         0, 0, wid, hgh, int(x+1), baseline-hgh);
+               XFlush(fl_display);
+               if (flags & 4) XDrawRectangle(fl_display, pm, getGC(gc_copy),
+                                             int(x), baseline - hgh - 1,
+                                             wid+1, hgh+1);
+       } else {
+#endif
+               char * msg = 0;
+               // draw frame
+               pain.rectangle(x, baseline - hgh - 1, wid + 1, hgh + 1);
 
+               if (figure && figure->data) {
+                       if (figure->data->broken)  msg = _("[render error]");
+                       else if (figure->data->reading) msg = _("[rendering ... ]");
+               } else 
+                       if (fname.empty()) msg = _("[no file]");
+                       else if ((flags & 3) == 0) msg = _("[not displayed]");
+                       else if (lyxrc->ps_command.empty()) msg = _("[no ghostscript]");
+               
+               if (!msg) msg = _("[unknown error]");
+               
+               font.setFamily(LyXFont::SANS_FAMILY);
+               font.setSize(LyXFont::SIZE_FOOTNOTE);
+               string justname = OnlyFilename (fname);
+               pain.text(int(x + 8), baseline - font.maxAscent() - 4,
+                         justname, font);
+               
+               font.setSize(LyXFont::SIZE_TINY);
+               pain.text(int(x + 8), baseline - 4, msg, strlen(msg), font);
+#if 0
+       }
+#endif
+       x += width(pain, font);    // ?
+}
+#else
 void InsetFig::Draw(LyXFont font, LyXScreen & scr, int baseline, float & x)
 {
        if (bitmap_waiting) getbitmaps();
@@ -1043,16 +1154,16 @@ void InsetFig::Draw(LyXFont font, LyXScreen & scr, int baseline, float & x)
        if (figure && figure->data && figure->data->bitmap &&
            !figure->data->reading && !figure->data->broken) {
                // draw the bitmap
-               XCopyArea(fl_display, figure->data->bitmap, pm, getGC(gc_copy),
+               XCopyArea(fl_display, figure->data->bitmap, pm, local_gc_copy,
                          0, 0, wid, hgh, int(x+1), baseline-hgh);
                XFlush(fl_display);
-               if (flags & 4) XDrawRectangle(fl_display, pm, getGC(gc_copy),
+               if (flags & 4) XDrawRectangle(fl_display, pm, local_gc_copy,
                                              int(x), baseline - hgh - 1,
                                              wid+1, hgh+1);
        } else {
                char * msg = 0;
                // draw frame
-               XDrawRectangle(fl_display, pm, getGC(gc_copy),
+               XDrawRectangle(fl_display, pm, local_gc_copy,
                               int(x),
                               baseline - hgh - 1, wid+1, hgh+1);
                if (figure && figure->data) {
@@ -1079,6 +1190,7 @@ void InsetFig::Draw(LyXFont font, LyXScreen & scr, int baseline, float & x)
        }
        x += Width(font);    // ?
 }
+#endif
 
 
 void InsetFig::Write(ostream & os)
@@ -1324,7 +1436,6 @@ void InsetFig::Regenerate()
                cmd = "\\fbox{\\rule[-0.5in]{0pt}{1in}";
                cmd += _("empty figure path");
                cmd += '}';
-               //if (form) fl_set_object_label(form->cmd, "");
                return;
        }
 
@@ -1434,8 +1545,6 @@ void InsetFig::Regenerate()
        }
        
        cmd = cmdbuf;
-
-       //if (form) fl_set_object_label(form->cmd, cmd.c_str());
 }
 
 
@@ -1452,8 +1561,6 @@ void InsetFig::TempRegenerate()
        float txhgh = atof(fl_get_input(form->Height));
 
        if (!tfname || !*tfname) {
-               //fl_set_object_label(form->cmd, "");
-               //fl_redraw_object(form->cmd);
                cmd = "\\fbox{\\rule[-0.5in]{0pt}{1in}";
                cmd += _("empty figure path");
                cmd += '}';
index 43d29e2173b06d2b0f02393d698fefe87b56c9b3..ee06f05b5d41d539ef748bfd535363770081ae0e 100644 (file)
@@ -24,6 +24,17 @@ public:
        InsetFig(int tmpx, int tmpy, Buffer *);
        ///
        ~InsetFig();
+#ifdef USE_PAINTER
+       ///
+       int ascent(Painter &, LyXFont const & font) const;
+       ///
+       int descent(Painter &, LyXFont const & font) const;
+       ///
+       int width(Painter &, LyXFont const & font) const;
+       ///
+       void draw(Painter &, LyXFont const & font,
+                 int baseline, float & x) const;
+#else
        ///
        int Ascent(LyXFont const & font) const;
        ///
@@ -32,6 +43,7 @@ public:
        int Width(LyXFont const & font) const;
        ///
        void Draw(LyXFont font, LyXScreen & scr, int baseline, float & x);
+#endif
        ///
        void Write(ostream &);
        ///
index 26bc362f6702870972bd881b1ed1f7e66a7dfc61..7b8eb3e7ef0758963d70750c676301f38a919b88 100644 (file)
@@ -472,6 +472,23 @@ void BibitemUpdate(Combox * combox)
 
 
 // ale070405 This function maybe shouldn't be here. We'll fix this at 0.13.
+#ifdef USE_PAINTER
+int bibitemMaxWidth(Painter & pain, LyXFont const & font)
+{
+       int w = 0;
+       // Does look like a hack? It is! (but will change at 0.13)
+       LyXParagraph * par = current_view->buffer()->paragraph;
+    
+       while (par) {
+               if (par->bibkey) {
+                       int wx = par->bibkey->width(pain, font);
+                       if (wx > w) w = wx;
+               }
+               par = par->next;
+       }
+       return w;
+}
+#else
 int bibitemMaxWidth(LyXFont const & font)
 {
        int w = 0;
@@ -487,9 +504,36 @@ int bibitemMaxWidth(LyXFont const & font)
        }
        return w;
 }
+#endif
 
 
-// ale070405 
+// ale070405
+#ifdef USE_PAINTER
+string bibitemWidthest(Painter & pain)
+{
+       int w = 0;
+       // Does look like a hack? It is! (but will change at 0.13)
+       LyXParagraph * par = current_view->buffer()->paragraph;
+       InsetBibKey * bkey = 0;
+       LyXFont font;
+      
+       while (par) {
+               if (par->bibkey) {
+                       int wx = par->bibkey->width(pain, font);
+                       if (wx > w) {
+                               w = wx;
+                               bkey = par->bibkey;
+                       }
+               }
+               par = par->next;
+       }
+    
+       if (bkey && !bkey->getScreenLabel().empty())
+               return bkey->getScreenLabel();
+    
+       return "99";
+}
+#else
 string bibitemWidthest()
 {
        int w = 0;
@@ -514,3 +558,4 @@ string bibitemWidthest()
     
        return "99";
 }
+#endif
index 0c023f6051e65365d6f941a26c8acdab0e7f4563..04ec9d3d5ec987643525d6460359ff407a6ea794 100644 (file)
@@ -5,7 +5,7 @@
  *           LyX, The Document Processor
  *      
  *           Copyright 1995 Matthias Ettrich
- *           Copyright 1995-1999 The LyX Team.
+ *           Copyright 1995-2000 The LyX Team.
  * 
  * ====================================================== */
 
index 9f85c9ea5c786c8d22b49e9770021f4d2de6464b..1b0566ff05a9863baf56ab6d816120fab3836833 100644 (file)
@@ -17,6 +17,7 @@
 #include "insetcommand.h"
 #include "lyxdraw.h"
 #include "debug.h"
+#include "Painter.h"
 
 InsetCommand::InsetCommand()
 {
@@ -30,22 +31,49 @@ InsetCommand::InsetCommand(string const & cmd, string const & arg,
 }
 
 
+#ifdef USE_PAINTER
+int InsetCommand::ascent(Painter &, LyXFont const & font) const
+{
+       LyXFont f = font;
+       f.decSize();
+       return f.maxAscent() + 3;
+}
+#else
 int InsetCommand::Ascent(LyXFont const & font) const
 {
        LyXFont f = font;
        f.decSize();
        return f.maxAscent() + 3;
 }
+#endif
 
 
+#ifdef USE_PAINTER
+int InsetCommand::descent(Painter &, LyXFont const & font) const
+{
+       LyXFont f = font;
+       f.decSize();
+       return f.maxDescent() + 3;
+}
+#else
 int InsetCommand::Descent(LyXFont const & font) const
 {
        LyXFont f = font;
        f.decSize();
        return f.maxDescent() + 3;
 }
+#endif
 
 
+#ifdef USE_PAINTER
+int InsetCommand::width(Painter &, LyXFont const & font) const
+{
+       LyXFont f = font;
+       f.decSize();
+       string s = getScreenLabel();
+       return 10 + f.stringWidth(s);
+}
+#else
 int InsetCommand::Width(LyXFont const & font) const
 {
        LyXFont f = font;
@@ -53,8 +81,44 @@ int InsetCommand::Width(LyXFont const & font) const
        string s = getScreenLabel();
        return 10 + f.stringWidth(s);
 }
+#endif
 
 
+#ifdef USE_PAINTER
+void InsetCommand::draw(Painter & pain, LyXFont const & font,
+                       int baseline, float & x) const
+{
+       // Draw it as a box with the LaTeX text
+       x += 3;
+
+       pain.fillRectangle(int(x), baseline - ascent(pain, font) + 1,
+                          width(pain, font) - 6,
+                          ascent(pain, font) + descent(pain, font) - 2,
+                          LColor::insetbg);
+        // Tell whether this slows down the drawing  (ale)
+       // lets draw editable and non-editable insets differently
+        if (Editable()) {
+               int y = baseline - ascent(pain, font) + 1;
+               int w = width(pain, font) - 6;
+               int h = ascent(pain, font) + descent(pain, font) - 2;
+               pain.rectangle(int(x), y, w, h, LColor::insetframe);
+       } else {
+               
+               pain.rectangle(int(x), baseline - ascent(pain, font) + 1,
+                              width(pain, font) - 6,
+                              ascent(pain, font) + descent(pain, font) - 2,
+                              LColor::insetframe); 
+       }
+        string s = getScreenLabel();
+               LyXFont f(font);
+       f.decSize();
+       f.setColor(LColor::none);
+       f.setLatex(LyXFont::OFF);
+       pain.text(int(x + 2), baseline, s, f);
+       
+       x +=  width(pain, font) - 3;
+}
+#else
 void InsetCommand::Draw(LyXFont font, LyXScreen & scr,
                      int baseline, float & x)
 {
@@ -86,6 +150,7 @@ void InsetCommand::Draw(LyXFont font, LyXScreen & scr,
 
        x +=  Width(font) - 3;
 }
+#endif
 
 
 // In lyxf3 this will be just LaTeX
index af2c590412fea63bc1f543f7fad91e731e935e51..c271b9f331c85cd096162ae4e04fbb64d002eef3 100644 (file)
@@ -4,8 +4,8 @@
  *
  *           LyX, The Document Processor
  *      
- *         Copyright 1995 Matthias Ettrich
- *          Copyright 1996-2000 The LyX Team.
+ *           Copyright 1995 Matthias Ettrich
+ *           Copyright 1995-2000 The LyX Team.
  *
  * ====================================================== */
 
@@ -32,6 +32,16 @@ public:
        ///
        InsetCommand(string const & name, string const & arg = string(), 
                     string const & opt = string());
+#ifdef USE_PAINTER
+       ///
+       int ascent(Painter &, LyXFont const &) const;
+       ///
+       int descent(Painter &, LyXFont const &) const;
+       ///
+       int width(Painter &, LyXFont const &) const;
+       ///
+       void draw(Painter &, LyXFont const &, int baseline, float & x) const;
+#else
        ///
        int Ascent(LyXFont const & font) const;
        ///
@@ -40,6 +50,7 @@ public:
        int Width(LyXFont const & font) const;
        ///
        void Draw(LyXFont, LyXScreen & scr, int baseline, float & x);
+#endif
        ///
        void Write(ostream &);
        /// Parse the command.
index 74c0cc7c793e953d00f6ba05b5fcd0af1f5a4562..163c7275eca51fd615e31d092876a72373627457 100644 (file)
@@ -18,6 +18,7 @@
 #include "lyxdraw.h"
 #include "gettext.h"
 #include "lyx_gui_misc.h" // CancelCloseBoxCB
+#include "Painter.h"
 
 /* Error, used for the LaTeX-Error Messages */
 
@@ -44,30 +45,80 @@ InsetError::~InsetError()
 }
 
 
+#ifdef USE_PAINTER
+int InsetError::ascent(Painter &, LyXFont const & font) const
+{
+       LyXFont efont;
+       efont.setSize(font.size()).decSize();
+       return efont.maxAscent() + 1;
+}
+#else
 int InsetError::Ascent(LyXFont const & font) const
 {
        LyXFont efont;
        efont.setSize(font.size()).decSize();
        return efont.maxAscent()+1;
 }
+#endif
 
 
+#ifdef USE_PAINTER
+int InsetError::descent(Painter &, LyXFont const & font) const
+{
+       LyXFont efont;
+       efont.setSize(font.size()).decSize();
+       return efont.maxDescent() + 1;
+}
+#else
 int InsetError::Descent(LyXFont const & font) const
 {
        LyXFont efont;
        efont.setSize(font.size()).decSize();
        return efont.maxDescent()+1;
 }
+#endif
 
 
+#ifdef USE_PAINTER
+int InsetError::width(Painter &, LyXFont const & font) const
+{
+       LyXFont efont;
+       efont.setSize(font.size()).decSize();
+       return 6 + efont.textWidth(_("Error"), strlen(_("Error")));
+}
+#else
 int InsetError::Width(LyXFont const & font) const
 {
        LyXFont efont;
        efont.setSize(font.size()).decSize();
        return 6 + efont.textWidth(_("Error"), strlen(_("Error")));
 }
+#endif
 
 
+#ifdef USE_PAINTER
+void InsetError::draw(Painter & pain, LyXFont const & font,
+                     int baseline, float & x) const
+{
+       LyXFont efont;
+       efont.setSize(font.size()).decSize();
+       efont.setColor(LColor::error);
+   
+       // Draw as "Error" in a framed box
+       x += 1;
+       pain.fillRectangle(int(x), baseline - ascent(pain, font) + 1,
+                         width(pain, font) - 2,
+                         ascent(pain, font) + descent(pain, font) - 2,
+                          LColor::insetbg);
+       pain.rectangle(int(x), baseline - ascent(pain, font) + 1,
+                      width(pain, font) - 2,
+                      ascent(pain, font) + descent(pain, font) - 2,
+                      LColor::error);
+       pain.text(int(x + 2), baseline, _("Error"), efont);
+
+       x +=  width(pain, font) - 1;
+}
+#else
 void InsetError::Draw(LyXFont font, LyXScreen & scr,
                      int baseline, float & x)
 {
@@ -87,7 +138,7 @@ void InsetError::Draw(LyXFont font, LyXScreen & scr,
 
        x +=  Width(font) - 1;
 }
-
+#endif
 
 void InsetError::Write(ostream &)
 {
index 4179e6cb7870b26d32e140d97beb9448e54d56df..998a755cfcaed778e4b0d6334318e344c83a3a27 100644 (file)
@@ -4,7 +4,8 @@
  *
  *           LyX, The Document Processor
  *      
- *         Copyright (C) 1995 Matthias Ettrich
+ *           Copyright 1995 Matthias Ettrich
+ *           Copyright 1995-2000 The LyX Team. 
  *
  * ====================================================== */
 
@@ -33,6 +34,17 @@ public:
        InsetError();
        ///
        ~InsetError();
+#ifdef USE_PAINTER
+       ///
+       int ascent(Painter &, LyXFont const & font) const;
+       ///
+       int descent(Painter &, LyXFont const & font) const;
+       ///
+       int width(Painter &, LyXFont const & font) const;
+       ///
+       void draw(Painter &, LyXFont const & font,
+                 int baseline, float & x) const;
+#else
        ///
        int Ascent(LyXFont const & font) const;
        ///
@@ -41,6 +53,7 @@ public:
        int Width(LyXFont const & font) const;
        ///
        void Draw(LyXFont font, LyXScreen & scr, int baseline, float & x);
+#endif
        ///
        void Write(ostream &);
        ///
index 24cc383658b850f54c8fbafc9db55ccd99471fb5..ba8dce83c0b70c6bfdb77508ac210f8c9cccbadc 100644 (file)
@@ -24,6 +24,7 @@
 #include "lyx_gui_misc.h" // CancelCloseBoxCB
 #include "buffer.h"
 #include "support/lstrings.h"
+#include "Painter.h"
 
 /* Info, used for the Info boxes */
 
@@ -53,24 +54,67 @@ InsetInfo::~InsetInfo()
 }
 
 
+#ifdef USE_PAINTER
+int InsetInfo::ascent(Painter &, LyXFont const & font) const
+{
+       return font.maxAscent() + 1;
+}
+#else
 int InsetInfo::Ascent(LyXFont const & font) const
 {
        return font.maxAscent() + 1;
 }
+#endif
 
 
+#ifdef USE_PAINTER
+int InsetInfo::descent(Painter &, LyXFont const & font) const
+{
+       return font.maxDescent() + 1;
+}
+#else
 int InsetInfo::Descent(LyXFont const & font) const
 {
        return font.maxDescent() + 1;
 }
+#endif
 
 
+#ifdef USE_PAINTER
+int InsetInfo::width(Painter &, LyXFont const & font) const
+{
+       return 6 + font.textWidth(_("Note"), strlen(_("Note")));
+}
+#else
 int InsetInfo::Width(LyXFont const & font) const
 {
        return 6 + font.textWidth(_("Note"), strlen(_("Note")));
 }
+#endif
+
 
+#ifdef USE_PAINTER
+void InsetInfo::draw(Painter & pain, LyXFont const & f,
+                    int baseline, float & x) const
+{
+       LyXFont font(f);
+       
+       /* Info-insets are never LaTeX, so just correct the font */
+       font.setLatex(LyXFont::OFF);
 
+       // Draw as "Note" in a yellow box
+       x += 1;
+       pain.fillRectangle(int(x), baseline - ascent(pain, font) + 1,
+                          width(pain, font) - 2,
+                          ascent(pain, font) + descent(pain, font) - 2);
+       pain.rectangle(int(x), baseline - ascent(pain, font) + 1,
+                      width(pain, font) - 2,
+                      ascent(pain, font) + descent(pain, font) - 2);
+       
+       pain.text(int(x + 2), baseline, _("Note"), font);
+       x +=  width(pain, font) - 1;
+}
+#else
 void InsetInfo::Draw(LyXFont font, LyXScreen & scr,
                     int baseline, float & x)
 {
@@ -89,6 +133,7 @@ void InsetInfo::Draw(LyXFont font, LyXScreen & scr,
        scr.drawString(font, _("Note"), baseline, int(x+2));
        x +=  Width(font) - 1;
 }
+#endif
 
 
 void InsetInfo::Write(ostream & os)
index b4f9fe9dbb5a1ff893d695577ff2d9654508f9b9..170d729c815b732d3bf87f5820207156b7b45426 100644 (file)
@@ -36,6 +36,16 @@ public:
        InsetInfo(string const & string);
        ///
        ~InsetInfo();
+#ifdef USE_PAINTER
+       ///
+       int ascent(Painter &, LyXFont const &) const;
+       ///
+       int descent(Painter &, LyXFont const &) const;
+       ///
+       int width(Painter &, LyXFont const &) const;
+       ///
+       void draw(Painter &, LyXFont const &, int baseline, float & x) const;
+#else
        ///
        int Ascent(LyXFont const & font) const;
        ///
@@ -44,6 +54,7 @@ public:
        int Width(LyXFont const & font) const;
        ///
        void Draw(LyXFont font, LyXScreen & scr, int baseline, float & x);
+#endif
        ///
        void Write(ostream &);
        ///
index 4693c2eaa64f6decda718cc6563c6f2db0055d4d..dd97fcf5859d4d0d434f9e5ac758b9fd4705edb5 100644 (file)
@@ -19,6 +19,7 @@
 #include "lyxrc.h"
 #include "lyxdraw.h"
 #include "support/lstrings.h"
+#include "Painter.h"
 
 extern LyXRC * lyxrc;
 
@@ -252,6 +253,26 @@ void InsetLatexAccent::checkContents()
 }
 
 
+#ifdef USE_PAINTER
+int InsetLatexAccent::ascent(Painter &, LyXFont const & font) const
+{
+       // This function is a bit too simplistix and is just a
+       // "try to make a fit for all accents" approach, to
+       // make it better we need to know what kind of accent is
+       // used and add to max based on that.
+       int max;
+       if (candisp) {
+               if (ic == ' ')
+                       max = font.ascent('a');
+               else
+                       max = font.ascent(ic);
+               if (plusasc) 
+                       max += (font.maxAscent() + 3) / 3;
+       } else
+               max = font.maxAscent() + 4;
+       return max;
+}
+#else
 int InsetLatexAccent::Ascent(LyXFont const & font) const
 {
        // This function is a bit too simplistix and is just a
@@ -270,8 +291,25 @@ int InsetLatexAccent::Ascent(LyXFont const & font) const
                max = font.maxAscent() + 4;
        return max;
 }
+#endif
 
 
+#ifdef USE_PAINTER
+int InsetLatexAccent::descent(Painter &, LyXFont const & font) const
+{
+       int max;
+       if (candisp) {
+               if (ic == ' ') 
+                       max = font.descent('a');
+                else
+                       max = font.descent(ic);
+                if (plusdesc)
+                       max += 3;
+       } else
+               max = font.maxDescent() + 4;
+       return max;
+}
+#else
 int InsetLatexAccent::Descent(LyXFont const & font) const
 {
        int max;
@@ -286,8 +324,18 @@ int InsetLatexAccent::Descent(LyXFont const & font) const
                max = font.maxDescent() + 4;
        return max;
 }
+#endif
 
 
+#ifdef USE_PAINTER
+int InsetLatexAccent::width(Painter &, LyXFont const & font) const
+{
+       if (candisp)
+               return font.textWidth(&ic, 1);
+        else
+                return font.stringWidth(contents) + 4;
+}
+#else
 int InsetLatexAccent::Width(LyXFont const & font) const
 {
        if (candisp)
@@ -295,6 +343,7 @@ int InsetLatexAccent::Width(LyXFont const & font) const
         else
                 return font.stringWidth(contents) + 4;
 }
+#endif
 
 
 int InsetLatexAccent::Lbearing(LyXFont const & font) const
@@ -309,6 +358,49 @@ int InsetLatexAccent::Rbearing(LyXFont const & font) const
 }
 
 
+#ifdef USE_PAINTER
+bool InsetLatexAccent::DisplayISO8859_9(Painter & pain, LyXFont const & font,
+                                       int baseline, 
+                                       float & x) const
+{
+       unsigned char tmpic = ic;
+       
+       switch (modtype) {
+       case CEDILLA:
+       {
+               if (ic == 'c') tmpic = 0xe7;
+               if (ic == 'C') tmpic = 0xc7;
+               if (ic == 's') tmpic = 0xfe;
+               if (ic == 'S') tmpic = 0xde;
+               break;
+       }
+       case BREVE:
+       {       if (ic == 'g') tmpic = 0xf0;
+       if (ic == 'G') tmpic = 0xd0;
+       break;
+       }
+       case UMLAUT:
+       {
+               if (ic == 'o') tmpic = 0xf6;
+               if (ic == 'O') tmpic = 0xd6;
+               if (ic == 'u') tmpic = 0xfc;
+               if (ic == 'U') tmpic = 0xdc;
+               break;
+       }
+       case DOT:        if (ic == 'I') tmpic = 0xdd; break;
+       case DOT_LESS_I: tmpic = 0xfd; break;
+       default:         return false;
+       }
+       if (tmpic != ic) {
+               char ch = char(tmpic);
+               pain.text(x, baseline, ch, font);
+               x += width(pain, font);
+               return true;
+       }
+       else
+               return false;
+}
+#else
 bool InsetLatexAccent::DisplayISO8859_9(LyXFont font,
                                        LyXScreen & scr,
                                        int baseline, 
@@ -351,8 +443,314 @@ bool InsetLatexAccent::DisplayISO8859_9(LyXFont font,
        else
                return false;
 }
+#endif
+
+
+#ifdef USE_PAINTER
+void InsetLatexAccent::draw(Painter & pain, LyXFont const & font,
+                           int baseline, float & x) const
+{
+       if (lyxrc->font_norm == "iso8859-9")
+               if (DisplayISO8859_9(pain, font, baseline, x))  
+                       return;
+       
+       /* draw it! */ 
+       // All the manually drawn accents in this function could use an
+       // overhaul. Different ways of drawing (what metrics to use)
+       // should also be considered.
+       
+       if (candisp) {
+               int asc = ascent(pain, font);
+               int desc = descent(pain, font);
+               int wid = width(pain, font);
+               float x2 = x + (Rbearing(font) - Lbearing(font)) / 2.0;
+               float hg;
+               int y;
+               if (plusasc) {
+                       // mark at the top
+                       hg = font.maxDescent();
+                       y = baseline - asc;
+
+                       if (font.shape() == LyXFont::ITALIC_SHAPE)
+                               x2 += (4.0 * hg) / 5.0; // italic
+               } else {
+                       // at the bottom
+                       hg = desc;
+                       y = baseline;
+               }
 
+               float hg35 = float(hg * 3.0) / 5.0;
 
+               // display with proper accent mark
+               // first the letter
+               pain.text(int(x), baseline, ic, font);
+
+#if 0
+               GC pgc = GetAccentGC(font, int((hg + 3.0) / 5.0));
+#endif
+
+               if (remdot) {
+                       int tmpvar = baseline - font.ascent('i');
+                       float tmpx = 0;
+                       if (font.shape() == LyXFont::ITALIC_SHAPE)
+                               tmpx += (8.0 * hg) / 10.0; // italic
+                       lyxerr[Debug::KEY] << "Removing dot." << endl;
+                       // remove the dot first
+                       pain.fillRectangle(int(x + tmpx), tmpvar, wid,
+                                          font.ascent('i') -
+                                          font.ascent('x') - 1,
+                                          LColor::background);
+                       // the five lines below is a simple hack to
+                       // make the display of accent 'i' and 'j'
+                       // better. It makes the accent be written
+                       // closer to the top of the dot-less 'i' or 'j'.
+                       char tmpic = ic; // store the ic when we
+                       ic = 'x';        // calculates the ascent of
+                       asc = ascent(pain, font); // the dot-less version (here: 'x')
+                       ic = tmpic;      // set the orig ic back
+                       y = baseline - asc; // update to new y coord.
+               }
+               // now the rest - draw within (x, y, x+wid, y+hg)
+               switch (modtype) {
+               case ACUTE:     // acute
+               {
+                       pain.line(int(x2), int(y + hg),
+                                 int(x2 + hg35), y + hg35);
+                       break;
+               }
+               case GRAVE:     // grave
+               {
+                       pain.line(int(x2), int(y + hg),
+                                 int(x2 - hg35), y + hg35);
+                       break;
+               }
+               case MACRON:     // macron
+               {
+                       pain.line(int(x2 - wid * 0.4),
+                                 int(y + hg),
+                                 int(x2 + wid * 0.4),
+                                 int(y + hg));
+                       break;
+               }
+               case TILDE:     // tilde
+               {
+                       if (hg35 > 2.0) hg35 -= 1.0;
+                       x2 += (hg35 / 2.0);
+                       int xp[4], yp[4];
+                       
+                       xp[0] = int(x2 - 2.0 * hg35);
+                       yp[0] = int(y + hg);
+                       
+                       xp[1] = int(x2 - hg35);
+                       yp[1] = int(y + hg35);
+                       
+                       xp[2] = int(x2);
+                       yp[2] = int(y + hg);
+                       
+                       xp[3] = int(x2 + hg35);
+                       yp[3] = int(y + hg35);
+                       
+                       pain.lines(xp, yp, 4);
+                       break;
+               }
+               case UNDERBAR:     // underbar
+               {
+                       pain.line(int(x2 - wid * 0.4),
+                                 y + hg / 2.0,
+                                 int(x2 + wid * 0.4),
+                                 y + hg / 2.0);
+                       break;
+               }
+               case CEDILLA:     // cedilla
+               {
+                       int xp[4], yp[4];
+                       
+                       xp[0] = int(x2);
+                       yp[0] = y;
+                       
+                       xp[1] = int(x2);
+                       yp[1] = y + int(hg / 3.0);
+                       
+                       xp[2] = int(x2 + (hg / 3.0));
+                       yp[2] = y + int(hg / 2.0);
+                       
+                       xp[3] = int(x2 - (hg / 4.0));
+                       yp[3] = y + int(hg);
+
+                       pain.lines(xp, yp, 4);
+                       break;
+               }
+               case UNDERDOT:     // underdot
+               {
+                       pain.arc(int(x2), y + hg35,
+                                    3, 3, 0, 360 * 64);
+                       break;
+               }
+
+               case DOT:    // dot
+               {
+                       pain.arc(int(x2), y + hg * 0.5,
+                                    (hg + 3.0)/5.0,
+                                    (hg + 3.0)/5.0,
+                                    0, 360 * 64);
+                       break;
+               }
+
+               case CIRCLE:     // circle
+               {
+                       pain.arc(int(x2 - (hg / 2.0)),
+                                y + (hg / 2.0), hg, hg , 0,
+                                360 * 64);
+                       break;
+               }
+               case TIE:     // tie
+               {
+                       pain.arc(int(x2 + hg35), y + hg / 2.0,
+                                2 * hg, hg, 0, 360 * 32);
+                       break;
+               }
+               case BREVE:     // breve
+               {
+                       pain.arc(int(x2 - (hg / 2.0)), y,
+                                hg, hg, 0, -360*32);
+                       break;
+               }
+               case CARON:    // caron
+               {
+                       int xp[3], yp[3];
+                       
+                       xp[0] = int(x2 - hg35); yp[0] = int(y + hg35);
+                       xp[1] = int(x2);        yp[1] = int(y + hg);
+                       xp[2] = int(x2 + hg35); yp[2] = int(y + hg35);
+                       pain.lines(xp, yp, 3);
+                       break;
+               }
+               case SPECIAL_CARON:    // special caron
+               {
+                       switch (ic) {
+                       case 'L': wid = int(4.0 * wid / 5.0); break;
+                       case 't': y -= int(hg35 / 2.0); break;
+                       }
+                       int xp[3], yp[3];
+                       xp[0] = int(x + wid);
+                       yp[0] = int(y + hg35 + hg);
+                       
+                       xp[1] = int(x + wid + (hg35 / 2.0));
+                       yp[1] = int(y + hg + (hg35 / 2.0));
+                       
+                       xp[2] = int(x + wid + (hg35 / 2.0));
+                       yp[2] = y + int(hg);
+
+                       pain.lines(xp, yp, 3);
+                       break;
+               }
+               case HUNGARIAN_UMLAUT:    // hung. umlaut
+               {
+                       int xs1[2], xs2[2], ys1[2], ys2[2];
+                       
+                       xs1[0] = int(x2 - (hg / 2.0));
+                       ys1[0] = int(y + hg);
+                       
+                       xs2[0] = int(x2 + hg35 - (hg / 2.0));
+                       ys2[0] = int(y + hg35);
+                       
+                       xs1[1] = int(x2 + (hg / 2.0));
+                       ys1[1] = int(y + hg);
+                       
+                       xs2[1] = int(x2 + hg35 + (hg / 2.0));
+                       ys2[1] = int(y + hg35);
+
+                       pain.segments(xs1, ys1, xs2, ys2, 2);
+                       break;
+               }
+               case UMLAUT:    // umlaut
+               {
+                       float rad = hg / 2.0;
+                       if (rad <= 1.0) {
+                               pain.point(int(x2 - 4.0 * hg / 7.0),
+                                          y + hg35);
+                               pain.point(int(x2 + 4.0 * hg / 7.0),
+                                          y + hg35);
+                       } else {
+                               rad += .5; // this ensures that f.ex. 1.5 will
+                               // not be rounded down to .5 and then
+                               // converted to int = 0
+                               pain.arc(int(x2 - 2.0 * hg / 4.0),
+                                            y + hg35,
+                                            rad, rad,
+                                            0, 360 * 64);
+                               pain.arc(int(x2 + 2.0 * hg / 4.0),
+                                           y + hg35,
+                                           rad, rad, 0, 360*64);
+                       }
+                       break;
+               }
+               case CIRCUMFLEX:    // circumflex
+               {
+                       int xp[3], yp[3];
+                       
+                       xp[0] = int(x2 - hg35); yp[0] = y + int(hg);
+                       xp[1] = int(x2);        yp[1] = int(y + hg35);
+                       xp[2] = int(x2 + hg35); yp[2] = y + int(hg);
+                       pain.lines(xp, yp, 3);
+                       break;
+               }
+               case OGONEK:    // ogonek
+               {
+                       // this does probably not look like an ogonek, so
+                       // it should certainly be refined
+                       int xp[4], yp[4];
+                       
+                       xp[0] = int(x2);
+                       yp[0] = y;
+                       
+                       xp[1] = int(x2);
+                       yp[1] = y + int(hg35);
+                       
+                       xp[2] = int(x2 - hg35);
+                       yp[2] = y + int(hg / 2.0);
+                       
+                       xp[3] = int(x2 + hg / 4.0);
+                       yp[3] = y + int(hg);
+
+                       pain.lines(xp, yp, 4);
+                       break;
+               }
+               case lSLASH:
+               case LSLASH:
+               {
+                       int xp[2], yp[2];
+                       
+                       xp[0] = int(x);
+                       yp[0] = y + int(3.0 * hg);
+                       
+                       xp[1] = int(x + float(wid) * 0.75);
+                       yp[1] = y + int(hg);
+                       
+                       pain.lines(xp, yp, 2);
+                       break;
+               }
+               case DOT_LESS_I: // dotless-i
+               case DOT_LESS_J: // dotless-j
+               {
+                       // nothing to do for these
+                       break;
+               }
+               }
+       } else {
+               pain.fillRectangle(int(x + 1),
+                                  baseline - ascent(pain, font) + 1,
+                                  width(pain, font) - 2,
+                                  ascent(pain, font)
+                                  + descent(pain, font) - 2);
+               pain.rectangle(int(x + 1), baseline - ascent(pain, font) + 1,
+                              width(pain, font) - 2,
+                              ascent(pain, font) + descent(pain, font) - 2);
+               pain.text(int(x + 2), baseline, contents, font);
+       }
+       x +=  width(pain, font);
+}
+#else
 void InsetLatexAccent::Draw(LyXFont font,
                            LyXScreen & scr,
                            int baseline, 
@@ -462,7 +860,6 @@ void InsetLatexAccent::Draw(LyXFont font,
                }
                case CEDILLA:     // cedilla
                {
-#if 1
                        XPoint p[4];
                        p[0].x = int(x2);          p[0].y = y;
                        p[1].x = int(x2);          p[1].y = y + int(hg / 3.0);
@@ -470,44 +867,28 @@ void InsetLatexAccent::Draw(LyXFont font,
                        p[2].y = y + int(hg / 2.0);
                        p[3].x = int(x2 - (hg / 4.0)); p[3].y = y + int(hg);
                        scr.drawLines(pgc, p, 4);
-#endif
-                       //scr.drawLine(pgc,
-                       //           x2, y,
-                       //           x2 - hg / 4.0, y + hg);
-                       // and then we need a circle thingie.
-                       // ...
                        break;
                }
                case UNDERDOT:     // underdot
                {
-#if 1
                        scr.fillArc(pgc, int(x2), y + hg35,
                                    3, 3, 0, 360*64);
-#endif
-                       //scr.drawText(font, "·", 1, y + 2 * hg, x2);
                        break;
                }
 
                case DOT:    // dot
                {
-#if 1
                        scr.fillArc(pgc, int(x2), y + hg * 0.5,
                                    (hg + 3.0)/5.0,
                                    (hg + 3.0)/5.0, 0, 360*64);
-#endif
-                       //scr.drawText(font, "·", 1, y + 2.0 * hg, x2);
                        break;
                }
 
                case CIRCLE:     // circle
                {
-#if 1
                        scr.drawArc(pgc, int(x2 - (hg / 2.0)),
                                    y + (hg / 2.0), hg, hg, 0,
                                    360*64);
-#endif
-                       //scr.drawText(font, "°", 1, y + 2.0 * hg, x2);
-                       
                        break;
                }
                case TIE:     // tie
@@ -640,6 +1021,7 @@ void InsetLatexAccent::Draw(LyXFont font,
        }
        x +=  Width(font);
 }
+#endif
 
 
 void InsetLatexAccent::Write(ostream & os)
index 297c6f9e8483b7b465351b8aa6ad13f386b3111e..b8085e016b017d1bfa49694ab57de6573e354c01 100644 (file)
@@ -33,21 +33,38 @@ public:
        InsetLatexAccent(); 
        ///
        InsetLatexAccent(string const & string);
+#ifdef USE_PAINTER
+       ///
+       int ascent(Painter &, LyXFont const &) const;
+       ///
+       int descent(Painter &, LyXFont const &) const;
+       ///
+       int width(Painter &, LyXFont const &) const;
+       ///
+       void draw(Painter &, LyXFont const &, int baseline, float & x) const;
+#else
        ///
        int Ascent(LyXFont const & font) const;
        ///
        int Descent(LyXFont const & font) const;
        ///
        int Width(LyXFont const & font) const;
+       ///
+       void Draw(LyXFont, LyXScreen & scr, int baseline, float & x);
+#endif
        ///
        int Lbearing(LyXFont const & font) const;
        ///
        int Rbearing(LyXFont const & font) const;
+#ifdef USE_PAINTER
+       ///
+       bool DisplayISO8859_9(Painter &, LyXFont const & font,
+                             int baseline, float & x) const;
+#else
        ///
        bool DisplayISO8859_9(LyXFont font, LyXScreen & scr,
                              int baseline, float & x);
-       ///
-       void Draw(LyXFont font, LyXScreen & scr, int baseline, float & x);
+#endif
        ///
        void Write(ostream &);
        ///
@@ -133,7 +150,7 @@ private:
        /// add something to descent - underlined char
        bool  plusdesc;
        /// international char
-       char  ic;    
+       mutable char  ic;    
 };
 
 bool InsetLatexAccent::CanDisplay()
index d069cc2d6b9836ada42f5b76c1ab500f8c448957..b7a4da1c63dc23011b76043e757aeb7c3c33ac8d 100644 (file)
@@ -22,6 +22,7 @@
 #include "buffer.h"
 #include "LaTeXFeatures.h"
 #include "support/lstrings.h"
+#include "Painter.h"
 
 // Quotes. Used for the various quotes. German, English, French,
 // Danish, Polish, all either double or single.
@@ -155,18 +156,50 @@ string InsetQuotes::DispString() const
 }
 
 
+#ifdef USE_PAINTER
+int InsetQuotes::ascent(Painter &, LyXFont const & font) const
+{
+       return font.maxAscent();
+}
+#else
 int InsetQuotes::Ascent(LyXFont const & font) const
 {
        return font.maxAscent();
 }
+#endif
 
 
+#ifdef USE_PAINTER
+int InsetQuotes::descent(Painter &, LyXFont const & font) const
+{
+       return font.maxDescent();
+}
+#else
 int InsetQuotes::Descent(LyXFont const & font) const
 {
        return font.maxDescent();
 }
+#endif
 
 
+#ifdef USE_PAINTER
+int InsetQuotes::width(Painter &, LyXFont const & font) const
+{
+       string text = DispString();
+       int w = 0;
+
+       for (string::size_type i = 0; i < text.length(); ++i) {
+               if (text[i] == ' ')
+                       w += font.width('i');
+               else if (i == 0 || text[i] != text[i-1])
+                       w += font.width(text[i]);
+               else
+                       w += font.width(',');
+       }
+
+       return w;
+}
+#else
 int InsetQuotes::Width(LyXFont const & font) const
 {
        string text = DispString();
@@ -183,6 +216,7 @@ int InsetQuotes::Width(LyXFont const & font) const
 
        return w;
 }
+#endif
 
 
 LyXFont InsetQuotes::ConvertFont(LyXFont font)
@@ -193,6 +227,16 @@ LyXFont InsetQuotes::ConvertFont(LyXFont font)
 }
 
 
+#ifdef USE_PAINTER
+void InsetQuotes::draw(Painter & pain, LyXFont const & font,
+                      int baseline, float & x) const
+{
+       string text = DispString();
+
+       pain.text(int(x), baseline, text, font);
+       x += width(pain, font);
+}
+#else
 void InsetQuotes::Draw(LyXFont font, LyXScreen & scr,
                       int baseline, float & x)
 {
@@ -201,6 +245,7 @@ void InsetQuotes::Draw(LyXFont font, LyXScreen & scr,
        scr.drawString(font, text, baseline, int(x));
        x += Width(font);
 }
+#endif
 
 
 void InsetQuotes::Write(ostream & os)
index 006b519e76f37aa7a02ef194c773786eb9052fa2..abd48cdfe4dc7fd449a787c95d63288909fbaec8 100644 (file)
@@ -70,6 +70,16 @@ public:
        /// Create the right quote inset after character c
        InsetQuotes(char c, BufferParams const & params);
 
+#ifdef USE_PAINTER
+       ///
+       int ascent(Painter &, LyXFont const &) const;
+       ///
+       int descent(Painter &, LyXFont const &) const;
+       ///
+       int width(Painter &, LyXFont const &) const;
+       ///
+       void draw(Painter &, LyXFont const &, int baseline, float & x) const;
+#else
        ///
        int Ascent(LyXFont const & font) const;
        ///
@@ -78,6 +88,7 @@ public:
        int Width(LyXFont const & font) const;
        ///
        void Draw(LyXFont font, LyXScreen & scr, int baseline, float & x);
+#endif
        ///
        LyXFont ConvertFont(LyXFont font);
        ///
index f1074c604f4b0d5276ae906f46f90adb8e28f296..3b831ed654accfbfb23fd4514f02b93ad501021b 100644 (file)
 #include "lyxdraw.h"
 #include "debug.h"
 #include "LaTeXFeatures.h"
+#include "Painter.h"
 
 InsetSpecialChar::InsetSpecialChar(Kind k)
        : kind(k)
 {}
 
 
+#ifdef USE_PAINTER
+int InsetSpecialChar::ascent(Painter &, LyXFont const & font) const
+{
+       return font.maxAscent();
+}
+#else
 int InsetSpecialChar::Ascent(LyXFont const & font) const
 {
        return font.maxAscent();
 }
+#endif
 
 
+#ifdef USE_PAINTER
+int InsetSpecialChar::descent(Painter &, LyXFont const & font) const
+{
+       return font.maxDescent();
+}
+#else
 int InsetSpecialChar::Descent(LyXFont const & font) const
 {
        return font.maxDescent();
 }
+#endif
 
 
+#ifdef USE_PAINTER
+int InsetSpecialChar::width(Painter &, LyXFont const & font) const
+{
+       LyXFont f(font);
+       switch (kind) {
+       case HYPHENATION:
+       {
+               int w = f.textWidth("-", 1);
+               if (w > 5) 
+                       w -= 2; // to make it look shorter
+               return w;
+       }
+       case END_OF_SENTENCE:
+       {
+               return f.textWidth(".", 1);
+       }
+       case LDOTS:
+       {
+               return f.textWidth(". . .", 5);
+       }
+       case MENU_SEPARATOR: {
+               return f.textWidth(" x ", 3);
+       }
+       }
+       return 1; // To shut up gcc
+}
+#else
 int InsetSpecialChar::Width(LyXFont const & font) const
 {
        LyXFont f = font;
@@ -60,29 +102,76 @@ int InsetSpecialChar::Width(LyXFont const & font) const
        }
        return 1; // To shut up gcc
 }
+#endif
 
 
+#ifdef USE_PAINTER
+void InsetSpecialChar::draw(Painter & pain, LyXFont const & f,
+                           int baseline, float & x) const
+{
+       LyXFont font(f);
+       switch (kind) {
+       case HYPHENATION:
+       {
+               font.setColor(LColor::magenta);
+               pain.text(int(x), baseline, "-", font);
+               x += width(pain, font);
+               break;
+       }
+       case END_OF_SENTENCE:
+       {
+               font.setColor(LColor::magenta);
+               pain.text(int(x), baseline, ".", font);
+               x += width(pain, font);
+               break;
+       }
+       case LDOTS:
+       {
+               font.setColor(LColor::magenta);
+               pain.text(int(x), baseline, ". . .", font);
+               x += width(pain, font);
+               break;
+       }
+       case MENU_SEPARATOR:
+       {
+#if 0
+               // A triangle the width and height of an 'x'
+               int w = font.textWidth("x", 1);
+               int ox = font.textWidth(" ", 1) + int(x);
+               int h = font.ascent('x');
+               XPoint p[4];
+               p[0].x = ox;    p[0].y = baseline;
+               p[1].x = ox;    p[1].y = baseline - h;
+               p[2].x = ox + w;p[2].y = baseline - h/2;
+               p[3].x = ox;    p[3].y = baseline;
+               scr.drawLines(getGC(gc_copy), p, 4);
+#endif
+               x += width(pain, font);
+       }
+       }
+}
+#else
 void InsetSpecialChar::Draw(LyXFont font, LyXScreen & scr,
                            int baseline, float & x)
 {
        switch (kind) {
        case HYPHENATION:
        {
-               font.setColor(LyXFont::MAGENTA);
+               font.setColor(LyXFont::BLUE);
                scr.drawText(font, "-", 1, baseline, int(x));
                x += Width(font);
                break;
        }
        case END_OF_SENTENCE:
        {
-               font.setColor(LyXFont::MAGENTA);
+               font.setColor(LyXFont::BLUE);
                scr.drawText(font, ".", 1, baseline, int(x));
                x += Width(font);
                break;
        }
        case LDOTS:
        {
-               font.setColor(LyXFont::MAGENTA);
+               font.setColor(LyXFont::BLUE);
                scr.drawText(font, ". . .", 5, baseline, int(x));
                x += Width(font);
                break;
@@ -103,6 +192,7 @@ void InsetSpecialChar::Draw(LyXFont font, LyXScreen & scr,
        }
        }
 }
+#endif
 
 
 // In lyxf3 this will be just LaTeX
index 406c793301908d7171807569463c1d6606ca10f4..164ff1085b2ab3d07f57bb3b0a53cbf1ef2c09a9 100644 (file)
@@ -40,6 +40,16 @@ public:
        InsetSpecialChar() {}
        ///
        InsetSpecialChar(Kind k);
+#ifdef USE_PAINTER
+       ///
+       int ascent(Painter &, LyXFont const &) const;
+       ///
+       int descent(Painter &, LyXFont const &) const;
+       ///
+       int width(Painter &, LyXFont const &) const;
+       ///
+       void draw(Painter &, LyXFont const &, int baseline, float & x) const;
+#else
        ///
        int Ascent(LyXFont const & font) const;
        ///
@@ -48,6 +58,7 @@ public:
        int Width(LyXFont const & font) const;
        ///
        void Draw(LyXFont, LyXScreen & scr, int baseline, float & x);
+#endif
        ///
        void Write(ostream &);
        /// Will not be used when lyxf3
index b7478a114faa08ec2f58fcb1e1e311d13bc0d534..f008ea88bfc6f7b9979e1dc587503aea8fa3896f 100644 (file)
@@ -4,7 +4,7 @@
  *
  *           LyX, The Document Processor
  *      
- *         Copyright (C) 1997 LyX Team (this file was created this year)
+ *         Copyright 1997-2000 The LyX Team.
  * 
  * ====================================================== */
 
index 42d37b6b6bf9ded5fed6056dd0e74dc84a97f7a9..5905b7bc16f69d1f78774519f79edabdd55a040b 100644 (file)
 #include "lyxlex.h"
 #include "lyxscreen.h"
 
+//#define USE_PAINTER 1
+
+#ifdef USE_PAINTER
+class Painter;
+#endif
 
 class Buffer;
 struct LaTeXFeatures;
@@ -80,6 +85,17 @@ public:
 
        ///
        virtual ~Inset() {}
+#ifdef USE_PAINTER
+       ///
+       virtual int ascent(Painter &, LyXFont const &) const = 0;
+       ///
+       virtual int descent(Painter &, LyXFont const &) const = 0;
+       ///
+       virtual int width(Painter &, LyXFont const &) const = 0;
+       ///
+       virtual void draw(Painter &, LyXFont const &,
+                         int baseline, float & x) const = 0;
+#else
        ///
        virtual int Ascent(LyXFont const & font) const = 0;
        ///
@@ -87,10 +103,11 @@ public:
        ///
        virtual int Width(LyXFont const & font) const = 0;
        ///
-       virtual LyXFont ConvertFont(LyXFont font);
-       ///
        virtual void Draw(LyXFont font, LyXScreen & scr,
                          int baseline, float & x) = 0;
+#endif
+       ///
+       virtual LyXFont ConvertFont(LyXFont font);
        /// what appears in the minibuffer when opening
        virtual char const * EditMessage() const {return _("Opened inset");}
        ///
@@ -200,6 +217,6 @@ public:
        bool isCursorVisible() const { return cursor_visible; }
 protected:
        ///
-       bool cursor_visible;
+       mutable bool cursor_visible;
 };
 #endif
index 7591c60f97c91dea9d2b6764e0185b625a67083f..f0f6f26b68c96504d1ddf5c336d122577de7acc9 100644 (file)
@@ -244,9 +244,10 @@ void AllowInput()
        if (fd_form_character->form_character->visible)
                XUndefineCursor(fl_display,
                                fd_form_character->form_character->window);
+#ifndef NEW_WA
        if (current_view->getWorkArea()->belowmouse)
                SetXtermCursor(current_view->owner()->getForm()->window);
-
+#endif
        XFlush(fl_display);
        fl_activate_all_forms();
 }
@@ -2270,6 +2271,21 @@ LyXFont UserFreeFont()
        }
 
        pos = fl_get_choice(fd_form_character->choice_color);
+#ifdef USE_PAINTER
+       switch(pos) {
+       case 1: font.setColor(LColor::ignore); break;
+       case 2: font.setColor(LColor::none); break;
+       case 3: font.setColor(LColor::black); break;
+       case 4: font.setColor(LColor::white); break;
+       case 5: font.setColor(LColor::red); break;
+       case 6: font.setColor(LColor::green); break;
+       case 7: font.setColor(LColor::blue); break;
+       case 8: font.setColor(LColor::cyan); break;
+       case 9: font.setColor(LColor::magenta); break;
+       case 10: font.setColor(LColor::yellow); break;
+       case 11: font.setColor(LColor::inherit); break;
+       }
+#else
        switch(pos) {
        case 1: font.setColor(LyXFont::IGNORE_COLOR); break;
        case 2: font.setColor(LyXFont::NONE); break;
@@ -2283,7 +2299,7 @@ LyXFont UserFreeFont()
        case 10: font.setColor(LyXFont::YELLOW); break;
        case 11: font.setColor(LyXFont::INHERIT_COLOR); break;
        }
-
+#endif
        return font; 
 }
 
index b93365bb8287cd37564c8b53cc27ef3aba984e65..594d5aa714d72cb4fc17c93f1bfbd12e91fb2e44 100644 (file)
@@ -297,10 +297,12 @@ void LyXGUI::init()
        // 0.13 it should be moved again...
        lyxserver = new LyXServer(lyxViews->getLyXFunc(), lyxrc->lyxpipes);
 
+#ifndef USE_PAINTER
        // This is to make sure we get the selection color
        getGC(gc_selection);
        // This is to make sure we set the background_pixels
        getGC(gc_clear);
+#endif
 }
 
 
index fe2e9d18597c690a0b51f94a4bea4878ca155d01..44347c107dd5e704c1326bf9fd01842ba3f6c1f7 100644 (file)
@@ -1,5 +1,8 @@
+
 #include <config.h>
 
+#ifndef USE_PAINTER
+
 #include "lyxdraw.h"
 #include "debug.h"
 
@@ -418,7 +421,11 @@ GC GetLightedGC()
 }
 
 
+#ifdef USE_PAINTER
+GC GetColorGC(LColor::color color)
+#else
 GC GetColorGC(LyXFont::FONT_COLOR color)
+#endif
 {
        if (color_gc[color]) return color_gc[color];
                       
@@ -549,3 +556,5 @@ GC getGC(gc_type typ)
        }
        return gc;
 }
+
+#endif
index f50975a7cb7ef0773358561fbf96924449a2490f..6ee8f009412eee63b9f02489ee441ffeac04578f 100644 (file)
@@ -1,4 +1,5 @@
 // -*- C++ -*-
+#ifndef USE_PAINTER
 
 #ifndef LYX_DRAW_H
 #define LYX_DRAW_H
@@ -52,3 +53,5 @@ extern GC GetAccentGC(LyXFont const &f, int line_width);
 extern GC GetColorGC(LyXFont::FONT_COLOR color);
 
 #endif
+
+#endif
index d7231df75a453c7ad2600294a021cfa9f9293203..82c42aec7a26e5231e1edca3a296822433e72280 100644 (file)
@@ -62,11 +62,14 @@ string const GUIMiscNames[5] =
 string const GUIDirectionNames[5] = 
 { N_("LTR"), N_("RTL"), N_("Toggle"), N_("Inherit"), N_("Ignore") };
 
+
+#ifndef USE_PAINTER
 string const GUIColorNames[13] = 
 { N_("None"), N_("Black"), N_("White"), N_("Red"), N_("Green"), N_("Blue"),
   N_("Cyan"), N_("Magenta"), 
   N_("Yellow"), N_("Math"), N_("Inset"), N_("Inherit"), N_("Ignore") };
+#endif
+
 //
 // Strings used to read and write .lyx format files
 //
@@ -87,9 +90,11 @@ string const LyXSizeNames[14] =
 string const LyXMiscNames[12] = 
 { "off", "on", "toggle", "default", "error" };
 
+#ifndef USE_PAINTER
 string const LyXColorNames[13] = 
 { "none", "black", "white", "red", "green", "blue", "cyan", "magenta", 
   "yellow", "matherror", "inseterror", "default", "error" };
+#endif
 
 //
 // Strings used to write LaTeX files
@@ -107,10 +112,59 @@ string const LaTeXShapeNames[6] =
 string const LaTeXSizeNames[14] = 
 { "tiny", "scriptsize", "footnotesize", "small", "normalsize", "large",
   "Large", "LARGE", "huge", "Huge", "error8", "error9", "error10", "error11" };
+
+#ifndef USE_PAINTER
 string const LaTeXColorNames[13] = 
 { "none", "black", "white", "red", "green", "blue", "cyan", "magenta", 
   "yellow", "error12", "error13", "error14", "error15" };
+#endif
+
+#ifdef NEW_BITS
+LyXFont::FontBits LyXFont::sane = { ROMAN_FAMILY,
+                 MEDIUM_SERIES,
+                 UP_SHAPE,
+                 SIZE_NORMAL,
+#ifdef USE_PAINTER
+                 LColor::none,
+#else
+                 NONE,
+#endif
+                 OFF,
+                 OFF,
+                 OFF,
+                 OFF,
+                 LTR_DIR };
+
+LyXFont::FontBits LyXFont::inherit = { INHERIT_FAMILY, 
+                     INHERIT_SERIES, 
+                     INHERIT_SHAPE, 
+                     INHERIT_SIZE,
+#ifdef USE_PAINTER
+                     LColor::inherit,
+#else
+                     INHERIT_COLOR,
+#endif
+                     INHERIT,
+                     INHERIT,
+                     INHERIT,
+                     INHERIT,
+                     INHERIT_DIR };
+
+LyXFont::FontBits LyXFont::ignore = { IGNORE_FAMILY,
+                    IGNORE_SERIES,
+                    IGNORE_SHAPE,
+                    IGNORE_SIZE,
+#ifdef USE_PAINTER
+                    LColor::ignore,
+#else
+                    IGNORE_COLOR,
+#endif
+                    IGNORE,
+                    IGNORE,
+                    IGNORE,
+                    IGNORE,
+                    IGNORE_DIR };
+#endif
 
 /// Decreases font size by one
 LyXFont & LyXFont::decSize() 
@@ -139,7 +193,7 @@ LyXFont & LyXFont::decSize()
                lyxerr <<"Can't LyXFont::decSize on IGNORE_SIZE" << endl;
                break;
        }
-       return (*this);
+       return *this;
 }
 
 
@@ -170,7 +224,7 @@ LyXFont & LyXFont::incSize()
                lyxerr <<"Can't LyXFont::incSize on IGNORE_SIZE" << endl;
                break;
        }
-       return (*this);
+       return *this;
 }
 
 
@@ -256,10 +310,17 @@ void LyXFont::update(LyXFont const & newfont, bool toggleall)
                setDirection(newfont.direction());
        }
 
+#ifdef USE_PAINTER
+       if(newfont.color() == color() && toggleall)
+               setColor(LColor::inherit); // toggle 'back'
+       else if (newfont.color() != LColor::ignore)
+               setColor(newfont.color());
+#else
        if(newfont.color() == color() && toggleall)
-               setColor(INHERIT_COLOR); // toggle 'back'
-       else if (newfont.color() != IGNORE_COLOR)
+               setColor(LyXFont::INHERIT_COLOR); // toggle 'back'
+       else if (newfont.color() != LyXFont::IGNORE_COLOR)
                setColor(newfont.color());
+#endif
 }
 
 
@@ -282,8 +343,13 @@ void LyXFont::reduce(LyXFont const & tmplt)
                setNoun(INHERIT);
        if (latex() == tmplt.latex())
                setLatex(INHERIT);
+#ifdef USE_PAINTER
        if (color() == tmplt.color())
-               setColor(INHERIT_COLOR);
+               setColor(LColor::inherit);
+#else
+       if (color() == tmplt.color())
+               setColor(LyXFont::INHERIT_COLOR);
+#endif
        if (direction() == tmplt.direction())
                setDirection(INHERIT_DIR);
 }
@@ -291,6 +357,54 @@ void LyXFont::reduce(LyXFont const & tmplt)
 
 /// Realize font from a template
 // This one is not pretty, but it's extremely fast (Asger)
+#ifdef NEW_BITS
+LyXFont & LyXFont::realize(LyXFont const & tmplt)
+{
+       if (bits == inherit) {
+               bits = tmplt.bits;
+               return *this;
+       }
+       
+       if (bits.family == INHERIT_FAMILY) {
+               bits.family = tmplt.bits.family;
+       }
+       if (bits.series == INHERIT_SERIES) {
+               bits.series = tmplt.bits.series;
+       }
+       if (bits.shape == INHERIT_SHAPE) {
+               bits.shape = tmplt.bits.shape;
+       }
+       if (bits.size == INHERIT_SIZE) {
+               bits.size = tmplt.bits.size;
+       }
+       if (bits.emph == INHERIT) {
+               bits.emph = tmplt.bits.emph;
+       }
+       if (bits.underbar == INHERIT) {
+               bits.underbar = tmplt.bits.underbar;
+       }
+       if (bits.noun == INHERIT) {
+               bits.noun = tmplt.bits.noun;
+       }
+       if (bits.latex == INHERIT) {
+               bits.latex = tmplt.bits.latex;
+       }
+#ifdef USE_PAINTER
+       if (bits.color == LColor::inherit) {
+               bits.color = tmplt.bits.color;
+       }
+#else
+       if (bits.color == INHERIT_COLOR) {
+               bits.color = tmplt.bits.color;
+       }
+#endif
+       if (bits.direction == INHERIT_DIR) {
+               bits.direction = tmplt.bits.direction;
+       }
+
+       return *this;
+}
+#else
 LyXFont & LyXFont::realize(LyXFont const & tmplt)
 {
        if (bits == inherit) {
@@ -338,11 +452,19 @@ LyXFont & LyXFont::realize(LyXFont const & tmplt)
                        bits &= ~(Misc_Mask << Lat_Pos);
                        bits |= (tmplt.bits & Misc_Mask << Lat_Pos);
                }
+#ifdef USE_PAINTER
+       if ((bits & (Col_Mask << Col_Pos)) == ui32(LColor::inherit) << Col_Pos)
+               {
+                       bits &= ~(Col_Mask << Col_Pos);
+                       bits |= (tmplt.bits & Col_Mask << Col_Pos);
+               }
+#else
        if ((bits & (Col_Mask << Col_Pos)) == ui32(INHERIT_COLOR) << Col_Pos)
                {
                        bits &= ~(Col_Mask << Col_Pos);
                        bits |= (tmplt.bits & Col_Mask << Col_Pos);
                }
+#endif
        if ((bits & (Dir_Mask << Dir_Pos)) == ui32(INHERIT_DIR) << Dir_Pos)
                {
                        bits &= ~(Dir_Mask << Dir_Pos);
@@ -351,9 +473,21 @@ LyXFont & LyXFont::realize(LyXFont const & tmplt)
 
        return *this;
 }
+#endif
 
 
 /// Is font resolved?
+#ifdef USE_PAINTER
+bool LyXFont::resolved() const
+{
+       return (family() != INHERIT_FAMILY && series() != INHERIT_SERIES &&
+               shape() != INHERIT_SHAPE && size() != INHERIT_SIZE &&
+               emph() != INHERIT && underbar() != INHERIT && 
+               noun() != INHERIT && latex() != INHERIT && 
+               color() != LColor::inherit &&
+               direction() != INHERIT_DIR);
+}
+#else
 bool LyXFont::resolved() const
 {
        return (family() != INHERIT_FAMILY && series() != INHERIT_SERIES &&
@@ -363,6 +497,7 @@ bool LyXFont::resolved() const
                color() != INHERIT_COLOR &&
                direction() != INHERIT_DIR);
 }
+#endif
 
 
 /// Build GUI description of font state
@@ -377,9 +512,13 @@ string LyXFont::stateText() const
                buf += string(_(GUIShapeNames[shape()].c_str())) + ", ";
        if (size() != INHERIT_SIZE)
                buf += string(_(GUISizeNames[size()].c_str())) + ", ";
+#ifdef USE_PAINTER
+       if (color() != LColor::inherit)
+               buf += lcolor.getGUIName(color()) + ", ";
+#else
        if (color() != INHERIT_COLOR)
                buf += string(_(GUIColorNames[color()].c_str())) + ", ";
+#endif
        if (emph() != INHERIT)
                buf += string(_("Emphasis ")) + _(GUIMiscNames[emph()].c_str()) + ", ";
        if (underbar() != INHERIT)
@@ -476,6 +615,9 @@ LyXFont::FONT_MISC_STATE LyXFont::setLyXMisc(string const & siz)
 /// Sets color after LyX text format
 LyXFont & LyXFont::setLyXColor(string const & col)
 {
+#ifdef USE_PAINTER
+       setColor(lcolor.getFromLyXName(col));
+#else
        string s = lowercase(col);
        int i= 0;
        while (s != LyXColorNames[i] && LyXColorNames[i] != "error") ++i;
@@ -484,6 +626,7 @@ LyXFont & LyXFont::setLyXColor(string const & col)
        } else
                lyxerr << "LyXFont::setLyXColor: Unknown Color `"
                       << s << '\'' << endl;
+#endif
        return *this;
 }
 
@@ -491,6 +634,12 @@ LyXFont & LyXFont::setLyXColor(string const & col)
 /// Sets size after GUI name
 LyXFont & LyXFont::setGUISize(string const & siz)
 {
+#ifdef USE_PAINTER
+       /// ??????
+       // this is how it was how it was done in the lyx repository...
+       // but this does not make sense.
+       setColor(lcolor.getFromGUIName(siz));
+#else
        string s = lowercase(siz);
        int i = 0;
        while (!lGUISizeNames[i].empty() &&
@@ -501,6 +650,7 @@ LyXFont & LyXFont::setGUISize(string const & siz)
        } else
                lyxerr << "LyXFont::setGUISize: Unknown Size `"
                       << s << '\'' << endl;
+#endif
        return *this;
 }
 
@@ -592,7 +742,7 @@ LyXFont & LyXFont::lyxRead(LyXLex & lex)
                        error = true;
                }
        }
-       return * this;
+       return *this;
 }
 
 
@@ -650,9 +800,15 @@ void LyXFont::lyxWriteChanges(LyXFont const & orgfont, ostream & os) const
                break;
                }
        }
+#ifdef USE_PAINTER
+       if (orgfont.color() != color()) {
+               os << "\\color " << lcolor.getLyXName(color()) << "\n";
+       }
+#else
        if (orgfont.color() != color()) {
                os << "\\color " << LyXColorNames[color()] << "\n";
        }
+#endif
        if (orgfont.direction() != direction()) {
                switch (direction()) {
                case RTL_DIR:   os << "\\direction rtl \n"; break;
@@ -672,7 +828,8 @@ void LyXFont::lyxWriteChanges(LyXFont const & orgfont, ostream & os) const
 
 /// Writes the head of the LaTeX needed to impose this font
 // Returns number of chars written.
-int LyXFont::latexWriteStartChanges(string & file, LyXFont const & base, LyXFont const & prev) const
+int LyXFont::latexWriteStartChanges(string & file, LyXFont const & base,
+                                   LyXFont const & prev) const
 {
        LyXFont f = *this;
        f.reduce(base);
@@ -718,6 +875,15 @@ int LyXFont::latexWriteStartChanges(string & file, LyXFont const & base, LyXFont
                count += LaTeXShapeNames[f.shape()].length() + 2;
                env = true; //We have opened a new environment
        }
+#ifdef USE_PAINTER
+       if (f.color() != LColor::inherit) {
+               file += "\\textcolor{";
+               file += lcolor.getLaTeXName(f.color());
+               file += "}{";
+               count += lcolor.getLaTeXName(f.color()).length() + 13;
+               env = true; //We have opened a new environment
+       }
+#else
        if (f.color() != INHERIT_COLOR) {
                file += "\\textcolor{";
                file += LaTeXColorNames[f.color()];
@@ -725,6 +891,7 @@ int LyXFont::latexWriteStartChanges(string & file, LyXFont const & base, LyXFont
                count += LaTeXColorNames[f.color()].length() + 13;
                env = true; //We have opened a new environment
        }
+#endif
        if (f.emph() == ON) {
                file += "\\emph{";
                count += 6;
@@ -759,7 +926,8 @@ int LyXFont::latexWriteStartChanges(string & file, LyXFont const & base, LyXFont
 /// Writes ending block of LaTeX needed to close use of this font
 // Returns number of chars written
 // This one corresponds to latexWriteStartChanges(). (Asger)
-int LyXFont::latexWriteEndChanges(string & file, LyXFont const & base, LyXFont const & next) const
+int LyXFont::latexWriteEndChanges(string & file, LyXFont const & base,
+                                 LyXFont const & next) const
 {
        LyXFont f = *this; // why do you need this?
        f.reduce(base); // why isn't this just "reduce(base);" (Lgb)
@@ -796,11 +964,19 @@ int LyXFont::latexWriteEndChanges(string & file, LyXFont const & base, LyXFont c
                ++count;
                env = true; // Size change need not bother about closing env.
        }
+#ifdef USE_PAINTER
+       if (f.color() != LColor::inherit) {
+               file += '}';
+               ++count;
+               env = true; // Size change need not bother about closing env.
+       }
+#else
        if (f.color() != INHERIT_COLOR) {
                file += '}';
                ++count;
                env = true; // Size change need not bother about closing env.
        }
+#endif
        if (f.emph() == ON) {
                file += '}';
                ++count;
@@ -828,6 +1004,18 @@ int LyXFont::latexWriteEndChanges(string & file, LyXFont const & base, LyXFont c
 }
 
 
+#ifdef USE_PAINTER
+LColor::color LyXFont::realColor() const
+{
+       if (latex() == ON)
+               return LColor::latex;
+       if (color() == LColor::none)
+               return LColor::foreground;
+       return color();
+}
+#endif
+
+
 // Convert logical attributes to concrete shape attribute
 LyXFont::FONT_SHAPE LyXFont::realShape() const
 {
@@ -845,6 +1033,7 @@ LyXFont::FONT_SHAPE LyXFont::realShape() const
 }
 
 
+#ifndef USE_PAINTER
 GC LyXFont::getGC() const
 {
        GC gc;
@@ -864,6 +1053,7 @@ GC LyXFont::getGC() const
        XSetFont(fl_display, gc, getXFontstruct()->fid);
        return gc;
 }
+#endif
 
 
 XFontStruct * LyXFont::getXFontstruct() const
@@ -991,6 +1181,53 @@ int LyXFont::signedStringWidth(string const & s) const
 }
 
 
+#ifdef USE_PAINTER
+int LyXFont::drawText(char const * s, int n, Pixmap, 
+                     int, int x) const
+{
+       if (realShape() != LyXFont::SMALLCAPS_SHAPE) {
+               /* XDrawString(fl_display,
+                  pm,
+                  getGC(),
+                  x, baseline,
+                  s, n);
+                  XFlush(fl_display); */
+               return XTextWidth(getXFontstruct(), s, n);
+
+       } else {
+               // emulate smallcaps since X doesn't support this
+               char c;
+               int sx = x;
+               LyXFont smallfont = *this;
+               smallfont.decSize();
+               smallfont.decSize();
+               smallfont.setShape(LyXFont::UP_SHAPE);
+               for (int i = 0; i < n; ++i) {
+                       c = s[i];
+                       if (islower(static_cast<unsigned char>(c))){
+                               c = toupper(c);
+                               /* XDrawString(fl_display,
+                                  pm,
+                                  smallfont.getGC(),
+                                  x, baseline,
+                                  &c, 1); */
+                               x += XTextWidth(smallfont.getXFontstruct(),
+                                               &c, 1);
+                               //XFlush(fl_display);
+                       } else {
+                               /* XDrawString(fl_display,
+                                  pm,
+                                  getGC(),
+                                  x, baseline,
+                                  &c, 1);*/
+                               x += XTextWidth(getXFontstruct(), &c, 1);
+                               //XFlush(fl_display);
+                       }
+               }
+               return x - sx;
+       }
+}
+#else
 int LyXFont::drawText(char const * s, int n, Pixmap pm, 
                      int baseline, int x) const
 {
@@ -1036,6 +1273,7 @@ int LyXFont::drawText(char const * s, int n, Pixmap pm,
                return x - sx;
        }
 }
+#endif
 
 
 int LyXFont::drawString(string const & s, Pixmap pm, int baseline, int x) const
index a3cbfc4e25524565b803a5fe43c7b387746264f2..69711ef045848d4c37a0c52e5c4252ac5c2bcab4 100644 (file)
@@ -19,6 +19,7 @@
 #include "LString.h"
 #include "debug.h"
 #include "direction.h"
+#include "LColor.h"
 
 // It might happen that locale.h defines ON and OFF. This is not good
 // for us, since we use these names below. But of course this is due
@@ -35,6 +36,8 @@
 
 class LyXLex;
 
+#define NEW_BITS 1
+
 ///
 class LyXFont {
 public:
@@ -145,7 +148,8 @@ public:
                ///
                IGNORE
        };
+
+#ifndef USE_PAINTER
        ///
        enum FONT_COLOR {
                ///
@@ -175,7 +179,8 @@ public:
                ///
                IGNORE_COLOR
        };
-
+#endif
+       
        /// Trick to overload constructor and make it megafast
        enum FONT_INIT1 {
                ///
@@ -237,9 +242,14 @@ public:
 
        ///
        FONT_MISC_STATE latex() const;
+
+#ifdef USE_PAINTER
+       ///
+       LColor::color color() const;
+#else
        ///
        FONT_COLOR color() const;
+#endif
 
        ///
        FONT_DIRECTION direction() const;
@@ -263,8 +273,13 @@ public:
        LyXFont & setNoun(LyXFont::FONT_MISC_STATE n);
        ///
        LyXFont & setLatex(LyXFont::FONT_MISC_STATE l);
+#ifdef USE_PAINTER
+       ///
+       LyXFont & setColor(LColor::color c);
+#else
        ///
        LyXFont & setColor(LyXFont::FONT_COLOR c);
+#endif
        ///
        LyXFont & setDirection(LyXFont::FONT_DIRECTION d);
 
@@ -315,7 +330,7 @@ public:
        bool resolved() const;
  
        /// Read a font specification from LyXLex. Used for layout files.
-       LyXFont & lyxRead(LyXLex&);
+       LyXFont & lyxRead(LyXLex &);
  
        /// Writes the changes from this font to orgfont in .lyx format in file
        void lyxWriteChanges(LyXFont const & orgfont, ostream &) const;
@@ -369,14 +384,25 @@ public:
        int signedStringWidth(string const & s) const;
 
        /// Draws text and returns width of text
-       int drawText(char const*, int n, Pixmap, int baseline, int x) const;
+       int drawText(char const *, int n, Pixmap, int baseline, int x) const;
 
        ///
        int drawString(string const &, Pixmap pm, int baseline, int x) const;
 
+#ifdef USE_PAINTER
        ///
-       GC getGC() const;
+       LColor::color realColor() const;
+#endif
 
+       ///
+       XID getFontID() const {
+               return getXFontstruct()->fid;
+       }
+       
+#ifndef USE_PAINTER
+       ///
+       GC getGC() const;
+#endif
        ///
        friend inline
        bool operator==(LyXFont const & font1, LyXFont const & font2) {
@@ -393,22 +419,78 @@ public:
        bool equalExceptLatex(LyXFont const &) const;
 
 private:
+#ifdef NEW_BITS
+       ///
+       struct FontBits {
+               bool operator==(FontBits const & fb1) const {
+                       return fb1.family == family &&
+                               fb1.series == series &&
+                               fb1.shape == shape &&
+                               fb1.size == size &&
+                               fb1.color == color &&
+                               fb1.emph == emph &&
+                               fb1.underbar == underbar &&
+                               fb1.noun == noun &&
+                               fb1.latex == latex &&
+                               fb1.direction == direction;
+               }
+               bool operator!=(FontBits const & fb1) const {
+                       return !(fb1 == *this);
+               }
+               
+               FONT_FAMILY family;
+               FONT_SERIES series;
+               FONT_SHAPE shape;
+               FONT_SIZE size;
+#ifdef USE_PAINTER
+               LColor::color color;
+#else
+               FONT_COLOR color;
+#endif
+               FONT_MISC_STATE emph;
+               FONT_MISC_STATE underbar;
+               FONT_MISC_STATE noun;
+               FONT_MISC_STATE latex;
+               FONT_DIRECTION direction;
+       };
+#else
        /// This have to be at least 32 bits, but 64 or more does not hurt
        typedef unsigned int ui32;
+#endif
 
        /** Representation: bit table
            Layout of bit table:
-           11 1111 111 122 222 222 2233
+               11 1111 111 122 222 222 2233
            Bit 012 34 567 8901 2345 678 901 234 567 8901
-           FFF SS SSS SSSS CCCC EEE UUU NNN LLL
-           aaa ee hhh iiii oooo mmm nnn ooo aaa
-           mmm rr aaa zzzz llll ppp ddd uuu ttt
-
+               FFF SS SSS SSSS CCCC EEE UUU NNN LLL
+               aaa ee hhh iiii oooo mmm nnn ooo aaa
+               mmm rr aaa zzzz llll ppp ddd uuu ttt
+
+           Bit 76543210 76543210 76543210 76543210
+                                                --- Fam_Pos
+                                             --    Ser_Pos
+                                          ---      Sha_Pos
+                                     ----          Siz_Pos
+                                 ----              Col_Pos
+                             ---                   Emp_Pos
+                          ---                      Und_Pos
+                      - --                         Nou_Pos
+                   ---                             Lat_Pos
+               ----                                Dir_Pos
+               
            Some might think this is a dirty representation, but it gives
-           us at least 25% speed-up, so why not?
+           us at least 25% speed-up, so why not? (Asger)
+
+           First of all it is a maintence nightmare...and now that we need
+           to enlarge the Color bits with 2 (from 4 to 6), we have a problem
+           since a 32 bit entity is not large enough... (Lgb)
        */
-       ui32 bits;
 
+#ifdef NEW_BITS
+       FontBits bits;
+#else
+       ui32 bits;
+       
        ///
        enum FONT_POSITION {
                ///
@@ -450,25 +532,46 @@ private:
                ///
                Misc_Mask = 0x07
        };
+#endif
+
+       
+#ifdef NEW_BITS
+       /// Sane font
+       static FontBits sane;
+       
+       /// All inherit font
+       static FontBits inherit;
  
+       /// All ignore font
+       static FontBits ignore;
+
+#else
        /// Sane font
        enum {  sane = ui32(ROMAN_FAMILY) << Fam_Pos
                | ui32(MEDIUM_SERIES) << Ser_Pos
                | ui32(UP_SHAPE) << Sha_Pos
                | ui32(SIZE_NORMAL) << Siz_Pos
+#ifdef USE_PAINTER
+               | ui32(LColor::none) << Col_Pos
+#else
                | ui32(NONE) << Col_Pos
+#endif
                | ui32(OFF) << Emp_Pos
                | ui32(OFF) << Und_Pos
                | ui32(OFF) << Nou_Pos
                | ui32(OFF) << Lat_Pos
                | ui32(LTR_DIR) << Dir_Pos};
+       
        /// All inherit font
        enum{ inherit = ui32(INHERIT_FAMILY) << Fam_Pos
                      | ui32(INHERIT_SERIES) << Ser_Pos
                      | ui32(INHERIT_SHAPE) << Sha_Pos
                      | ui32(INHERIT_SIZE) << Siz_Pos
+#ifdef USE_PAINTER
+                     | ui32(LColor::inherit) << Col_Pos
+#else
                      | ui32(INHERIT_COLOR) << Col_Pos
+#endif
                      | ui32(INHERIT) << Emp_Pos
                      | ui32(INHERIT) << Und_Pos
                      | ui32(INHERIT) << Nou_Pos
@@ -480,13 +583,17 @@ private:
                      | ui32(IGNORE_SERIES) << Ser_Pos
                      | ui32(IGNORE_SHAPE) << Sha_Pos
                      | ui32(IGNORE_SIZE) << Siz_Pos
+#ifdef USE_PAINTER
+                     | ui32(LColor::ignore) << Col_Pos
+#else
                      | ui32(IGNORE_COLOR) << Col_Pos
+#endif
                      | ui32(IGNORE) << Emp_Pos
                      | ui32(IGNORE) << Und_Pos
                      | ui32(IGNORE) << Nou_Pos
                      | ui32(IGNORE) << Lat_Pos
                      | ui32(IGNORE_DIR) << Dir_Pos};
+#endif
        /// Updates a misc setting according to request
        LyXFont::FONT_MISC_STATE setMisc(LyXFont::FONT_MISC_STATE newfont,
                                         LyXFont::FONT_MISC_STATE org);
@@ -495,7 +602,7 @@ private:
        LyXFont::FONT_SHAPE realShape() const;
 
        ///
-       XFontStruct* getXFontstruct() const;
+       XFontStruct * getXFontstruct() const;
 };
 
 ostream & operator<<(ostream &, LyXFont::FONT_MISC_STATE);
@@ -537,8 +644,178 @@ inline LyXFont & LyXFont::operator=(LyXFont const & x)
 }
 
 
+#ifdef NEW_BITS
+// You don't have to understand the stuff below :-)
+// It works, and it's bloody fast. (Asger)
+// And impossible to work with. (Lgb)
+
+inline
+LyXFont::FONT_FAMILY LyXFont::family() const 
+{
+       return bits.family;
+}
+
+
+inline
+LyXFont::FONT_SERIES LyXFont::series() const
+{
+       return bits.series;
+}
+
+
+inline
+LyXFont::FONT_SHAPE LyXFont::shape() const
+{
+       return bits.shape;
+}
+
+
+inline
+LyXFont::FONT_SIZE LyXFont::size() const
+{
+       return bits.size;
+}
+
+
+inline
+LyXFont::FONT_MISC_STATE LyXFont::emph() const
+{
+       return bits.emph;
+}
+
+
+inline
+LyXFont::FONT_MISC_STATE LyXFont::underbar() const
+{
+       return bits.underbar;
+}
+
+
+inline
+LyXFont::FONT_MISC_STATE LyXFont::noun() const
+{
+       return bits.noun;
+}
+
+
+inline
+LyXFont::FONT_MISC_STATE LyXFont::latex() const 
+{
+       return bits.latex;
+}
+
+
+#ifdef USE_PAINTER
+inline
+LColor::color LyXFont::color() const 
+{
+       return bits.color;
+}
+#else
+inline
+LyXFont::FONT_COLOR LyXFont::color() const 
+{
+       return bits.color;
+}
+#endif
+
+
+inline
+LyXFont::FONT_DIRECTION LyXFont::direction() const 
+{
+       return bits.direction;
+}
+
+inline
+LyXFont & LyXFont::setFamily(LyXFont::FONT_FAMILY f)
+{
+       bits.family = f;
+       return *this;
+}
+
+
+inline
+LyXFont & LyXFont::setSeries(LyXFont::FONT_SERIES s)
+{
+       bits.series = s;
+       return *this;
+}
+
+
+inline
+LyXFont & LyXFont::setShape(LyXFont::FONT_SHAPE s)
+{
+       bits.shape = s;
+       return *this;
+}
+
+
+inline
+LyXFont & LyXFont::setSize(LyXFont::FONT_SIZE s)
+{
+       bits.size = s;
+       return *this;
+}
+
+
+inline
+LyXFont & LyXFont::setEmph(LyXFont::FONT_MISC_STATE e)
+{
+       bits.emph = e;
+       return *this;
+}
+
+
+inline
+LyXFont & LyXFont::setUnderbar(LyXFont::FONT_MISC_STATE u)
+{
+       bits.underbar = u;
+       return *this;
+}
+
+
+inline
+LyXFont & LyXFont::setNoun(LyXFont::FONT_MISC_STATE n)
+{
+       bits.noun = n;
+       return *this;
+}
+
+inline
+LyXFont & LyXFont::setLatex(LyXFont::FONT_MISC_STATE l)
+{
+       bits.latex = l;
+       return *this;
+}
+
+
+#ifdef USE_PAINTER
+inline
+LyXFont & LyXFont::setColor(LColor::color c)
+{
+       bits.color = c;
+       return *this;
+}
+#else
+inline
+LyXFont & LyXFont::setColor(LyXFont::FONT_COLOR c)
+{
+       bits.color = c;
+       return *this;
+}
+#endif
+
+inline
+LyXFont & LyXFont::setDirection(LyXFont::FONT_DIRECTION d)
+{
+       bits.direction = d;
+       return *this;
+}
+#else
 // You don't have to understand the stuff below :-)
 // It works, and it's bloody fast. (Asger)
+// And impossible to work with. (Lgb)
+
 inline LyXFont::FONT_FAMILY LyXFont::family() const 
 {
        return LyXFont::FONT_FAMILY((bits >> Fam_Pos) & Fam_Mask);
@@ -587,10 +864,18 @@ inline LyXFont::FONT_MISC_STATE LyXFont::latex() const
 }
 
 
-inline LyXFont::FONT_COLOR LyXFont::color() const 
+#ifdef USE_PAINTER
+inline LColor::color LyXFont::color() const 
+{
+       return LColor::color((bits >> Col_Pos) & Col_Mask);
+}
+#else
+inline LyXFont::FONT_COLOR LyXFont::color() const
 {
-       return LyXFont::FONT_COLOR((bits >> Col_Pos) & Col_Mask);
+       return FONT_COLOR((bits >> Col_Pos) & Col_Mask);
 }
+#endif
+
 
 inline LyXFont::FONT_DIRECTION LyXFont::direction() const 
 {
@@ -660,12 +945,21 @@ inline LyXFont & LyXFont::setLatex(LyXFont::FONT_MISC_STATE l)
 }
 
 
+#ifdef USE_PAINTER
+inline LyXFont & LyXFont::setColor(LColor::color c)
+{
+       bits &= ~(Col_Mask << Col_Pos);
+       bits |= ui32(c) << Col_Pos;
+       return *this;
+}
+#else
 inline LyXFont & LyXFont::setColor(LyXFont::FONT_COLOR c)
 {
        bits &= ~(Col_Mask << Col_Pos);
        bits |= ui32(c) << Col_Pos;
        return *this;
 }
+#endif
 
 inline LyXFont & LyXFont::setDirection(LyXFont::FONT_DIRECTION d)
 {
@@ -673,5 +967,6 @@ inline LyXFont & LyXFont::setDirection(LyXFont::FONT_DIRECTION d)
        bits |= ui32(d) << Dir_Pos;
        return *this;
 }
+#endif
 
 #endif
index 5e8461fee0a3a9310998374302eb3cc293bdf07e..6143c9d8f1aebd05ab9c0af1b2af583e41ea3df0 100644 (file)
@@ -265,10 +265,14 @@ bool LyXFindReplace1::SearchCB(bool fForward)
                current_view->owner()->getMiniBuffer()->Set(_("String not found!"));
                result = false;
        }
-   
+
+#ifdef NEW_WA
+       if (current_view->focus())
+               current_view->getScreen()->ShowCursor();
+#else
        if (current_view->getWorkArea()->focus)
                current_view->getScreen()->ShowCursor();
-
+#endif
        return result;
 }
 
index 59508367fb283751b827f8a76a5e421c1aef5873..4fa02f314eeaae2d696f81163e9a69769ad84c3a 100644 (file)
@@ -63,6 +63,7 @@
 #include "ImportLaTeX.h"
 #include "ImportNoweb.h"
 #include "layout.h"
+#include "WorkArea.h"
 
 extern bool cursor_follows_scrollbar;
 
@@ -662,10 +663,20 @@ string LyXFunc::Dispatch(int ac,
        case LFUN_CENTER: // this is center and redraw.
                owner->view()->beforeChange();
                if (owner->view()->text->cursor.y >
-                   owner->view()->getWorkArea()->h / 2)        {
+#ifdef NEW_WA
+                   owner->view()->getWorkArea()->height() / 2)
+#else
+                   owner->view()->getWorkArea()->h / 2)
+#endif
+                       {
                        owner->view()->getScreen()->
                                Draw(owner->view()->text->cursor.y -
-                                    owner->view()->getWorkArea()->h / 2);
+#ifdef NEW_WA
+                                    owner->view()->getWorkArea()->height() / 2
+#else
+                                    owner->view()->getWorkArea()->h / 2
+#endif
+                                       );
                } else { // <= 
                        owner->view()->getScreen()->
                                Draw(0);
@@ -1299,6 +1310,34 @@ string LyXFunc::Dispatch(int ac,
                
        case LFUN_LEFT:
        {
+#ifdef USE_PAINTER
+               // This is soooo ugly. Isn`t it possible to make
+               // it simpler? (Lgb)
+               LyXText * txt = owner->view()->text;
+               LyXDirection direction = txt->cursor.par->getParDirection();
+               if(!txt->mark_set) owner->view()->beforeChange();
+               owner->view()->update(-2);
+               if (direction == LYX_DIR_LEFT_TO_RIGHT)
+                       txt->CursorLeft();
+               if (txt->cursor.pos < txt->cursor.par->Last()
+                   && txt->cursor.par->GetChar(txt->cursor.pos)
+                   == LyXParagraph::META_INSET
+                   && txt->cursor.par->GetInset(txt->cursor.pos)
+                   && txt->cursor.par->GetInset(txt->cursor.pos)->Editable() == 2) {
+                       Inset * tmpinset = txt->cursor.par->GetInset(txt->cursor.pos);
+                       setMessage(tmpinset->EditMessage());
+                       tmpinset->Edit(tmpinset->width(owner->view()->painter(),
+                                                      txt->GetFont(txt->cursor.par,
+                                                                   txt->cursor.pos)), 0);
+                       break;
+               }
+               if  (direction == LYX_DIR_RIGHT_TO_LEFT)
+                       txt->CursorRight();
+
+               owner->view()->text->FinishUndo();
+               moveCursorUpdate(false);
+               owner->getMiniBuffer()->Set(CurrentState());
+#else
                // This is soooo ugly. Isn`t it possible to make
                // it simpler? (Lgb)
                LyXText * txt = owner->view()->text;
@@ -1324,6 +1363,7 @@ string LyXFunc::Dispatch(int ac,
                owner->view()->text->FinishUndo();
                moveCursorUpdate(false);
                owner->getMiniBuffer()->Set(CurrentState());
+#endif
        }
        break;
                
@@ -1970,10 +2010,20 @@ string LyXFunc::Dispatch(int ac,
                // Recenter screen
                owner->view()->beforeChange();
                if (owner->view()->text->cursor.y >
-                   owner->view()->getWorkArea()->h / 2)        {
+#ifdef NEW_WA
+                   owner->view()->getWorkArea()->height() / 2
+#else
+                   owner->view()->getWorkArea()->h / 2
+#endif
+                       ) {
                        owner->view()->getScreen()->
                                Draw(owner->view()->text->cursor.y -
-                                    owner->view()->getWorkArea()->h/2);
+#ifdef NEW_WA
+                                    owner->view()->getWorkArea()->height() / 2
+#else
+                                    owner->view()->getWorkArea()->h / 2
+#endif
+                                       );
                } else { // <= 
                        owner->view()->getScreen()->
                                Draw(0);
index 22731d3268dd2f00a2baadd70492cecb96c886eb..75c411410dbf89a5056f2dc71bfecc7aaecc907f 100644 (file)
@@ -4,8 +4,8 @@
  * 
  *           LyX, The Document Processor
  *      
- *         Copyright 1995 Matthias Ettrich
- *          Copyright 1995-1999 The LyX Team
+ *           Copyright 1995 Matthias Ettrich
+ *           Copyright 1995-2000 The LyX Team
  *
  * ====================================================== */
 
@@ -24,6 +24,10 @@ class LyXText;
 struct Row;
 typedef unsigned short Dimension;
 
+class BufferView;
+
+#define NEW_WA 1
+
 /** The class LyXScreen is used for the main Textbody.
     Concretely, the screen is held in a pixmap.  This pixmap is kept up to
     date and used to optimize drawing on the screen.
@@ -32,12 +36,15 @@ typedef unsigned short Dimension;
 class LyXScreen {
 public:
        ///
-       LyXScreen(Window window,
+       LyXScreen(BufferView *, Window window,
+#ifdef NEW_WA
+                 Pixmap p,
+#endif
                  Dimension width, 
                  Dimension height,
                  Dimension offset_x,
                  Dimension offset_y,
-                 LyXText *text_ptr);
+                 LyXText * text_ptr);
        ///
        ~LyXScreen();
 
@@ -86,6 +93,7 @@ public:
            or only current row */
        void SmallUpdate();
 
+#ifndef USE_PAINTER
        /** Functions for drawing into the LyXScreen. The number of
            drawing functions should be minimized, now there
            is too many. And also there is mixed X and XForms drawing
@@ -132,7 +140,7 @@ public:
        ///
        int drawString(LyXFont const & font, string const & str,
                       int baseline, int x);
-               
+#endif
        /// first visible pixel-row
        long first;
 
@@ -148,6 +156,9 @@ private:
        /// y is a coordinate of the text
        void DrawOneRow(Row * row, long & y_text);
 
+       ///
+       BufferView * owner;
+       
        ///
        LyXText * text;
 
@@ -178,11 +189,15 @@ private:
        ///
        Row * screen_refresh_row;
        ///
-       friend class InsetFormula;  
+       friend class InsetFormula;
+#ifdef USE_PAINTER
+       ///
+       GC gc_copy;
+#endif
 };
 
 // Some of the easy to inline draw methods:
-
+#ifndef USE_PAINTER
 inline
 void LyXScreen::drawPoint(GC gc, int x, int y)
 {
@@ -315,5 +330,6 @@ int LyXScreen::drawString(LyXFont const & font, string const & str,
 {
        return font.drawString(str, foreground, baseline, x);
 }
+#endif
 
 #endif
index ccc024fd8c809f827f882c78566229e5def8f957..b9fe99cb201d2a95f216ba14fdf0c461d3735568 100644 (file)
@@ -26,6 +26,7 @@ class Buffer;
 class BufferParams;
 class LyXScreen;
 class Row;
+class BufferView;
 
 /**
   This class holds the mapping between buffer paragraphs and screen rows.
@@ -58,11 +59,14 @@ public:
        mutable LyXFont real_current_font;
 
        /// Constructor
-       LyXText(int paperwidth, Buffer *);
+       LyXText(BufferView *, int paperwidth, Buffer *);
    
        /// Destructor
        ~LyXText();
-   
+
+       ///
+       void owner(BufferView *);
+       
        ///
        LyXFont GetFont(LyXParagraph * par,
                        LyXParagraph::size_type pos) const;
@@ -285,9 +289,14 @@ public:
        /** returns a printed row in a pixmap. The y value is needed to
          decide, wether it is selected text or not. This is a strange
          solution but faster.
-        */ 
+        */
+#ifdef USE_PAINTER
+       void GetVisibleRow(int offset, 
+                          Row * row_ptr, long y);
+#else
        void GetVisibleRow(LyXScreen & scr, int offset, 
                           Row * row_ptr, long y);
+#endif
                                           
        /* footnotes: */
        ///
@@ -474,6 +483,9 @@ public:
        ///
        unsigned short paperWidth() const { return paperwidth; }
 private:
+       ///
+       BufferView * owner_;
+       
        /// width of the paper
        unsigned short  paperwidth;
 
@@ -543,10 +555,17 @@ private:
        ///
        int SingleWidth(LyXParagraph * par,
                        LyXParagraph::size_type pos, char c) const;
+#ifdef USE_PAINTER
+       ///
+       void draw(Row const * row,
+                 LyXParagraph::size_type & pos,
+                 int offset, float & x);
+#else
        ///
        void Draw(Row const * row, LyXParagraph::size_type & pos,
                  LyXScreen & scr,
                  int offset, float & x);
+#endif
        /// get the next breakpoint in a given paragraph
        LyXParagraph::size_type NextBreakPoint(Row const * row,
                                               int width) const;
@@ -610,7 +629,8 @@ private:
                                     LyXParagraph::size_type offset) const;
 
        /// Maps positions in the visual string to positions in logical string.
-       inline LyXParagraph::size_type log2vis(LyXParagraph::size_type pos) const {
+       inline
+       LyXParagraph::size_type log2vis(LyXParagraph::size_type pos) const {
                if (bidi_start == -1)
                        return pos;
                else
@@ -618,7 +638,8 @@ private:
        }
 
        /// Maps positions in the logical string to positions in visual string.
-       inline LyXParagraph::size_type vis2log(LyXParagraph::size_type pos) const {
+       inline
+       LyXParagraph::size_type vis2log(LyXParagraph::size_type pos) const {
                if (bidi_start == -1)
                        return pos;
                else
index 8a05232bb387e2f0fc1113c93b081c2ae4490ac1..0da5e63e5c69e9d5a5919d83847c2dafc8d3d0ed 100644 (file)
@@ -39,6 +39,7 @@
 #include "lyx_gui_misc.h"
 #include "support/LOstream.h"
 #include "LyXView.h"
+#include "Painter.h"
 
 extern void UpdateInset(BufferView *, Inset * inset, bool mark_dirty = true);
 
@@ -141,9 +142,14 @@ LyXFont WhichFont(short type, int size)
             lyxerr << "Mathed Error: wrong font size: " << size << endl;
        break;
     }
-    
+
+#ifdef USE_PAINTER
     if (type != LM_TC_TEXTRM) 
-      f.setColor(LyXFont::MATH);
+      f.setColor(LColor::math);
+#else
+    if (type != LM_TC_TEXTRM)
+           f.setColor(LyXFont::MATH);
+#endif    
     return f;
 }
 
@@ -183,7 +189,16 @@ void mathed_init_fonts() //removed 'static' because DEC cxx does not
     MathedInset::df_width = f.width('I');    
 }
 
-
+#ifdef USE_PAINTER
+LyXFont mathed_get_font(short type, int size)
+{
+       LyXFont f = WhichFont(type, size);
+       if (type == LM_TC_TEX) {
+               f.setLatex(LyXFont::ON);
+       }
+       return f;
+}
+#else
 void mathed_set_font(short type, int size)
 {
     if (!canvasGC) {
@@ -200,6 +215,7 @@ void mathed_set_font(short type, int size)
     } else
       mathGC = f.getGC();
 }
+#endif
 
 
 int mathed_string_width(short type, int size, byte const * s, int ls)
@@ -256,6 +272,23 @@ int mathed_char_height(short type, int size, byte c, int & asc, int & des)
 
 
 // In a near future maybe we use a better fonts renderer
+#ifdef USE_PAINTER
+void MathedInset::drawStr(Painter & pain, short type, int size,
+                         int x, int y, byte * s, int ls)
+{
+       string st;
+       if (MathIsBinary(type)) {
+               for (int i = 0; i < ls; ++i) {
+#warning What conversion should be done for s[i] here?
+                       st += string(" ") + char(s[i]) + ' ';
+               }
+       } else {
+               st = string(reinterpret_cast<char*>(s), ls);
+       }
+       LyXFont mf = mathed_get_font(type, size);
+       pain.text(x, y, st, mf);
+}
+#else
 void MathedInset::drawStr(short type, int siz, int x, int y, byte * s, int ls)
 {
     mathed_set_font(type, siz);
@@ -275,6 +308,7 @@ void MathedInset::drawStr(short type, int siz, int x, int y, byte * s, int ls)
     XDrawString(fl_display, pm, gc, x, y, reinterpret_cast<char*>(s), ls);
     XFlush(fl_display);
 }
+#endif
 
 
 InsetFormula::InsetFormula(bool display)
@@ -395,26 +429,108 @@ void InsetFormula::Read(LyXLex & lex)
 }
 
 
+#ifdef USE_PAINTER
+int InsetFormula::ascent(Painter &, LyXFont const &) const
+{
+   return par->Ascent() + ((disp_flag) ? 8 : 1);
+}
+#else
 int InsetFormula::Ascent(LyXFont const &) const
 {
    return par->Ascent() + ((disp_flag) ? 8 : 1);
 }
+#endif
 
 
+#ifdef USE_PAINTER
+int InsetFormula::descent(Painter &, LyXFont const &) const
+{
+   return par->Descent() + ((disp_flag) ? 8 : 1);
+}
+#else
 int InsetFormula::Descent(LyXFont const &) const
 {
    return par->Descent() + ((disp_flag) ? 8 : 1);
 }
+#endif
 
 
+#ifdef USE_PAINTER
+int InsetFormula::width(Painter &, LyXFont const & f) const
+{
+    lfont_size = f.size();
+    par->Metrics();
+    return par->Width(); //+2;
+}
+#else
 int InsetFormula::Width(LyXFont const & f) const
 {
     lfont_size = f.size();
     par->Metrics();
     return par->Width(); //+2;
 }
+#endif
 
 
+#ifdef USE_PAINTER
+void InsetFormula::draw(Painter & pain, LyXFont const &,
+                       int baseline, float & x) const
+{
+       LyXFont font = mathed_get_font(LM_TC_TEXTRM, LM_ST_TEXT);
+
+       lfont_size = font.size();
+       /// Let's try to wait a bit with this... (Lgb)
+       //UpdatableInset::draw(pain, font, baseline, x);
+       
+       // otherwise a segfault could occur
+       // in some XDrawRectangles (i.e. matrix) (Matthias)
+       if (mathcursor && mathcursor->GetPar() == par) { 
+               if (mathcursor->Selection()) {
+                       int n;
+                       int * xp = 0;
+                       int * yp = 0;
+                       mathcursor->SelGetArea(xp, yp, n);
+                       pain.fillPolygon(xp, yp, n, LColor::selection);
+               }
+               mathcursor->draw(pain, int(x), baseline);
+       } else {
+               par->draw(pain, int(x), baseline);
+       }
+       x += float(width(pain, font));
+       
+       if (par->GetType() == LM_OT_PARN || par->GetType() == LM_OT_MPARN) {
+               LyXFont font = WhichFont(LM_TC_BF, par->size);
+               font.setLatex(LyXFont::OFF);
+               
+               if (par->GetType() == LM_OT_PARN) {
+                       string str;
+                       if (!label.empty())
+                               str = string("(") + label + ")";
+                       else
+                               str = string("(#)");
+                       pain.text(int(x + 20), baseline, str, font);
+               } else if (par->GetType() == LM_OT_MPARN) {
+                       MathMatrixInset * mt =
+                               static_cast<MathMatrixInset*>(par);
+                       int y;
+                       MathedRowSt const * crow = mt->getRowSt();
+                       while (crow) {
+                               y = baseline + crow->getBaseline();
+                               if (crow->isNumbered()) {
+                                       string str;
+                                       if (crow->getLabel())
+                                               str = string("(") + crow->getLabel() + ")";
+                                       else
+                                               str = "(#)";
+                                       pain.text(int(x + 20), y, str, font);
+                               }
+                               crow = crow->getNext();
+                       }
+               }
+       }
+       cursor_visible = false;
+}
+#else
 void InsetFormula::Draw(LyXFont f, LyXScreen & scr, int baseline, float & x)
 {
        // This is Alejandros domain so I'll use this
@@ -469,6 +585,7 @@ void InsetFormula::Draw(LyXFont f, LyXScreen & scr, int baseline, float & x)
    }
    cursor_visible = false;
 }
+#endif
 
 
 void InsetFormula::Edit(int x, int y)
@@ -1211,6 +1328,23 @@ bool InsetFormula::LocalDispatch(int action, char const * arg)
 }
 
 
+#ifdef USE_PAINTER
+void
+MathFuncInset::draw(Painter & pain, int x, int y)
+{ 
+       if (name && name[0] > ' ') {
+               LyXFont font = WhichFont(LM_TC_TEXTRM, size);
+               font.setLatex(LyXFont::ON);
+               x += (font.textWidth("I", 1) + 3) / 4;
+               if (mono_video) {
+                       int a = font.maxAscent();
+                       int d = font.maxDescent();
+                       pain.fillRectangle(x, y - a, font.textWidth(name, strlen(name)), a + d);
+               }
+               pain.text(x, y, name, font);
+       }
+}
+#else
 void
 MathFuncInset::Draw(int x, int y)
 { 
@@ -1228,7 +1362,7 @@ MathFuncInset::Draw(int x, int y)
                font.drawString(name, pm, y, x);
        }
 }
-
+#endif
 
 void MathFuncInset::Metrics() 
 {
index 1205e2ced3a52826a480552313f9bb183f9fcb40..491616ed997c4eb885d08ca1dbbe84d3dba7a805 100644 (file)
@@ -36,6 +36,16 @@ public:
        InsetFormula(MathParInset *);
        ///
        ~InsetFormula();
+#ifdef USE_PAINTER
+       ///
+       int ascent(Painter &, LyXFont const &) const;
+       ///
+       int descent(Painter &, LyXFont const &) const;
+       ///
+       int width(Painter &, LyXFont const &) const;
+       ///
+       void draw(Painter &, LyXFont const &, int baseline, float & x) const;
+#else
        ///
        int Ascent(LyXFont const & font) const;
        ///
@@ -44,6 +54,7 @@ public:
        int Width(LyXFont const & font) const;
        ///
        void Draw(LyXFont font, LyXScreen & scr, int baseline, float & x);
+#endif
        ///
        void Write(ostream &);
        ///
index fa9f94cd89a34437ac39ef5ead322181f735c520..90576cbdd9a06f7bcf7217818550893851a5bc5f 100644 (file)
@@ -31,6 +31,7 @@
 #include "lyxscreen.h"
 #include "lyxdraw.h"
 #include "gettext.h"
+#include "Painter.h"
 
 
 InsetFormulaMacro::InsetFormulaMacro()
@@ -115,6 +116,16 @@ void InsetFormulaMacro::Read(LyXLex & lex)
 }
 
 
+#ifdef USE_PAINTER
+int InsetFormulaMacro::ascent(Painter & pain, LyXFont const & f) const
+{
+    if (opened) {
+       tmacro->update();
+       return InsetFormula::ascent(pain, f);
+    }
+    return f.maxAscent()+3;
+}
+#else
 int InsetFormulaMacro::Ascent(LyXFont const & f) const
 {
     if (opened) {
@@ -123,8 +134,19 @@ int InsetFormulaMacro::Ascent(LyXFont const & f) const
     }
     return f.maxAscent()+3;
 }
+#endif
 
 
+#ifdef USE_PAINTER
+int InsetFormulaMacro::descent(Painter & pain, LyXFont const & f) const
+{
+    if (opened) {
+       tmacro->update();
+       return InsetFormula::descent(pain, f);
+    }
+    return f.maxDescent()+1;
+}
+#else
 int InsetFormulaMacro::Descent(LyXFont const & f) const
 {
     if (opened) {
@@ -133,8 +155,21 @@ int InsetFormulaMacro::Descent(LyXFont const & f) const
     }
     return f.maxDescent()+1;
 }
+#endif
 
 
+#ifdef USE_PAINTER
+int InsetFormulaMacro::width(Painter & pain, LyXFont const & f) const
+{
+    if (opened) {
+       tmacro->update();
+       return InsetFormula::width(pain, f);
+    }
+    string ilabel(_("Macro: "));
+    ilabel += name;
+    return 6 + f.stringWidth(ilabel);
+}
+#else
 int InsetFormulaMacro::Width(LyXFont const & f) const
 {
     if (opened) {
@@ -145,8 +180,37 @@ int InsetFormulaMacro::Width(LyXFont const & f) const
     ilabel += name;
     return 6 + f.stringWidth(ilabel);
 }
+#endif
 
 
+#ifdef USE_PAINTER
+void InsetFormulaMacro::draw(Painter & pain, LyXFont const & f,
+                            int baseline, float & x) const
+{
+       LyXFont font(f);
+       tmacro->update();
+       if (opened) {
+               tmacro->setEditMode(true);
+               InsetFormula::draw(pain, font, baseline, x);
+               tmacro->setEditMode(false);     
+       } else {
+               font.setColor(LColor::math);
+               
+               int y = baseline - ascent(pain, font) + 1;
+               int w = width(pain, font) - 2;
+               int h = (ascent(pain, font) + descent(pain, font) - 2);
+
+       
+               pain.fillRectangle(int(x), y, w, h, LColor::mathbg);
+               pain.rectangle(int(x), y, w, h, LColor::mathframe);
+               
+               string s(_("Macro: "));
+               s += name;
+               pain.text(int(x + 2), baseline, s, font);
+               x +=  width(pain, font) - 1;
+       }
+}
+#else
 void InsetFormulaMacro::Draw(LyXFont font, LyXScreen & scr,
                             int baseline, float & x)
 {
@@ -171,6 +235,7 @@ void InsetFormulaMacro::Draw(LyXFont font, LyXScreen & scr,
        x +=  Width(font) - 1;
     }
 }
+#endif
 
 
 void InsetFormulaMacro::Edit(int x, int y)
index 486b16ae068fa7a5ae20dc1987547b89158dce8c..d2ce795473ec8e64d7effa404d8acd0596599d42 100644 (file)
@@ -35,6 +35,16 @@ public:
        InsetFormulaMacro(string name, int na = 0, bool env = false);
        ///
        ~InsetFormulaMacro();
+#ifdef USE_PAINTER
+       ///
+       int ascent(Painter &, LyXFont const &) const;
+       ///
+       int descent(Painter &, LyXFont const &) const;
+       ///
+       int width(Painter &, LyXFont const &) const;
+       ///
+       void draw(Painter &, LyXFont const &, int baseline, float & x) const;
+#else
        ///
        int Ascent(LyXFont const & font) const;
        ///
@@ -43,6 +53,7 @@ public:
        int Width(LyXFont const & font) const;
        ///
        void Draw(LyXFont font, LyXScreen & scr, int baseline, float & x);
+#endif
        ///
        void Read(LyXLex & lex);
         ///
index f33026ae0482167ac667bd37080aef1d9769e999..90c5beb193c46ba6639ae4aab0fee33c232326da 100644 (file)
@@ -28,6 +28,8 @@
 #include "math_root.h"
 #include "support/lstrings.h"
 #include "debug.h"
+#include "LColor.h"
+#include "Painter.h"
 
 extern void mathed_set_font(short type, int style);
 
@@ -149,6 +151,25 @@ void MathedCursor::SetPar(MathParInset * p)
 }
 
 
+#ifdef USE_PAINTER
+void MathedCursor::draw(Painter & pain, int x, int y)
+{
+       //    lyxerr << "Cursor[" << x << " " << y << "] ";
+       //win = pm;    // win = (mathedCanvas) ? mathedCanvas: pm;
+       par->Metrics();
+       int w = par->Width() + 2;
+       int a = par->Ascent() + 1;
+       int h = par->Height() + 1;
+       if (par->GetType() > LM_OT_PAR) { a += 4;  h += 8; }
+       
+       pain.rectangle(x - 1, y - a,
+                      x - 1 + w, y - a + h,
+                      LColor::mathframe);
+       
+       par->draw(pain, x, y);
+       cursor->Adjust();
+}
+#else
 void MathedCursor::Draw(long unsigned pm, int x, int y)
 {
 //    lyxerr << "Cursor[" << x << " " << y << "] ";
@@ -165,8 +186,24 @@ void MathedCursor::Draw(long unsigned pm, int x, int y)
     par->Draw(x, y);
     cursor->Adjust();
 }
+#endif
 
 
+#ifdef USE_PAINTER
+void MathedCursor::Redraw(Painter & pain)
+{  
+       lyxerr[Debug::MATHED] << "Mathed: Redrawing!" << endl;
+       par->Metrics();
+       int w = par->Width(), h = par->Height();
+       int x, y;
+       par->GetXY(x, y);
+       //mathed_set_font(LM_TC_VAR, 1);
+       pain.fillRectangle(x, y - par->Ascent(),
+                          x + w, y - par->Ascent() + h,
+                          LColor::mathbg);
+       par->draw(pain, x, y);
+}
+#else
 void MathedCursor::Redraw()
 {  
        lyxerr[Debug::MATHED] << "Mathed: Redrawing!" << endl;
@@ -180,6 +217,7 @@ void MathedCursor::Redraw()
     MathParInset::pm = win;
    par->Draw(x, y);
 }
+#endif
 
 
 bool MathedCursor::Left(bool sel)
@@ -920,6 +958,71 @@ void MathedCursor::SelBalance()
 } 
 
 
+#ifdef USE_PAINTER
+void MathedCursor::SelGetArea(int * xp, int * yp, int & np)
+{   
+    if (!selection) {
+       np = 0;
+       return;
+    }
+
+    static int xpoint[10];
+    static int ypoint[10];
+    
+    // single row selection
+    int i = 0, x, y, a, d, xo, yo, x1, y1, a1, d1;
+
+    // Balance anchor and cursor
+    SelBalance();
+    cursor->p->GetXY(xo, yo);
+    int w = cursor->p->Width();
+    cursor->GetPos(x1, y1);
+    cursor->getAD(a1, d1);
+    anchor->GetPos(x, y);
+    anchor->getAD(a, d);
+
+    xpoint[i] = x;
+    ypoint[i++] = y + d;
+    xpoint[i] = x;
+    ypoint[i++] = y - a;
+    
+    if (y != y1) {
+           xpoint[i] = xo + w;
+           ypoint[i++] = y - a;
+
+           if (x1 < xo + w) {
+                   xpoint[i] = xo + w;
+                   ypoint[i++] = y1 - a;
+           }
+    }
+
+    xpoint[i] = x1;
+    ypoint[i++] = y1 - a;
+    xpoint[i] = x1;
+    ypoint[i++] = y1 + d;
+    
+    if (y != y1) {
+           xpoint[i] = xo;
+           ypoint[i++] = y1 + d;
+           if (x > xo) {
+                   xpoint[i] = xo;
+                   ypoint[i++] = y + d;
+           }
+    }
+    xpoint[i] = xpoint[0];
+    ypoint[i++] = ypoint[0];
+
+    xp = &xpoint[0];
+    yp = &ypoint[0];
+    np = i;
+//    lyxerr << "AN[" << x << " " << y << " " << x1 << " " << y1 << "] ";
+//    lyxerr << "MT[" << a << " " << d << " " << a1 << " " << d1 << "] ";
+//    for (i = 0; i < np; ++i)
+//      lyxerr << "XY[" << point[i].x << " " << point[i].y << "] ";
+    
+}
+#else
 XPoint * MathedCursor::SelGetArea(int & np)
 {   
     if (!selection) {
@@ -979,7 +1082,7 @@ XPoint * MathedCursor::SelGetArea(int & np)
     
     return &point[0];
 }
-
+#endif
 
 
 void MathedCursor::setAccent(int ac)
index 1772357f3e953b4843aded20067013977a5219e6..c8c16e9094a8979ccadec7c870a8216d45026045 100644 (file)
@@ -37,7 +37,7 @@ class MathedCursor {
     ///
     void Insert(byte, MathedTextCodes t = LM_TC_MIN);
     ///
-    void Insert(MathedInset*, int t = LM_TC_INSET);
+    void Insert(MathedInset *, int t = LM_TC_INSET);
     ///
     void Home();
     ///
@@ -56,10 +56,17 @@ class MathedCursor {
     bool Push();
     /// Pull out an argument from its container inset
     bool pullArg();
+#ifdef USE_PAINTER
+    ///
+    void draw(Painter &, int x, int y);
+    ///
+    void Redraw(Painter &);
+#else
     ///
     void Draw(long unsigned pm, int x, int y);
     ///
     void Redraw();
+#endif
     ///
     void Delete();
     ///
@@ -115,9 +122,13 @@ class MathedCursor {
     ///
     void SelClear();
     ///
-    void SelBalance();  
+    void SelBalance();
+#ifdef USE_PAINTER
+       void SelGetArea(int * xp, int * yp, int & n);
+#else
     ///
     XPoint * SelGetArea(int &);
+#endif
     ///
     void clearLastCode() { lastcode = LM_TC_MIN; }
     ///
index 0dc1679cd8892c265cacbce0a08fe518e3cc0e7a..f9cdbabc46a1fefe547021c63af81cd258f4d953 100644 (file)
@@ -31,6 +31,8 @@
 
 #include "array.h"
 
+class Painter;
+
 
 ///
 enum math_align {
@@ -224,9 +226,14 @@ class MathedInset  {
     MathedInset(MathedInset *);
     ///
     virtual ~MathedInset() {}
-    
+
+#ifdef USE_PAINTER
+       /// Draw the object
+       virtual void draw(Painter &, int x, int baseline) = 0;  
+#else
     /// Draw the object 
     virtual void Draw(int x, int baseline) = 0;
+#endif
 
     /// Write LaTeX and Lyx code
     virtual void Write(ostream &) = 0;
@@ -267,8 +274,10 @@ class MathedInset  {
     virtual void  SetStyle(short st) { size = st; } // Metrics();
     ///
     virtual void  SetName(char const * n) { name = n; }
+#ifndef USE_PAINTER
     /// 
     void setDrawable(long unsigned int d) { pm = d; }
+#endif
  
  protected:
     ///
@@ -283,14 +292,20 @@ class MathedInset  {
     int descent;
     ///
     short size;
+#ifndef USE_PAINTER
     /// This works while only one process can draw unless
     /// the process have their own data
-    static long unsigned int pm;
+    static unsigned long pm;
+#endif
     /// Default metrics
     static int df_asc, df_des, df_width;
 
     /// In a near future maybe we use a better fonts renderer than X
+#ifdef USE_PAINTER
+    void drawStr(Painter &, short, int, int, int, byte *, int);
+#else
     void drawStr(short, int, int, int, byte *, int);
+#endif
        ///
     friend class MathedCursor;
        ///
@@ -332,7 +347,11 @@ class MathParInset: public MathedInset  {
     virtual MathedInset * Clone();
 
     /// Draw the object on a drawable
+#ifdef USE_PAINTER
+    virtual void draw(Painter &, int x, int baseline);
+#else
     virtual void Draw(int x, int baseline);
+#endif
 
     /// Write LaTeX code
     virtual void Write(ostream &);
@@ -490,8 +509,13 @@ class MathMatrixInset: public MathParInset {
     MathedInset * Clone();
     ///
     virtual ~MathMatrixInset();
+#ifdef USE_PAINTER
+       ///
+       void draw(Painter &, int, int);
+#else
     ///
     void Draw(int, int);
+#endif
     ///
     void Write(ostream &);
     ///
index 995973bbfe0ec2153057760f6b1709c871a654c4..9f5a462f6b10bb4b779b6c232541bcf17ca53f4e 100644 (file)
@@ -21,6 +21,8 @@
 #include <cstdlib>
 #include "symbol_def.h"
 #include "math_inset.h"
+#include "LColor.h"
+#include "Painter.h"
 
 /* 
  * Internal struct of a drawing: code n x1 y1 ... xn yn, where code is:
@@ -296,7 +298,73 @@ static int search_deco(int code)
    if (!math_deco_table[i].code) i = -1;
    return i;
 }
-      
+
+
+#ifdef USE_PAINTER
+void mathed_draw_deco(Painter & pain, int x, int y, int w, int h, int code)
+{
+       Matriz mt, sqmt;
+       float xx, yy, x2, y2;
+       int i = 0;
+   
+       int j = search_deco(code);   
+       if (j < 0) return;
+   
+       int r = math_deco_table[j].angle;
+       float * d = math_deco_table[j].data;
+       
+       if (h > 70 && (math_deco_table[j].code == int('(') || math_deco_table[j].code == int(')')))
+               d = parenthHigh;
+       
+       mt.rota(r);
+       mt.escala(w, h);
+   
+       int n = (w < h) ? w: h;
+       sqmt.rota(r);
+       sqmt.escala(n, n);
+       if (r > 0 && r < 3) y += h;   
+       if (r >= 2) x += w;   
+       do {
+               code = int(d[i++]);
+               switch (code) {
+               case 0: break;
+               case 1: 
+               case 3:
+               {
+                       xx = d[i++]; yy = d[i++];
+                       x2 = d[i++]; y2 = d[i++];
+                       if (code == 3) 
+                               sqmt.transf(xx, yy, xx, yy);
+                       else
+                               mt.transf(xx, yy, xx, yy);
+                       mt.transf(x2, y2, x2, y2);
+                       pain.line(x + int(xx), y + int(yy),
+                                 x + int(x2), y + int(y2),
+                                 LColor::mathline);
+                       break;
+               }        
+               case 2: 
+               case 4:
+               {
+                       int xp[32], yp[32];
+                       n = int(d[i++]);
+                       for (j = 0; j < n; ++j) {
+                               xx = d[i++]; yy = d[i++];
+//          lyxerr << " " << xx << " " << yy << " ";
+                               if (code == 4) 
+                                       sqmt.transf(xx, yy, xx, yy);
+                               else
+                                       mt.transf(xx, yy, xx, yy);
+                               xp[j] = x + int(xx);
+                               yp[j] = y + int(yy);
+                               //  lyxerr << "P[" << j " " << xx << " " << yy << " " << x << " " << y << "]";
+                       }
+                       pain.lines(xp, yp, n, LColor::mathline);
+               }
+               }
+       } while (code);
+}
+#else
 void mathed_draw_deco(Window win, int x, int y, int w, int h, int code)
 {
    Matriz mt, sqmt;
@@ -361,7 +429,31 @@ void mathed_draw_deco(Window win, int x, int y, int w, int h, int code)
       }
    } while (code);
 }
+#endif
 
+
+#ifdef USE_PAINTER
+void
+MathDelimInset::draw(Painter & pain, int x, int y)
+{ 
+       xo = x;  yo = y; 
+       MathParInset::draw(pain, x + dw + 2, y - dh); 
+       
+       if (left == '.') {
+               pain.line(x + 4, yo - ascent,
+                         x + 4, yo + descent,
+                         LColor::mathcursor);
+       } else
+               mathed_draw_deco(pain, x, y - ascent, dw, Height(), left);
+       x += Width()-dw-2;
+       if (right == '.') {
+               pain.line(x + 4, yo - ascent,
+                         x + 4, yo + descent,
+                         LColor::mathcursor);
+       } else
+               mathed_draw_deco(pain, x, y-ascent, dw, Height(), right);
+}
+#else
 void
 MathDelimInset::Draw(int x, int y)
 { 
@@ -383,6 +475,8 @@ MathDelimInset::Draw(int x, int y)
    else
      mathed_draw_deco(pm, x, y-ascent, dw, Height(), right);
 }
+#endif
+
 
 void
 MathDelimInset::Metrics()
@@ -401,12 +495,21 @@ MathDelimInset::Metrics()
 }
 
 
+#ifdef USE_PAINTER
+void
+MathDecorationInset::draw(Painter & pain, int x, int y)
+{ 
+   MathParInset::draw(pain, x + (width - dw) / 2, y);
+   mathed_draw_deco(pain, x, y + dy, width, dh, deco);
+}
+#else
 void
 MathDecorationInset::Draw(int x, int y)
 { 
    MathParInset::Draw(x+(width-dw)/2, y);
    mathed_draw_deco(pm, x, y+dy, width, dh, deco);
 }
+#endif
 
 
 void
@@ -430,6 +533,22 @@ MathDecorationInset::Metrics()
    width = w;
 }
 
+
+#ifdef USE_PAINTER
+void
+MathAccentInset::draw(Painter & pain, int x, int y)
+{
+    int dw = width - 2;
+
+    if (inset) {
+       inset->draw(pain, x, y);
+    } else {
+       drawStr(pain, fn, size, x, y, &c, 1);
+    }
+    x += (code == LM_not) ? (width-dw) / 2 : 2;
+    mathed_draw_deco(pain, x, y - dy, dw, dh, code);
+}
+#else
 void
 MathAccentInset::Draw(int x, int y)
 {
@@ -453,6 +572,8 @@ MathAccentInset::Draw(int x, int y)
     x += (code == LM_not) ? (width-dw)/2: 2;
     mathed_draw_deco(pm, x, y-dy, dw, dh, code);
 }
+#endif
+
 
 void
 MathAccentInset::Metrics()
@@ -482,6 +603,16 @@ MathAccentInset::Metrics()
 }
 
 
+#ifdef USE_PAINTER
+void
+MathDotsInset::draw(Painter & pain, int x, int y)
+{
+   mathed_draw_deco(pain, x + 2, y - dh, width - 2, ascent, code);
+   if (code == LM_vdots || code == LM_ddots) ++x; 
+   if (code != LM_vdots) --y;
+   mathed_draw_deco(pain, x + 2, y - dh, width - 2, ascent, code);
+}
+#else
 void
 MathDotsInset::Draw(int x, int y)
 {
@@ -489,7 +620,9 @@ MathDotsInset::Draw(int x, int y)
    if (code == LM_vdots || code == LM_ddots) ++x; 
    if (code!= LM_vdots) --y;
    mathed_draw_deco(pm, x + 2, y - dh, width - 2, ascent, code);
-}     
+}
+#endif
+
 
 void
 MathDotsInset::Metrics()
index aece4abd22d8578076bacf3fad68a0778a63d3bb..9efb95adcfe5d0415b68f9888d200b6ae19862d4 100644 (file)
 #include "math_cursor.h"
 #include "math_parser.h"
 #include "debug.h"
+#include "lyxfont.h"
+#include "Painter.h"
 
+#ifdef USE_PAINTER
+extern LyXFont mathed_get_font(short type, int size);
+#else
 extern void mathed_set_font(short type, int style);
+#endif
 extern int mathed_char_width(short type, int style, byte c);
 extern int mathed_string_width(short type, int style, byte const* s, int ls);
 extern int mathed_string_height(short, int, byte const*, int, int&, int&);
@@ -30,8 +36,30 @@ extern int mathed_char_height(short, int, byte, int&, int&);
 GC canvasGC= 0, mathGC= 0, mathLineGC= 0, latexGC= 0, cursorGC= 0, mathFrameGC= 0;
 
 
-long unsigned int MathedInset::pm;
+#ifndef USE_PAINTER
+unsigned long MathedInset::pm;
+#endif
 
+#ifdef USE_PAINTER
+void
+MathSpaceInset::draw(Painter & pain, int x, int y)
+{ 
+
+// XPoint p[4] = {{++x, y-3}, {x, y}, {x+width-2, y}, {x+width-2, y-3}};
+
+// Sadly, HP-UX CC can't handle that kind of initialization.
+
+   int xp[4];
+   int yp[4];
+   
+   xp[0] = ++x;            yp[0] = y - 3;
+   xp[1] = x;             yp[1] = y;
+   xp[2] = x + width - 2;  yp[2] = y;
+   xp[3] = x + width - 2;  yp[3] = y - 3;
+
+   pain.lines(xp, yp, 4, (space) ? LColor::latex : LColor::math);
+}
+#else
 void
 MathSpaceInset::Draw(int x, int y)
 { 
@@ -49,7 +77,96 @@ MathSpaceInset::Draw(int x, int y)
    XDrawLines(fl_display, pm,(space) ? latexGC: mathGC, p, 4, CoordModeOrigin);
    XFlush(fl_display);
 }
+#endif
 
+
+#ifdef USE_PAINTER
+void 
+MathParInset::draw(Painter & pain, int x, int y)
+{
+   byte cx, cxp = 0;
+   int xp = 0, ls;
+   int asc = df_asc, des = 0;
+   bool limits = false;
+    
+   xo = x;  yo = y; 
+   if (!array || array->empty()) {
+       if (array) {
+          MathedXIter data(this);
+          data.GetPos(x, y);
+       }
+       pain.rectangle(x, y - df_asc, df_width, df_asc, LColor::mathline);
+      return;
+   }  
+   MathedXIter data(this);
+   data.GoBegin();
+   while (data.OK()) {
+      data.GetPos(x, y);
+      cx = data.GetChar();
+      if (cx >= ' ') {
+        byte * s = data.GetString(ls);
+         drawStr(pain, data.FCode(), size, x, y, s, ls);
+         mathed_char_height(LM_TC_CONST, size, 'y', asc, des);
+         limits = false;
+      } else {
+         if (cx == 0) break;
+        if (MathIsInset(cx)) {
+           int yy = y;
+           MathedInset * p = data.GetInset();
+           if (cx == LM_TC_UP) {
+              if (limits) {
+                 x -= (xp>p->Width()) ? p->Width()+(xp-p->Width())/2: xp;  
+                 yy -= (asc + p->Descent()+4);
+              } else
+                 yy -= (p->Descent()>asc) ? p->Descent()+4: asc;
+           } else
+           if (cx == LM_TC_DOWN) {
+              if (limits) {
+                 x -= (xp>p->Width()) ? p->Width()+(xp-p->Width())/2: xp;
+                 yy += des + p->Ascent() + 2;
+              } else
+                yy += des + p->Ascent()/2;
+           } else {
+              asc = p->Ascent();
+              des = p->Descent();
+           }
+           p->draw(pain, x, yy);
+           if (cx!= LM_TC_UP && cx!= LM_TC_DOWN) {
+              limits = p->GetLimits();
+              if (limits) xp = p->Width();
+           }
+           data.Next();
+        } else 
+          if (cx == LM_TC_TAB) {
+              if ((cxp == cx || cxp == LM_TC_CR || data.IsFirst())) { // && objtype == L
+                      pain.rectangle(x, y - df_asc, df_width, df_asc,
+                                     LColor::mathline);
+              }
+             data.Next();
+             limits = false;
+          } else
+           if (cx == LM_TC_CR) {
+               if (cxp == LM_TC_TAB || cxp == LM_TC_CR || data.IsFirst()) { //  && objtype == LM_OT_MATRIX) {
+                       pain.rectangle(x, y - df_asc, df_width, df_asc,
+                                      LColor::mathline);
+               }
+               data.Next();
+               limits = false;
+           }
+        else {  
+                lyxerr << "GMathed Error: Unrecognized code[" << cx
+                       << "]" << endl;
+           break;
+        }
+      }
+      cxp = cx;
+   }
+   if (cxp == LM_TC_TAB || cxp == LM_TC_CR) { // && objtype == LM_OT_MATRIX) {
+      data.GetPos(x, y);
+      pain.rectangle(x, y - df_asc, df_width, df_asc, LColor::mathline);
+   }
+}
+#else
 void 
 MathParInset::Draw(int x, int y)
 {
@@ -139,6 +256,7 @@ MathParInset::Draw(int x, int y)
       XFlush(fl_display);
    }
 }
+#endif
 
 
 void 
@@ -248,19 +366,41 @@ MathParInset::Metrics()
 }
 
 
+#ifdef USE_PAINTER
+void
+MathSqrtInset::draw(Painter & pain, int x, int y)
+{ 
+   MathParInset::draw(pain, x + hmax + 2, y); 
+   int h = ascent;
+   int d = descent;
+   int h2 = Height() / 2;
+   int w2 = (Height() > 4 * hmax) ? hmax : hmax / 2; 
+   int xp[4], yp[4];
+   xp[0] = x + hmax + wbody; yp[0] = y - h;
+   xp[1] = x + hmax;         yp[1] = y - h;
+   xp[2] = x + w2;           yp[2] = y + d;
+   xp[3] = x;                yp[3] = y + d - h2;
+   pain.lines(xp, yp, 4, LColor::mathline);
+}
+#else
 void
 MathSqrtInset::Draw(int x, int y)
 { 
    MathParInset::Draw(x+hmax+2, y); 
-   int h= ascent, d= descent, h2= Height()/2, w2 = (Height()>4*hmax)?hmax:hmax/2; 
+   int h = ascent;
+   int d = descent;
+   int h2 = Height() / 2;
+   int w2 = (Height() > 4 * hmax) ? hmax : hmax / 2; 
    XPoint p[4];
-   p[0].x = x + hmax + wbody, p[0].y = y-h;
-   p[1].x = x+hmax,    p[1].y = y-h;
-   p[2].x = x+w2,      p[2].y = y+d;
-   p[3].x = x,         p[3].y = y+d-h2;
+   p[0].x = x + hmax + wbody; p[0].y = y - h;
+   p[1].x = x + hmax;    p[1].y = y - h;
+   p[2].x = x + w2;      p[2].y = y + d;
+   p[3].x = x;         p[3].y = y + d - h2;
    XDrawLines(fl_display, pm, mathLineGC, p, 4, CoordModeOrigin);
    XFlush(fl_display);
 }
+#endif
+
 
 void
 MathSqrtInset::Metrics()
@@ -270,11 +410,29 @@ MathSqrtInset::Metrics()
    descent += 2;
    int a, b;
    hmax = mathed_char_height(LM_TC_VAR, size, 'I', a, b);
-   if (hmax<10) hmax = 10;
+   if (hmax < 10) hmax = 10;
    wbody = width + 4;
    width += hmax + 4;
 }
 
+
+#ifdef USE_PAINTER
+void
+MathFracInset::draw(Painter & pain, int x, int y)
+{ 
+    short idxp = idx;
+    short sizex = size;
+    
+    idx = 0;
+    if (size == LM_ST_DISPLAY) ++size;
+    MathParInset::draw(pain, x + (width - w0) / 2, y - des0);
+    den->draw(pain, x + (width - w1) / 2, y + den->Ascent() + 2 - dh);
+    size = sizex;
+    if (objtype == LM_OT_FRAC)
+           pain.line(x + 2, y - dh, x + width - 4, y - dh, LColor::mathline);
+    idx = idxp;
+}
+#else
 void
 MathFracInset::Draw(int x, int y)
 { 
@@ -283,14 +441,17 @@ MathFracInset::Draw(int x, int y)
     
     idx = 0;
     if (size == LM_ST_DISPLAY) ++size;
-    MathParInset::Draw(x+(width-w0)/2, y - des0);
-    den->Draw(x+(width-w1)/2, y + den->Ascent() + 2 - dh);
+    MathParInset::Draw(x + (width - w0) / 2, y - des0);
+    den->Draw(x + (width - w1) / 2, y + den->Ascent() + 2 - dh);
     size = sizex;
     if (objtype == LM_OT_FRAC)
-      XDrawLine(fl_display, pm, mathLineGC, x+2, y-dh, x+width-4, y - dh);
+      XDrawLine(fl_display, pm, mathLineGC,
+               x + 2, y - dh, x + width - 4, y - dh);
     XFlush(fl_display);
     idx = idxp;
 }
+#endif
+
 
 void
 MathFracInset::Metrics()
@@ -317,6 +478,33 @@ MathFracInset::Metrics()
 }
 
 
+#ifdef USE_PAINTER
+void
+MathBigopInset::draw(Painter & pain, int x, int y)
+{
+   int ls;
+   char c;
+   char const *s;
+   short t;
+   
+   if (sym < 256 || sym == LM_oint) {
+      ls = 1;
+      c = (sym == LM_oint) ? LM_int : sym;
+      s = &c;
+      t = LM_TC_BSYM;
+   } else {
+      s = name;
+      ls = strlen(name);
+      t = LM_TC_TEXTRM;
+   }
+   if (sym == LM_oint) {
+          pain.arc(x, y - 5 * width / 4, width, width, 0, 360*64,
+                   LColor::mathline);
+          ++x;
+   }
+   pain.text(x, y, s, ls, mathed_get_font(t, size));
+}
+#else
 void
 MathBigopInset::Draw(int x, int y)
 {
@@ -344,7 +532,37 @@ MathBigopInset::Draw(int x, int y)
    XDrawString(fl_display, pm, mathGC, x, y, s, ls);
    XFlush(fl_display);
 }
+#endif
 
+
+#ifdef USE_PAINTER
+void
+MathBigopInset::Metrics()
+{   
+       int ls;
+       char c;
+       char const *s;
+       short t;
+       
+       if (sym < 256 || sym == LM_oint) {
+               ls = 1;
+               c = (sym == LM_oint) ? LM_int: sym;
+               s = &c;
+               t = LM_TC_BSYM;
+       } else {
+               s = name;
+               ls = strlen(name);
+               t = LM_TC_TEXTRM;
+       }
+       mathed_string_height(t, size,
+                            reinterpret_cast<const unsigned char*>(s),
+                            ls, ascent, descent);
+       width = mathed_string_width(t, size,
+                                   reinterpret_cast<const unsigned char*>(s),
+                                   ls);
+       if (sym == LM_oint) width += 2;
+}
+#else
 void
 MathBigopInset::Metrics()
 {   
@@ -368,4 +586,5 @@ MathBigopInset::Metrics()
    width = mathed_string_width(t, size, reinterpret_cast<const unsigned char*>(s), ls);
    if (sym == LM_oint) width += 2;
 }
+#endif
 
index ea81e507bde5f0e10656876b38c85830ef55f9f2..da543e7a25ec8b87bf41b2246fd400451f200f56 100644 (file)
@@ -416,10 +416,17 @@ void MathMatrixInset::SetData(LyxArrayBase * a)
 }
 
 
+#ifdef USE_PAINTER
+void MathMatrixInset::draw(Painter & pain, int x, int baseline)
+{
+    MathParInset::draw(pain, x, baseline);
+}
+#else
 void MathMatrixInset::Draw(int x, int baseline)
 {
     MathParInset::Draw(x, baseline);
-}                
+}
+#endif
 
 
 void MathMatrixInset::Metrics()
index 536e83458db58f0b2d22756811ea4a1ff24c344c..c128fca9cbdca191b59a9053ffb45fd472cd02ef 100644 (file)
@@ -43,8 +43,13 @@ public:
        ~MathFuncInset();
        ///
        MathedInset * Clone();
+#ifdef USE_PAINTER
+       ///
+       void draw(Painter &, int, int);
+#else
        ///
        void Draw(int, int);
+#endif
        ///
        void Write(ostream &);
        ///
@@ -74,8 +79,13 @@ public:
        ~MathAccentInset();
        ///
        MathedInset * Clone();
+#ifdef USE_PAINTER
+       ///
+       void draw(Painter &, int, int);
+#else
        ///
        void Draw(int, int);
+#endif
        ///
        void Write(ostream &);
        ///
@@ -106,8 +116,13 @@ public:
        MathDotsInset(char const *, int, short st = LM_ST_TEXT);
        ///
        MathedInset * Clone();
+#ifdef USE_PAINTER
+       ///
+       void draw(Painter &, int, int);
+#else
        ///
        void Draw(int, int);
+#endif
        ///
        void Write(ostream &);
        ///
@@ -127,8 +142,13 @@ public:
        MathSpaceInset(int sp, short ot = LM_OT_SPACE, short st = LM_ST_TEXT);
        ///
        MathedInset * Clone();
+#ifdef USE_PAINTER
+       ///
+       void draw(Painter &, int, int);
+#else
        ///
        void Draw(int, int);
+#endif
        ///
        void Write(ostream &);
        ///
@@ -152,8 +172,13 @@ public:
        MathBigopInset(char const *, int, short st = LM_ST_TEXT);
        ///
        MathedInset * Clone();
+#ifdef USE_PAINTER
+       ///
+       void draw(Painter &, int, int);
+#else
        ///
        void Draw(int, int);
+#endif
        ///
        void Write(ostream &);
        ///
@@ -181,8 +206,12 @@ public:
        MathSqrtInset(short st = LM_ST_TEXT);
        ///
        MathedInset * Clone();
+#ifdef USE_PAINTER
+       void draw(Painter &, int x, int baseline);
+#else
        ///
        void Draw(int x, int baseline);
+#endif
        ///
        void Write(ostream &);
        ///
@@ -206,8 +235,13 @@ public:
        ~MathFracInset();
        ///
        MathedInset * Clone();
+#ifdef USE_PAINTER
+       ///
+       void draw(Painter &, int x, int baseline);
+#else
        ///
        void Draw(int x, int baseline);
+#endif
        ///
        void Write(ostream &);
        ///
@@ -254,8 +288,13 @@ public:
        MathDelimInset(int, int, short st = LM_ST_TEXT);
        ///
        MathedInset * Clone();
+#ifdef USE_PAINTER
+       ///
+       void draw(Painter &, int, int);
+#else
        ///
        void Draw(int, int);
+#endif
        ///
        void Write(ostream &);
        ///
@@ -277,8 +316,13 @@ public:
        MathDecorationInset(int, short st = LM_ST_TEXT);
        ///
        MathedInset * Clone();
+#ifdef USE_PAINTER
+       ///
+       void draw(Painter &, int, int);
+#else
        ///
        void Draw(int, int);
+#endif
        ///
        void Write(ostream &);
        ///
index c4d8bfddac9c30e8e9f533457b62f39aa899e208..708c422b75322b7577353b4435df59f9f60f598d 100644 (file)
@@ -119,6 +119,19 @@ void MathMacro::Metrics()
 }
 
 
+#ifdef USE_PAINTER
+void MathMacro::draw(Painter & pain, int x, int y)
+{
+    xo = x;  yo = y;
+    Metrics();
+    tmplate->update(this);
+    tmplate->SetStyle(size);
+    mathGC = latexGC;
+    tmplate->draw(pain, x, y);
+    for (int i = 0; i < nargs; ++i)
+      tmplate->GetMacroXY(i, args[i].x, args[i].y);
+}
+#else
 void MathMacro::Draw(int x, int y)
 {
     xo = x;  yo = y;
@@ -130,6 +143,7 @@ void MathMacro::Draw(int x, int y)
     for (int i = 0; i < nargs; ++i)
       tmplate->GetMacroXY(i, args[i].x, args[i].y);
 }
+#endif
 
 
 int MathMacro::GetColumns()
@@ -222,6 +236,18 @@ MathMacroArgument::MathMacroArgument(int n)
 }
 
 
+#ifdef USE_PAINTER
+void MathMacroArgument::draw(Painter & pain, int x, int baseline)
+{
+    if (expnd_mode) {
+       MathParInset::draw(pain, x, baseline);
+    } else {
+       unsigned char s[3];
+       sprintf(reinterpret_cast<char*>(s), "#%d", number);
+       drawStr(pain, LM_TC_TEX, size, x, baseline, &s[0], 2);
+    }
+}
+#else
 void MathMacroArgument::Draw(int x, int baseline)
 {
     if (expnd_mode) {
@@ -232,6 +258,7 @@ void MathMacroArgument::Draw(int x, int baseline)
        drawStr(LM_TC_TEX, size, x, baseline, &s[0], 2);
     }
 }
+#endif
 
 
 void MathMacroArgument::Metrics()
@@ -310,6 +337,30 @@ void MathMacroTemplate::setEditMode(bool ed)
 }
 
 
+#ifdef USE_PAINTER
+void MathMacroTemplate::draw(Painter & pain, int x, int y)
+{
+    int x2, y2;
+    bool expnd = (nargs > 0) ? args[0].getExpand(): false;
+    if (flags & MMF_Edit) {
+       for (int i = 0; i < nargs; ++i) {
+           args[i].setExpand(false);
+       }
+      x2 = x; y2 = y;
+    } else {
+       for (int i = 0; i < nargs; ++i) {
+           args[i].setExpand(true);
+       }
+      x2 = xo; y2 = yo;
+    }
+    MathParInset::draw(pain, x, y);
+    xo = x2; yo = y2;
+    
+    for (int i = 0; i < nargs; ++i) {
+       args[i].setExpand(expnd);
+    }
+}
+#else
 void MathMacroTemplate::Draw(int x, int y)
 {
     int x2, y2;
@@ -332,6 +383,7 @@ void MathMacroTemplate::Draw(int x, int y)
        args[i].setExpand(expnd);
     }
 }
+#endif
 
 
 void MathMacroTemplate::Metrics()
index f25ffb2029c35d6525b5d0414a91d91574354eb3..abf40f2eb4efdc39b9e5dee63f7c019c1708159e 100644 (file)
@@ -42,8 +42,13 @@ class MathMacro : public MathParInset
     MathMacro(MathMacro *);
        ///
     ~MathMacro();
+#ifdef USE_PAINTER
+       ///
+       void draw(Painter &, int, int);
+#else
        ///
     void Draw(int, int);
+#endif
        ///
     void Metrics();
        ///
@@ -115,8 +120,13 @@ class MathMacroArgument: public MathParInset
     MathedInset * Clone() { return this; }
        ///
     void Metrics();
+#ifdef USE_PAINTER
+       ///
+       void draw(Painter &, int x, int baseline);
+#else
        ///
     void Draw(int x, int baseline);
+#endif
        ///
     void Write(ostream &);
        ///
@@ -144,8 +154,13 @@ class MathMacroTemplate: public MathParInset
     MathMacroTemplate(char const *, int na = 0, int f = 0);
        ///
     ~MathMacroTemplate();
+#ifdef USE_PAINTER
+       ///
+       void draw(Painter &, int, int);
+#else
        ///
     void Draw(int, int);
+#endif
        ///
     void Metrics();
        ///
index 791f7cd74c24a0b522037d4b3048622e27e975ac..bce021dafc23722a4393c3f83e805db77fd806c2 100644 (file)
@@ -109,6 +109,17 @@ void MathRootInset::Metrics()
 }
 
 
+#ifdef USE_PAINTER
+void MathRootInset::draw(Painter & pain, int x, int y)
+{
+    int idxp = idx;
+
+    idx = 1;
+    uroot->draw(pain, x, y - dh);
+    MathSqrtInset::draw(pain, x + wroot, y);
+    idx = idxp;
+}
+#else
 void MathRootInset::Draw(int x, int y)
 {
     int idxp = idx;
@@ -119,6 +130,7 @@ void MathRootInset::Draw(int x, int y)
     XFlush(fl_display);
     idx = idxp;
 }
+#endif
 
 
 void MathRootInset::SetStyle(short st)
index b9e5569a53e5fda5132052129760e3be77578b0a..41a00ecb3adeb4a517683bf202a50fe75b88e01a 100644 (file)
@@ -36,8 +36,13 @@ class MathRootInset: public MathSqrtInset {
     ~MathRootInset();
     ///
     MathedInset * Clone();
+#ifdef USE_PAINTER
+       ///
+       void draw(Painter &, int x, int baseline);
+#else
     ///
     void Draw(int x, int baseline);
+#endif
     ///
     void Write(ostream &);
     ///
index 5b0126d22c2595b43c17c29c00b66fb6c50b393e..1ddc78708840f6ac4eb0d093967ba47d371e8582 100644 (file)
@@ -46,8 +46,12 @@ void MiniBuffer::ExecutingCB(FL_OBJECT * ob, long)
 {
        MiniBuffer * obj = static_cast<MiniBuffer*>(ob->u_vdata);
        lyxerr.debug() << "Getting ready to execute: " << obj->cur_cmd << endl;
+#ifdef NEW_WA
+       obj->owner->view()->focus(true);
+#else
        fl_set_focus_object(obj->owner->getForm(),
                            obj->owner->view()->getWorkArea());
+#endif
        if (obj->cur_cmd.empty()) { 
                obj->Init();
                return ; 
@@ -100,8 +104,12 @@ int MiniBuffer::peek_event(FL_OBJECT * ob, int event, FL_Coord, FL_Coord,
                case 27:
                case XK_Escape:
                        // Abort
+#ifdef NEW_WA
+                       mini->owner->view()->focus(true);
+#else
                        fl_set_focus_object(mini->owner->getForm(),
                                            mini->owner->view()->getWorkArea());
+#endif
                        mini->Init();
                        return 1; 
                case 13:
index 1bd9a76d9583b20d2995054b56a912e589a538ec..0d65e12ee838814a6d84d0f4db81266d69490a3b 100644 (file)
@@ -43,7 +43,11 @@ extern LyXRC * lyxrc;
 
 
 // ale970405
+#ifdef USE_PAINTER
+extern string bibitemWidthest(Painter &);
+#else
 extern string bibitemWidthest();
+#endif
 
 // this is a minibuffer
 static char minibuffer_char;
@@ -344,10 +348,17 @@ void LyXParagraph::validate(LaTeXFeatures & features) const
                                             << endl;
                }
                switch ((*cit).font.color()) {
+#ifdef USE_PAINTER
+               case LColor::none:
+               case LColor::inherit:
+               case LColor::ignore:
+                       break;
+#else
                case LyXFont::NONE:
                case LyXFont::INHERIT_COLOR:
                case LyXFont::IGNORE_COLOR:
                        break;
+#endif
                default:
                        features.color = true;
                        lyxerr[Debug::LATEX] << "Color enabled. Font: "
@@ -3403,7 +3414,12 @@ LyXParagraph * LyXParagraph::TeXEnvironment(string & file, TexRow & texrow,
                } else if (style.labeltype == LABEL_BIBLIO) {
                        // ale970405
                        file += "\\begin{" + style.latexname() + "}{"
+#ifdef USE_PAINTER
+                               + bibitemWidthest(current_view->painter())
+                               + "}\n";
+#else
                                + bibitemWidthest() + "}\n";
+#endif
                } else if (style.latextype == LATEX_ITEM_ENVIRONMENT) {
 #ifdef FANCY_FOOTNOTE_CODE
                        if (foot_count < 0) {
index 97ceae396c6cf9baf01f200c974b94e254fabdd7..ded4be2502dd7f894cab39cee9069ce2fd87ed1e 100644 (file)
 #include "lyxdraw.h"
 #include "lyxtext.h"
 #include "lyxrow.h"
+#include "BufferView.h"
+#include "Painter.h"
 
 extern int mono_video;
 extern int fast_selection;
 
+#ifdef USE_PAINTER
+static
+GC createGC()
+{
+       XGCValues val;
+       val.foreground = BlackPixel(fl_display, 
+                                   DefaultScreen(fl_display));
+       
+       val.function=GXcopy;
+       val.graphics_exposures = false;
+       val.line_style = LineSolid;
+       val.line_width = 0;
+       return XCreateGC(fl_display, RootWindow(fl_display, 0), 
+                        GCForeground | GCFunction | GCGraphicsExposures
+                        | GCLineWidth | GCLineStyle , &val);
+}
+#endif
+
+
 // Constructor
-LyXScreen::LyXScreen(Window window,
+LyXScreen::LyXScreen(BufferView * o, Window window,
+#ifdef NEW_WA
+                    Pixmap p,
+#endif
                     Dimension width, 
                     Dimension height,
                     Dimension offset_x,
                     Dimension offset_y,
                     LyXText *text_ptr)
-       : text(text_ptr), _window(window), 
+       : owner(o), text(text_ptr), _window(window), 
        _width(width), _height(height),
        _offset_x(offset_x), _offset_y(offset_y)
 {
@@ -40,22 +64,33 @@ LyXScreen::LyXScreen(Window window,
        screen_refresh_y = -1;
 
        /* create the foreground pixmap */
+#ifdef NEW_WA
+       foreground = p;
+#else
        foreground = XCreatePixmap (fl_display,
                                    fl_root,
                                    _width, _height, 
                                    fl_get_visual_depth());
+#endif
        cursor_pixmap = 0;
        cursor_pixmap_x = 0;
        cursor_pixmap_y = 0;
        cursor_pixmap_w = 0;
        cursor_pixmap_h = 0;
+
+#ifdef USE_PAINTER
+       // We need this GC
+       gc_copy = createGC();
+#endif
 }
 
 
 // Destructor
 LyXScreen::~LyXScreen()
 {
+#ifndef NEW_WA
        XFreePixmap(fl_display, foreground);
+#endif
 }
 
 
@@ -71,6 +106,18 @@ void LyXScreen::Redraw()
 }
 
 
+#ifdef USE_PAINTER
+void LyXScreen::expose(int x, int y, int exp_width, int exp_height)
+{
+       XCopyArea(fl_display,
+                 foreground,
+                 _window,
+                 gc_copy,
+                 x, y,
+                 exp_width, exp_height,
+                 x+_offset_x, y+_offset_y);
+}
+#else
 void LyXScreen::expose(int x, int y, int exp_width, int exp_height)
 {
        XCopyArea(fl_display,
@@ -81,8 +128,36 @@ void LyXScreen::expose(int x, int y, int exp_width, int exp_height)
                  exp_width, exp_height,
                  x+_offset_x, y+_offset_y);
 }
+#endif
 
 
+#ifdef USE_PAINTER
+void LyXScreen::DrawFromTo(int y1, int y2)
+{
+       long y_text = first + y1;
+   
+       /* get the first needed row */ 
+       Row * row = text->GetRowNearY(y_text);
+       /* y_text is now the real beginning of the row */
+   
+       long y = y_text - first;
+       /* y1 is now the real beginning of row on the screen */
+       
+       while (row != 0 && y < y2) {
+
+               text->GetVisibleRow(y, row, y + first);
+               y += row->height;
+               row = row -> next;
+
+       }
+   
+       /* maybe we have to clear the screen at the bottom */ 
+       if (y < y2) {
+               owner->painter().fillRectangle(0, y, _width, y2 - y,
+                                              LColor::bottomarea);
+       }
+}
+#else
 void LyXScreen::DrawFromTo(int y1, int y2)
 {
        long y_text = first + y1;
@@ -111,6 +186,7 @@ void LyXScreen::DrawFromTo(int y1, int y2)
                              y2 - y);
        }
 }
+#endif
 
 
 void LyXScreen::DrawOneRow(Row * row, long & y_text)
@@ -119,7 +195,11 @@ void LyXScreen::DrawOneRow(Row * row, long & y_text)
       
        if (y + row->height > 0 && y - row->height <= _height) {
                /* ok there is something visible */
+#ifdef USE_PAINTER
+               text->GetVisibleRow(y, row, y + first);
+#else
                text->GetVisibleRow(*this, y, row, y + first);
+#endif
        }
        y_text+= row->height;
 }
@@ -127,6 +207,49 @@ void LyXScreen::DrawOneRow(Row * row, long & y_text)
 
 /* draws the screen, starting with textposition y. uses as much already
 * printed pixels as possible */
+#ifdef USE_PAINTER
+void LyXScreen::Draw(long  y)
+{
+       if (cursor_visible) HideCursor();
+
+       if (y < 0) y = 0;
+       long old_first = first;
+       first = y;
+
+       /* is any optimiziation possible? */ 
+       if ((y - old_first) < _height 
+           && (old_first - y) < _height) {
+               if (first < old_first) {
+                       DrawFromTo(0, old_first - first);
+                       XCopyArea (fl_display,
+                                  _window,
+                                  _window,
+                                  gc_copy,
+                                  _offset_x, _offset_y, 
+                                  _width , _height - old_first + first,
+                                  _offset_x, _offset_y + old_first - first);
+                       // expose the area drawn
+                       expose(0, 0, _width, old_first - first);
+               } else  {
+                       DrawFromTo(_height + old_first - first, _height);
+                       XCopyArea (fl_display,
+                                  _window,
+                                  _window,
+                                  gc_copy,
+                                  _offset_x, _offset_y + first - old_first, 
+                                  _width , _height + old_first - first, 
+                                  _offset_x, _offset_y);
+                       // expose the area drawn
+                       expose(0, _height + old_first - first, 
+                              _width, first - old_first);
+               }
+       } else {
+               /* make a dumb new-draw */ 
+               DrawFromTo(0, _height);
+               expose(0, 0, _width, _height);
+       }
+}
+#else
 void LyXScreen::Draw(long  y)
 {
        if (cursor_visible) HideCursor();
@@ -168,6 +291,7 @@ void LyXScreen::Draw(long  y)
                expose(0, 0, _width, _height);
        }
 }
+#endif
 
 
 void LyXScreen::ShowCursor()
@@ -189,6 +313,7 @@ void LyXScreen::ShowCursor()
        // Secure against very strange situations
        if (y2 < y1) y2 = y1;
 
+#ifndef USE_PAINTER
        if (fast_selection || mono_video) {
                if (y2 > 0 && y1 < _height) {
                        XDrawLine(fl_display,
@@ -200,6 +325,7 @@ void LyXScreen::ShowCursor()
                        cursor_visible = true;
                }
        } else {
+#endif
                if (cursor_pixmap){
                        XFreePixmap(fl_display, cursor_pixmap);
                        cursor_pixmap = 0;
@@ -216,6 +342,22 @@ void LyXScreen::ShowCursor()
                                              cursor_pixmap_w,
                                              cursor_pixmap_h,
                                              fl_get_visual_depth());
+#ifdef USE_PAINTER
+                       XCopyArea(fl_display,
+                                 _window,
+                                 cursor_pixmap,
+                                 gc_copy,
+                                 _offset_x + cursor_pixmap_x, 
+                                 _offset_y + cursor_pixmap_y,
+                                 cursor_pixmap_w, cursor_pixmap_h,
+                                 0, 0);
+                       XDrawLine(fl_display,
+                                 _window, gc_copy,
+                                 x + _offset_x,
+                                 y1 + _offset_y,
+                                 x + _offset_x,
+                                 y2 + _offset_y);
+#else
                        XCopyArea(fl_display,
                                  _window,
                                  cursor_pixmap,
@@ -225,14 +367,18 @@ void LyXScreen::ShowCursor()
                                  cursor_pixmap_w, cursor_pixmap_h,
                                  0, 0);
                        XDrawLine(fl_display,
-                                 _window, getGC(gc_copy),
+                                 _window,
+                                 getGC(gc_copy),
                                  x + _offset_x,
                                  y1 + _offset_y,
                                  x + _offset_x,
-                                 y2 + _offset_y); 
+                                 y2 + _offset_y);
+#endif
                        cursor_visible = true;
                }
+#ifndef USE_PAINTER
        }
+#endif
 }
 
 
@@ -279,7 +425,8 @@ void  LyXScreen::ShowManualCursor(long x, long y, int asc, int desc)
        y2 = y -first + desc;
        if (y2 > _height)
                y2 = _height;
-       
+
+#ifndef USE_PAINTER
        if (fast_selection || mono_video) {
                if (y2 > 0 && y1 < _height) {
                        XDrawLine(fl_display,
@@ -290,6 +437,7 @@ void  LyXScreen::ShowManualCursor(long x, long y, int asc, int desc)
                                  y2+_offset_y);
                }
        } else {
+#endif
                if (cursor_pixmap){
                        XFreePixmap(fl_display, cursor_pixmap);
                        cursor_pixmap = 0;
@@ -306,7 +454,23 @@ void  LyXScreen::ShowManualCursor(long x, long y, int asc, int desc)
                                               cursor_pixmap_w,
                                               cursor_pixmap_h,
                                               fl_get_visual_depth());
-
+#ifdef USE_PAINTER
+                       XCopyArea (fl_display,
+                                  _window,
+                                  cursor_pixmap,
+                                  gc_copy,
+                                  _offset_x + cursor_pixmap_x,
+                                  _offset_y + cursor_pixmap_y,
+                                  cursor_pixmap_w,
+                                  cursor_pixmap_h,
+                                  0, 0);
+                       XDrawLine(fl_display,
+                                 _window, gc_copy,
+                                 x+_offset_x,
+                                 y1+_offset_y,
+                                 x+_offset_x,
+                                 y2+_offset_y);
+#else
                        XCopyArea (fl_display,
                                   _window,
                                   cursor_pixmap,
@@ -317,27 +481,43 @@ void  LyXScreen::ShowManualCursor(long x, long y, int asc, int desc)
                                   cursor_pixmap_h,
                                   0, 0);
                        XDrawLine(fl_display,
-                                 _window, getGC(gc_copy),
+                                 _window,
+                                 getGC(gc_copy),
                                  x+_offset_x,
                                  y1+_offset_y,
                                  x+_offset_x,
-                                 y2+_offset_y);                        
+                                 y2+_offset_y);
+#endif
                }
                cursor_visible = true;
+#ifndef USE_PAINTER
        }
+#endif
 }
 
 
 void LyXScreen::HideCursor()
 {
        if (!cursor_visible) return;
-       
+
+#ifndef USE_PAINTER
        if (fast_selection || mono_video) {
                cursor_visible = false;
                ShowCursor();
                cursor_visible = false;
        } else {
+#endif
                if (cursor_pixmap){
+#ifdef USE_PAINTER
+                       XCopyArea (fl_display, 
+                                  cursor_pixmap,
+                                  _window,
+                                  gc_copy,
+                                  0, 0, 
+                                  cursor_pixmap_w, cursor_pixmap_h,
+                                  cursor_pixmap_x + _offset_x,
+                                  cursor_pixmap_y + _offset_y);
+#else
                        XCopyArea (fl_display, 
                                   cursor_pixmap,
                                   _window,
@@ -346,9 +526,12 @@ void LyXScreen::HideCursor()
                                   cursor_pixmap_w, cursor_pixmap_h,
                                   cursor_pixmap_x + _offset_x,
                                   cursor_pixmap_y + _offset_y);
+#endif
                }
                cursor_visible = false;
+#ifndef USE_PAINTER
        }
+#endif
 }
 
 
@@ -364,7 +547,7 @@ void LyXScreen::CursorToggle()
 /* returns a new top so that the cursor is visible */ 
 long LyXScreen::TopCursorVisible()
 {
-       long  newtop = first;
+       long newtop = first;
 
        if (text->cursor.y
            - text->cursor.row->baseline
@@ -488,7 +671,7 @@ void LyXScreen::ToggleSelection(bool kill_selection)
        long top = 0;
        long bottom = 0;
    
-       
+#ifndef USE_PAINTER
        if (fast_selection || mono_video) {
                
                /* selection only in one row ?*/ 
@@ -603,6 +786,7 @@ void LyXScreen::ToggleSelection(bool kill_selection)
                        }
                }
        } else {
+#endif
                top = text->sel_start_cursor.y
                        - text->sel_start_cursor.row->baseline;
                bottom = text->sel_end_cursor.y
@@ -623,7 +807,9 @@ void LyXScreen::ToggleSelection(bool kill_selection)
                        text->selection = 0;
                DrawFromTo(top - first, bottom - first);
                expose(0, top - first, _width, bottom - first - (top - first));
+#ifndef USE_PAINTER
        }
+#endif
 }
   
    
@@ -636,6 +822,7 @@ void LyXScreen::ToggleToggle()
            && text->toggle_cursor.pos == text->toggle_end_cursor.pos)
                return;
 
+#ifndef USE_PAINTER
        if (fast_selection || mono_video) {
                
                /* selection only in one row ?*/ 
@@ -729,6 +916,7 @@ void LyXScreen::ToggleToggle()
                        }
                }
        } else {
+#endif
                top = text->toggle_cursor.y
                        - text->toggle_cursor.row->baseline;
                bottom = text->toggle_end_cursor.y
@@ -747,11 +935,13 @@ void LyXScreen::ToggleToggle()
                
                DrawFromTo(top - first, bottom - first);
                expose(0, top - first, _width, bottom - first - (top - first));
+#ifndef USE_PAINTER
        }
+#endif
 }
 
 
-       
+#ifndef USE_PAINTER
 void LyXScreen::drawTableLine(int baseline, int x, int length, bool on_off)
 {
        GC gc;
@@ -765,8 +955,10 @@ void LyXScreen::drawTableLine(int baseline, int x, int length, bool on_off)
                 x + length,
                 baseline);
 }
+#endif
 
-       
+
+#ifndef USE_PAINTER
 void LyXScreen::drawVerticalTableLine(int x, int y1, int y2, bool on_off)
 {
        GC gc;
@@ -780,8 +972,10 @@ void LyXScreen::drawVerticalTableLine(int x, int y1, int y2, bool on_off)
                 x,
                 y2);
 }
+#endif
 
 
+#ifndef USE_PAINTER
 void LyXScreen::drawFrame(int /*ft*/, int x, int y, int w, int h,
                          FL_COLOR /*col*/, int /*b*/)
 {
@@ -836,3 +1030,4 @@ void LyXScreen::drawFrame(int /*ft*/, int x, int y, int w, int h,
                     fl_gc, pr, 4,
                     Convex, CoordModeOrigin); 
 }
+#endif
index e6c18259c395dd5d4d70e4158ce08ab985f454cf..6f9d5cb112b84f57e8efea62b7513866ae80eb04 100644 (file)
@@ -31,6 +31,7 @@
 #include "lyxrc.h"
 #include "LyXView.h"
 #include "lyxrow.h"
+#include "Painter.h"
 
 using std::max;
 using std::min;
@@ -44,7 +45,11 @@ extern BufferView * current_view;
 extern LyXRC * lyxrc;
 
 // ale070405
+#ifdef USE_PAINTER
+extern int bibitemMaxWidth(Painter &, LyXFont const &);
+#else
 extern int bibitemMaxWidth(LyXFont const &);
+#endif
 
 #define FIX_DOUBLE_SPACE 1
 
@@ -56,6 +61,68 @@ int LyXText::SingleWidth(LyXParagraph * par,
 }
 
 
+#ifdef USE_PAINTER
+int LyXText::SingleWidth(LyXParagraph * par,
+                        LyXParagraph::size_type pos, char c) const
+{
+       LyXFont font = GetFont(par, pos);
+
+       // The most common case is handled first (Asger)
+       if (IsPrintable(c)) {
+               return font.width(c);
+
+       } else if (IsHfillChar(c)) {
+               return 3;       /* Because of the representation
+                                * as vertical lines */
+       } else if (c == LyXParagraph::META_FOOTNOTE ||
+                  c == LyXParagraph::META_MARGIN ||
+                  c == LyXParagraph::META_FIG ||
+                  c == LyXParagraph::META_TAB ||
+                  c == LyXParagraph::META_WIDE_FIG ||
+                  c == LyXParagraph::META_WIDE_TAB ||
+                  c == LyXParagraph::META_ALGORITHM) {
+               string fs;
+               switch (c) {
+               case LyXParagraph::META_MARGIN:
+                       fs = "margin";
+                       break;
+               case LyXParagraph::META_FIG:
+                       fs = "fig";
+                       break;
+               case LyXParagraph::META_TAB:
+                       fs = "tab";
+                       break;
+               case LyXParagraph::META_ALGORITHM:
+                       fs = "alg";
+                       break;
+               case LyXParagraph::META_WIDE_FIG:
+                       fs = "wide-fig";
+                       break;
+               case LyXParagraph::META_WIDE_TAB:
+                       fs = "wide-tab";
+                       break;
+               case LyXParagraph::META_FOOTNOTE:
+                       fs = "foot";
+                       break;
+               }
+               font.decSize();
+               font.decSize();
+               return font.stringWidth(fs);
+       } else if (c == LyXParagraph::META_INSET) {
+               Inset * tmpinset= par->GetInset(pos);
+               if (tmpinset)
+                       return par->GetInset(pos)->width(owner_->painter(),
+                                                        font);
+               else
+                       return 0;
+
+       } else if (IsSeparatorChar(c))
+               c = ' ';
+       else if (IsNewlineChar(c))
+               c = 'n';
+       return font.width(c);
+}
+#else
 int LyXText::SingleWidth(LyXParagraph * par,
                         LyXParagraph::size_type pos, char c) const
 {
@@ -119,6 +186,7 @@ int LyXText::SingleWidth(LyXParagraph * par,
                c = 'n';
        return font.width(c);
 }
+#endif
 
 
 // Returns the paragraph position of the last character in the specified row
@@ -292,6 +360,226 @@ void LyXText::ComputeBidiTablesFromTo(Row * row,
 }
 
 
+#ifdef USE_PAINTER
+void LyXText::draw(Row const * row,
+                  LyXParagraph::size_type & vpos,
+                  int offset, float & x)
+{
+       Painter & pain = owner_->painter();
+       
+       LyXParagraph::size_type pos = vis2log(vpos);
+       char c = row->par->GetChar(pos);
+
+       if (IsNewlineChar(c)) {
+               ++vpos;
+               // Draw end-of-line marker
+               LyXFont font = GetFont(row->par, pos);
+               int wid = font.width('n');
+               int asc = font.maxAscent();
+               int y = offset + row->baseline;
+#ifdef USE_PAINTER
+               int xp[3], yp[3];
+               
+               if (row->par->getLetterDirection(pos) == LYX_DIR_LEFT_TO_RIGHT) {
+                       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);
+               }
+#else
+               XPoint p[3];
+               
+               if (row->par->getLetterDirection(pos) == LYX_DIR_LEFT_TO_RIGHT) {
+                       p[0].x = int(x + wid*0.375); p[0].y = int(y - 0.875*asc*0.75);
+                       p[1].x = int(x);             p[1].y = int(y - 0.500*asc*0.75);
+                       p[2].x = int(x + wid*0.375); p[2].y = int(y - 0.125*asc*0.75);
+                       scr.drawLines(::getGC(gc_new_line), p, 3);
+               
+                       p[0].x = int(x);             p[0].y = int(y - 0.500*asc*0.75);
+                       p[1].x = int(x + wid);       p[1].y = int(y - 0.500*asc*0.75);
+                       p[2].x = int(x + wid);       p[2].y = int(y - asc*0.75);
+                       scr.drawLines(::getGC(gc_new_line), p, 3);
+               } else {
+                       p[0].x = int(x + wid*0.625); p[0].y = int(y - 0.875*asc*0.75);
+                       p[1].x = int(x + wid);       p[1].y = int(y - 0.500*asc*0.75);
+                       p[2].x = int(x + wid*0.625); p[2].y = int(y - 0.125*asc*0.75);
+                       scr.drawLines(::getGC(gc_new_line), p, 3);
+               
+                       p[0].x = int(x + wid);       p[0].y = int(y - 0.500*asc*0.75);
+                       p[1].x = int(x);             p[1].y = int(y - 0.500*asc*0.75);
+                       p[2].x = int(x);             p[2].y = int(y - asc*0.75);
+                       scr.drawLines(::getGC(gc_new_line), p, 3);
+               }
+#endif
+               x += wid;
+               return;
+       }
+
+       LyXFont font = GetFont(row->par, pos);
+       LyXFont font2 = font;
+
+       if (c == LyXParagraph::META_FOOTNOTE
+           || c == LyXParagraph::META_MARGIN
+           || c == LyXParagraph::META_FIG
+           || c == LyXParagraph::META_TAB
+           || c == LyXParagraph::META_WIDE_FIG
+           || c == LyXParagraph::META_WIDE_TAB
+           || c == LyXParagraph::META_ALGORITHM) {
+               string fs;
+               switch (c) {
+               case LyXParagraph::META_MARGIN:
+                       fs = "margin";
+                       // Draw a sign at the left margin!
+                       owner_->painter()
+                               .text((LYX_PAPER_MARGIN - font.width('!'))/2,
+                                     offset + row->baseline, "!", 1, font);
+                       break;
+               case LyXParagraph::META_FIG:
+                       fs = "fig";
+                       break;
+               case LyXParagraph::META_TAB:
+                       fs = "tab";
+                       break;
+               case LyXParagraph::META_ALGORITHM:
+                       fs = "alg";
+                       break;
+               case LyXParagraph::META_WIDE_FIG:
+                       fs = "wide-fig";
+                       break;
+               case LyXParagraph::META_WIDE_TAB:
+                       fs = "wide-tab";
+                       break;
+               case LyXParagraph::META_FOOTNOTE:
+                       fs = "foot";
+                       break;
+               }
+               font.decSize();
+               font.decSize();
+         
+               // calculate the position of the footnotemark
+               int y = (row->baseline - font2.maxAscent() 
+                        + font.maxAscent());
+         
+               font.setColor(LColor::footnote);
+
+               float tmpx = x;
+
+               // draw it and set new x position
+               
+               pain.text(int(x), offset + y, fs, font);
+               x += pain.width(fs, font);
+               pain.line(int(tmpx), offset + row->baseline,
+                         int(x), offset + row->baseline,
+                         LColor::footnote);
+
+         
+               ++vpos;
+               return;
+       } else if (c == LyXParagraph::META_INSET) {
+               Inset * tmpinset = row->par->GetInset(pos);
+               if (tmpinset) 
+                       tmpinset->draw(owner_->painter(), font,
+                                      offset + row->baseline, x);
+               ++vpos;
+               return;
+       }
+
+       /* usual characters, no insets */
+
+       // 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;
+
+       LyXParagraph::size_type last = RowLast(row);
+       
+       while (vpos <= last &&
+              (pos = vis2log(vpos)) >= 0
+              && static_cast<unsigned char>(c = row->par->GetChar(pos)) > ' '
+              && font2 == GetFont(row->par, pos)) {
+               textstring += c;
+               ++vpos;
+       }
+       float tmpx = x;
+
+#if 0
+       // If monochrome and LaTeX mode, provide reverse background
+       if (mono_video &&
+           font.latex() == LyXFont::ON) {
+               int a = font.maxAscent();
+               int d = font.maxDescent();
+               scr.fillRectangle(gc_copy, int(tmpx),
+                                 offset + row->baseline - a,
+                                 font.textWidth(textstring.c_str(),
+                                                textstring.length()), a + d);
+       }
+#endif
+
+       // Draw text and set the new x position
+       pain.text(int(x), offset + row->baseline, textstring, font);
+       x += pain.width(textstring, font);
+       
+       // what about underbars?
+       if (font.underbar() == LyXFont::ON && font.latex() != LyXFont::ON) {
+               pain.line(tmpx, offset + row->baseline + 2,
+                         x, offset + row->baseline + 2);
+               
+       }
+
+       // If we want ulem.sty support, drawing
+       // routines should go here. (Asger)
+       // Why shouldn't LyXFont::drawText handle it internally?
+}
+#else
 void LyXText::Draw(Row const * row, LyXParagraph::size_type & vpos,
                   LyXScreen & scr, int offset, float & x)
 {
@@ -375,8 +663,12 @@ void LyXText::Draw(Row const * row, LyXParagraph::size_type & vpos,
                // calculate the position of the footnotemark
                int y = (row->baseline - font2.maxAscent() 
                         + font.maxAscent());
-         
-               font.setColor(LyXFont::INSET);
+
+#ifdef USE_PAINTER
+               font.setColor(LColor::footnote);
+#else
+               font.setColor(LyXFont::RED);
+#endif
 
                float tmpx = x;
 
@@ -450,6 +742,7 @@ void LyXText::Draw(Row const * row, LyXParagraph::size_type & vpos,
        // routines should go here. (Asger)
        // Why shouldn't LyXFont::drawText handle it internally?
 }
+#endif
 
 
 // Returns the left beginning of the text. 
@@ -655,10 +948,18 @@ int LyXText::LeftMargin(Row const * row) const
                else 
                        if (layout.labeltype == LABEL_BIBLIO) {
                                // ale970405 Right width for bibitems
+#ifdef USE_PAINTER
+                               x += bibitemMaxWidth(owner_->painter(),
+                                                    textclasslist
+                                                    .TextClass(parameters
+                                                               ->textclass)
+                                                    .defaultfont());
+#else
                                x += bibitemMaxWidth(textclasslist
                                                     .TextClass(parameters
                                                                ->textclass)
                                                     .defaultfont());
+#endif
                        }
        }
        
@@ -1144,10 +1445,11 @@ bool LyXText::HfillExpansion(Row const * row_ptr,
 }
 
 
+#ifdef USE_PAINTER
 void LyXText::SetHeightOfRow(Row * row_ptr) const
 {
     /* get the maximum ascent and the maximum descent */
-   int asc, maxasc, desc, maxdesc, pos_end, pos, labeladdon;
+   int asc, desc, pos;
    float layoutasc = 0;
    float layoutdesc = 0;
    float tmptop = 0;
@@ -1170,7 +1472,8 @@ void LyXText::SetHeightOfRow(Row * row_ptr) const
    LyXParagraph * par = row_ptr->par->LastPhysicalPar();
    LyXParagraph * firstpar = row_ptr->par->FirstPhysicalPar();
    
-   LyXLayout const & layout = textclasslist.Style(parameters->textclass, firstpar->GetLayout());
+   LyXLayout const & layout = textclasslist.Style(parameters->textclass,
+                                                 firstpar->GetLayout());
    
    LyXFont font = GetFont(par, par->Last()-1);
    LyXFont::FONT_SIZE size = font.size();
@@ -1179,16 +1482,16 @@ void LyXText::SetHeightOfRow(Row * row_ptr) const
 
    LyXFont labelfont = GetFont(par, -2);
 
-   maxasc = int(font.maxAscent() *
+   int maxasc = int(font.maxAscent() *
                   layout.spacing.getValue() *
                   parameters->spacing.getValue());
-   maxdesc = int(font.maxDescent() *
+   int maxdesc = int(font.maxDescent() *
                    layout.spacing.getValue() *
                    parameters->spacing.getValue());
 
-   pos_end = RowLast(row_ptr);
+   int pos_end = RowLast(row_ptr);
    
-   labeladdon = 0;
+   int labeladdon = 0;
 
    // Check if any insets are larger
    for (pos = row_ptr->pos; pos <= pos_end; ++pos) {
@@ -1196,8 +1499,8 @@ void LyXText::SetHeightOfRow(Row * row_ptr) const
         tmpfont = GetFont(row_ptr->par, pos);
          tmpinset = row_ptr->par->GetInset(pos);
          if (tmpinset) {
-            asc = tmpinset->Ascent(tmpfont);
-            desc = tmpinset->Descent(tmpfont);
+            asc = tmpinset->ascent(owner_->painter(), tmpfont);
+            desc = tmpinset->descent(owner_->painter(), tmpfont);
            if (asc > maxasc) 
              maxasc = asc;
            if (desc > maxdesc)
@@ -1304,7 +1607,7 @@ void LyXText::SetHeightOfRow(Row * row_ptr) const
        * or between the items of a itemize or enumerate environment */ 
       
       if (!firstpar->pagebreak_top) {
-        LyXParagraph *prev = row_ptr->par->Previous();
+        LyXParagraph * prev = row_ptr->par->Previous();
         if (prev)
            prev = row_ptr->par->DepthHook(row_ptr->par->GetDepth());
         if (prev && prev->GetLayout() == firstpar->GetLayout()
@@ -1371,8 +1674,8 @@ void LyXText::SetHeightOfRow(Row * row_ptr) const
          /* and now the layout spaces, for example before and after a section, 
           * or between the items of a itemize or enumerate environment */
          if (!firstpar->pagebreak_bottom && row_ptr->par->Next()) {
-            LyXParagraph *nextpar = row_ptr->par->Next();
-            LyXParagraph *comparepar = row_ptr->par;
+            LyXParagraph * nextpar = row_ptr->par->Next();
+            LyXParagraph * comparepar = row_ptr->par;
             float usual = 0;
             float  unusual = 0;
             
@@ -1413,274 +1716,550 @@ void LyXText::SetHeightOfRow(Row * row_ptr) const
    /* calculate the new height of the text */ 
    height -= row_ptr->height;
    
-   row_ptr->height= maxasc+maxdesc+labeladdon;
-   row_ptr->baseline= maxasc+labeladdon;
+   row_ptr->height = maxasc + maxdesc + labeladdon;
+   row_ptr->baseline = maxasc + labeladdon;
    
    height += row_ptr->height;
 }
-
-
-/* Appends the implicit specified paragraph behind the specified row,
- * start at the implicit given position */
-void LyXText::AppendParagraph(Row * row) const
+#else
+void LyXText::SetHeightOfRow(Row * row_ptr) const
 {
-   bool not_ready = true;
-   
-   // The last character position of a paragraph is an invariant so we can 
-   // safely get it here. (Asger)
-   int lastposition = row->par->Last();
+    /* get the maximum ascent and the maximum descent */
+   int asc, maxasc, desc, maxdesc, pos_end, pos, labeladdon;
+   float layoutasc = 0;
+   float layoutdesc = 0;
+   float tmptop = 0;
+   LyXFont tmpfont;
+   Inset * tmpinset;
 
-   do {
-      // Get the next breakpoint
-      int z = NextBreakPoint(row, paperwidth);
-      
-      Row * tmprow = row;
+   /* this must not happen before the currentrow for clear reasons.
+      so the trick is just to set the current row onto this row */
+   long unused_y;
+   GetRow(row_ptr->par, row_ptr->pos, unused_y);
 
-      // Insert the new row
-      if (z < lastposition) {
-        ++z;
-        InsertRow(row, row->par, z);
-        row = row->next;
+   /* ok , let us initialize the maxasc and maxdesc value. 
+    * This depends in LaTeX of the font of the last character
+    * in the paragraph. The hack below is necessary because
+    * of the possibility of open footnotes */
 
-        row->height = 0;
-      } else
-        not_ready = false;
-      
-      // Set the dimensions of the row
-      tmprow->fill = Fill(tmprow, paperwidth);
-      SetHeightOfRow(tmprow);
+   /* Correction: only the fontsize count. The other properties
+      are taken from the layoutfont. Nicer on the screen :) */
+   
+   LyXParagraph * par = row_ptr->par->LastPhysicalPar();
+   LyXParagraph * firstpar = row_ptr->par->FirstPhysicalPar();
+   
+   LyXLayout const & layout = textclasslist.Style(parameters->textclass, firstpar->GetLayout());
+   
+   LyXFont font = GetFont(par, par->Last()-1);
+   LyXFont::FONT_SIZE size = font.size();
+   font = GetFont(par, -1);
+   font.setSize(size);
 
-   } while (not_ready);
-}
+   LyXFont labelfont = GetFont(par, -2);
 
+   maxasc = int(font.maxAscent() *
+                  layout.spacing.getValue() *
+                  parameters->spacing.getValue());
+   maxdesc = int(font.maxDescent() *
+                   layout.spacing.getValue() *
+                   parameters->spacing.getValue());
 
-void LyXText::BreakAgain(Row * row) const
-{
-   bool not_ready = true;
+   pos_end = RowLast(row_ptr);
    
-   do  {
-      /* get the next breakpoint */
-       LyXParagraph::size_type z = 
-               NextBreakPoint(row, paperwidth);
-      Row * tmprow = row;
-      
-      if (z < row->par->Last() ) {
-        if (!row->next || (row->next && row->next->par != row->par)) {
-                // insert a new row
-           ++z;
-           InsertRow(row, row->par, z);
-           row = row->next;
-           row->height = 0;
-        } else  {
-           row = row->next;
-           ++z;
-           if (row->pos == z)
-                   not_ready = false;     // the rest will not change
-           else {
-              row->pos = z;
-           }
-        }
-      } else {
-        /* if there are some rows too much, delete them */
-        /* only if you broke the whole paragraph! */ 
-        Row * tmprow2 = row;
-        while (tmprow2->next && tmprow2->next->par == row->par) {
-           tmprow2 = tmprow2->next;
-        }
-        while (tmprow2 != row) {
-           tmprow2 = tmprow2->previous;
-           RemoveRow(tmprow2->next);
-        }
-        not_ready = false;
-      }
-       
-      /* set the dimensions of the row */ 
-      tmprow->fill = Fill(tmprow, paperwidth);
-      SetHeightOfRow(tmprow);
-   } while (not_ready);
-}
-
+   labeladdon = 0;
 
-/* this is just a little changed version of break again */ 
-void LyXText::BreakAgainOneRow(Row * row)
-{
-   /* get the next breakpoint */
-   LyXParagraph::size_type z = NextBreakPoint(row, paperwidth);
-   Row * tmprow = row;
-   
-   if (z < row->par->Last() ) {
-      if (!row->next || (row->next && row->next->par != row->par)) {
-        /* insert a new row */ 
-        ++z;
-        InsertRow(row, row->par, z);
-        row = row->next;
-        row->height = 0;
-      }
-      else  {
-        row= row->next;
-        ++z;
-        if (row->pos != z)
-           row->pos = z;
-      }
-   }
-   else {
-      /* if there are some rows too much, delete them */
-      /* only if you broke the whole paragraph! */ 
-      Row * tmprow2 = row;
-      while (tmprow2->next && tmprow2->next->par == row->par) {
-        tmprow2 = tmprow2->next;
-      }
-      while (tmprow2 != row) {
-        tmprow2 = tmprow2->previous;
-        RemoveRow(tmprow2->next);
+   // Check if any insets are larger
+   for (pos = row_ptr->pos; pos <= pos_end; ++pos) {
+      if (row_ptr->par->GetChar(pos) == LyXParagraph::META_INSET) {
+        tmpfont = GetFont(row_ptr->par, pos);
+         tmpinset = row_ptr->par->GetInset(pos);
+         if (tmpinset) {
+            asc = tmpinset->Ascent(tmpfont);
+            desc = tmpinset->Descent(tmpfont);
+           if (asc > maxasc) 
+             maxasc = asc;
+           if (desc > maxdesc)
+             maxdesc = desc;
+        }
       }
    }
-   
-   /* set the dimensions of the row */ 
-   tmprow->fill = Fill(tmprow, paperwidth);
-   SetHeightOfRow(tmprow);
-}
 
+   // Check if any custom fonts are larger (Asger)
+   // This is not completely correct, but we can live with the small,
+   // cosmetic error for now.
+   LyXFont::FONT_SIZE maxsize = row_ptr->par->HighestFontInRange(row_ptr->pos,
+                                                                pos_end);
+   if (maxsize > font.size()) {
+       font.setSize(maxsize);
 
-void LyXText::BreakParagraph(char keep_layout)
-{
-   LyXLayout const & layout = textclasslist.Style(parameters->textclass,
-                                     cursor.par->GetLayout());
-   
-   /* table stuff -- begin */
-   if (cursor.par->table) {
-       // breaking of tables is only allowed at the beginning or the end */
-       if (cursor.pos && cursor.pos < cursor.par->size() &&
-           !cursor.par->table->ShouldBeVeryLastCell(NumberOfCell(cursor.par, cursor.pos)))
-              return; // no breaking of tables allowed
+       asc = font.maxAscent();
+       desc = font.maxDescent();
+       if (asc > maxasc) 
+               maxasc = asc;
+       if (desc > maxdesc)
+               maxdesc = desc;
    }
-   /* table stuff -- end */
-
-   // this is only allowed, if the current paragraph is not empty or caption
-   if ((cursor.par->Last() <= 0 && !cursor.par->IsDummy())
-       && 
-       layout.labeltype!= LABEL_SENSITIVE)
-     return;
-
-   SetUndo(Undo::INSERT, 
-          cursor.par->ParFromPos(cursor.pos)->previous, 
-          cursor.par->ParFromPos(cursor.pos)->next); 
 
-   /* table stuff -- begin */
-   if (cursor.par->table) {
-       int cell = NumberOfCell(cursor.par, cursor.pos);
-       if (cursor.par->table->ShouldBeVeryLastCell(cell))
-           SetCursor(cursor.par, cursor.par->text.size());
+   /* table stuff -- begin*/
+   if (row_ptr->par->table){
+     // stretch the rows a bit
+      maxasc += 1;
+      maxdesc += 1;
    }
-   /* table stuff -- end */
-   
-   // please break always behind a space
-   if (cursor.pos < cursor.par->Last()
-       && cursor.par->IsLineSeparator(cursor.pos))
-     cursor.pos++;
-   
-   // break the paragraph
-   if (keep_layout)
-     keep_layout = 2;
-   else        
-     keep_layout = layout.isEnvironment();
-   cursor.par->BreakParagraph(cursor.pos, keep_layout);
+   /* table stuff -- end*/
 
-   /* table stuff -- begin */
-   if (cursor.par->table){
-     // the table should stay with the contents
-     if (!cursor.pos){
-       cursor.par->Next()->table = cursor.par->table;
-       cursor.par->table = 0;
-     }
-   }
-   /* table stuff -- end */
+   // This is nicer with box insets:
+   ++maxasc;
+   ++maxdesc;
 
-   // well this is the caption hack since one caption is really enough
-   if (layout.labeltype == LABEL_SENSITIVE){
-     if (!cursor.pos)
-            cursor.par->SetLayout(0); // set to standard-layout
-     else
-            cursor.par->Next()->SetLayout(0); // set to standard-layout
-   }
-   
-   /* if the cursor is at the beginning of a row without prior newline, 
-    * move one row up! 
-    * This touches only the screen-update. Otherwise we would may have
-    * an empty row on the screen */
-   if (cursor.pos && !cursor.row->par->IsNewline(cursor.row->pos -1) &&
-       cursor.row->pos == cursor.pos) {
-     CursorLeft();
-   } 
-   
-   status = LyXText::NEED_MORE_REFRESH;
-   refresh_row = cursor.row;
-   refresh_y = cursor.y - cursor.row->baseline;
+   row_ptr->ascent_of_text = maxasc;
    
-   // Do not forget the special right address boxes
-   if (layout.margintype == MARGIN_RIGHT_ADDRESS_BOX) {
-      while (refresh_row->previous &&
-            refresh_row->previous->par == refresh_row->par) {
-               refresh_row = refresh_row->previous;
-               refresh_y -= refresh_row->height;
-            }
+   /* is it a top line? */ 
+   if (row_ptr->pos == 0
+       && row_ptr->par == firstpar) {
+      
+      /* some parksips VERY EASY IMPLEMENTATION */ 
+      if (parameters->paragraph_separation == BufferParams::PARSEP_SKIP) {
+        if (layout.isParagraph()
+            && firstpar->GetDepth() == 0
+            && firstpar->Previous())
+           maxasc += parameters->getDefSkip().inPixels();
+        else if (firstpar->Previous()
+                 && textclasslist.Style(parameters->textclass,
+                          firstpar->Previous()->GetLayout()).isParagraph()
+                 && firstpar->Previous()->GetDepth() == 0)
+          // is it right to use defskip here too? (AS)
+          maxasc += parameters->getDefSkip().inPixels();
+      }
+      
+      /* the paper margins */ 
+      if (!row_ptr->par->previous)
+        maxasc += LYX_PAPER_MARGIN;
+      
+      /* add the vertical spaces, that the user added */
+      if (firstpar->added_space_top.kind() != VSpace::NONE)
+        maxasc += int(firstpar->added_space_top.inPixels());
+      
+      /* do not forget the DTP-lines! 
+       * there height depends on the font of the nearest character */
+      if (firstpar->line_top)
+        maxasc += 2 * GetFont(firstpar, 0).ascent('x');
+      
+      /* and now the pagebreaks */ 
+      if (firstpar->pagebreak_top)
+        maxasc += 3 * DefaultHeight();
+      
+      /*  this is special code for the chapter, since the label of this
+       * layout is printed in an extra row */ 
+      if (layout.labeltype == LABEL_COUNTER_CHAPTER
+         && parameters->secnumdepth>= 0) {
+             labeladdon = int(labelfont.maxDescent() *
+                                 layout.spacing.getValue() *
+                                 parameters->spacing.getValue())
+                     + int(labelfont.maxAscent() *
+                              layout.spacing.getValue() *
+                              parameters->spacing.getValue());
+      }
+      
+      /* special code for the top label */ 
+      if ((layout.labeltype == LABEL_TOP_ENVIRONMENT
+          || layout.labeltype == LABEL_BIBLIO
+          || layout.labeltype == LABEL_CENTERED_TOP_ENVIRONMENT)
+         && row_ptr->par->IsFirstInSequence()
+         && !row_ptr->par->GetLabestring().empty()) {
+        labeladdon = int(
+                (labelfont.maxAscent() *
+                 layout.spacing.getValue() *
+                 parameters->spacing.getValue())
+                +(labelfont.maxDescent() *
+                  layout.spacing.getValue() *
+                  parameters->spacing.getValue())
+                + layout.topsep * DefaultHeight()
+                + layout.labelbottomsep *  DefaultHeight());
+      }
+   
+      /* and now the layout spaces, for example before and after a section, 
+       * or between the items of a itemize or enumerate environment */ 
+      
+      if (!firstpar->pagebreak_top) {
+        LyXParagraph *prev = row_ptr->par->Previous();
+        if (prev)
+           prev = row_ptr->par->DepthHook(row_ptr->par->GetDepth());
+        if (prev && prev->GetLayout() == firstpar->GetLayout()
+            && prev->GetDepth() == firstpar->GetDepth()
+            && prev->GetLabelWidthString() == firstpar->GetLabelWidthString())
+          {
+             layoutasc = (layout.itemsep * DefaultHeight());
+          }
+        else if (row_ptr->previous) {
+           tmptop = layout.topsep;
+           
+           if (row_ptr->previous->par->GetDepth() >= row_ptr->par->GetDepth())
+              tmptop-= textclasslist.Style(parameters->textclass, row_ptr->previous->par->GetLayout()).bottomsep;
+           
+           if (tmptop > 0)
+              layoutasc = (tmptop * DefaultHeight());
+        }
+        else if (row_ptr->par->line_top){
+           tmptop = layout.topsep;
+           
+           if (tmptop > 0)
+              layoutasc = (tmptop * DefaultHeight());
+        }
+        
+        prev = row_ptr->par->DepthHook(row_ptr->par->GetDepth()-1);
+        if (prev)  {
+           maxasc += int(textclasslist.Style(parameters->textclass,
+                                        prev->GetLayout()).parsep * DefaultHeight());
+        }
+        else {
+               if (firstpar->Previous()
+                   && firstpar->Previous()->GetDepth() == 0
+                   && firstpar->Previous()->GetLayout() != firstpar->GetLayout()) {
+                  /* avoid parsep */ 
+               }
+           else if (firstpar->Previous()){
+              maxasc += int(layout.parsep * DefaultHeight());
+           }
+        }
+      }
    }
-   RemoveParagraph(cursor.row);
    
-   // set the dimensions of the cursor row
-   cursor.row->fill = Fill(cursor.row, paperwidth);
+   /* is it a bottom line? */ 
+   if (row_ptr->par->ParFromPos(RowLast(row_ptr) + 1) == par
+       && (!row_ptr->next || row_ptr->next->par != row_ptr->par)) {     
+         
+         /* the paper margins */ 
+         if (!par->next)
+           maxdesc += LYX_PAPER_MARGIN;
+       
+         /* add the vertical spaces, that the user added */
+         if (firstpar->added_space_bottom.kind() != VSpace::NONE)
+           maxdesc += int(firstpar->added_space_bottom.inPixels());
+         
+         /* do not forget the DTP-lines! 
+          * there height depends on the font of the nearest character */
+         if (firstpar->line_bottom)
+           maxdesc += 2 * (GetFont(par, par->Last()-1).ascent('x'));
+         
+         /* and now the pagebreaks */
+         if (firstpar->pagebreak_bottom)
+           maxdesc += 3 * DefaultHeight();
+         
+         /* and now the layout spaces, for example before and after a section, 
+          * or between the items of a itemize or enumerate environment */
+         if (!firstpar->pagebreak_bottom && row_ptr->par->Next()) {
+            LyXParagraph *nextpar = row_ptr->par->Next();
+            LyXParagraph *comparepar = row_ptr->par;
+            float usual = 0;
+            float  unusual = 0;
+            
+            if (comparepar->GetDepth() > nextpar->GetDepth()) {
+               usual = (textclasslist.Style(parameters->textclass, comparepar->GetLayout()).bottomsep * DefaultHeight());
+               comparepar = comparepar->DepthHook(nextpar->GetDepth());
+               if (comparepar->GetLayout()!= nextpar->GetLayout()
+                   || nextpar->GetLabelWidthString() != 
+                       comparepar->GetLabelWidthString())
+                 unusual = (textclasslist.Style(parameters->textclass, comparepar->GetLayout()).bottomsep * DefaultHeight());
+               
+               if (unusual > usual)
+                 layoutdesc = unusual;
+               else
+                 layoutdesc = usual;
+            }
+            else if (comparepar->GetDepth() ==  nextpar->GetDepth()) {
+               
+               if (comparepar->GetLayout()!= nextpar->GetLayout()
+                   || nextpar->GetLabelWidthString() != 
+                       comparepar->GetLabelWidthString())
+                 layoutdesc = int(textclasslist.Style(parameters->textclass, comparepar->GetLayout()).bottomsep * DefaultHeight());
+            }
+         }
+       }
+   
+   /* incalculate the layout spaces */ 
+   maxasc += int(layoutasc * 2 / (2 + firstpar->GetDepth()));
+   maxdesc += int(layoutdesc * 2 / (2 + firstpar->GetDepth()));
 
-   SetHeightOfRow(cursor.row);
+   /* table stuff -- begin*/
+   if (row_ptr->par->table){
+      maxasc += row_ptr->par->table->
+       AdditionalHeight(NumberOfCell(row_ptr->par, row_ptr->pos));
+   }
+   /* table stuff -- end*/
    
-   while (!cursor.par->Next()->table && cursor.par->Next()->Last()
-         && cursor.par->Next()->IsNewline(0))
-     cursor.par->Next()->Erase(0);
+   /* calculate the new height of the text */ 
+   height -= row_ptr->height;
    
-   InsertParagraph(cursor.par->Next(), cursor.row);
-
-   UpdateCounters(cursor.row->previous);
+   row_ptr->height= maxasc+maxdesc+labeladdon;
+   row_ptr->baseline= maxasc+labeladdon;
    
-   /* This check is necessary. Otherwise the new empty paragraph will
-    * be deleted automatically. And it is more friendly for the user! */ 
-   if (cursor.pos)
-     SetCursor(cursor.par->Next(), 0);
-   else
-     SetCursor(cursor.par, 0);
+   height += row_ptr->height;
+}
+#endif
+
+
+/* Appends the implicit specified paragraph behind the specified row,
+ * start at the implicit given position */
+void LyXText::AppendParagraph(Row * row) const
+{
+   bool not_ready = true;
    
-   if (cursor.row->next)
-     BreakAgain(cursor.row->next);
+   // The last character position of a paragraph is an invariant so we can 
+   // safely get it here. (Asger)
+   int lastposition = row->par->Last();
 
-   need_break_row = 0;
+   do {
+      // Get the next breakpoint
+      int z = NextBreakPoint(row, paperwidth);
+      
+      Row * tmprow = row;
+
+      // Insert the new row
+      if (z < lastposition) {
+        ++z;
+        InsertRow(row, row->par, z);
+        row = row->next;
+
+        row->height = 0;
+      } else
+        not_ready = false;
+      
+      // Set the dimensions of the row
+      tmprow->fill = Fill(tmprow, paperwidth);
+      SetHeightOfRow(tmprow);
+
+   } while (not_ready);
 }
 
 
-void LyXText::OpenFootnote()
+void LyXText::BreakAgain(Row * row) const
 {
-   LyXParagraph * endpar,* tmppar;
-   Row * row;
-   
-   LyXParagraph * par = cursor.par->ParFromPos(cursor.pos);
-   
-   /* if there is no footnote in this paragraph, just return. */ 
-   if (!par->next
-       || par->next->footnoteflag != LyXParagraph::CLOSED_FOOTNOTE)
-     return;
-   
-   /* ok, move the cursor right before the footnote */ 
-   
-   /* just a little faster than using CursorRight() */
-   for (cursor.pos = 0;
-       cursor.par->ParFromPos(cursor.pos) != par; cursor.pos++);
-   /* now the cursor is at the beginning of the physical par */
-   SetCursor(cursor.par,
-            cursor.pos + cursor.par->ParFromPos(cursor.pos)->text.size());
-   
-   /* the cursor must be exactly before the footnote */ 
-   par = cursor.par->ParFromPos(cursor.pos);
-   
-   status = LyXText::NEED_MORE_REFRESH;
-   refresh_row = cursor.row;
-   refresh_y = cursor.y - cursor.row->baseline;
+   bool not_ready = true;
+   
+   do  {
+      /* get the next breakpoint */
+       LyXParagraph::size_type z = 
+               NextBreakPoint(row, paperwidth);
+      Row * tmprow = row;
+      
+      if (z < row->par->Last() ) {
+        if (!row->next || (row->next && row->next->par != row->par)) {
+                // insert a new row
+           ++z;
+           InsertRow(row, row->par, z);
+           row = row->next;
+           row->height = 0;
+        } else  {
+           row = row->next;
+           ++z;
+           if (row->pos == z)
+                   not_ready = false;     // the rest will not change
+           else {
+              row->pos = z;
+           }
+        }
+      } else {
+        /* if there are some rows too much, delete them */
+        /* only if you broke the whole paragraph! */ 
+        Row * tmprow2 = row;
+        while (tmprow2->next && tmprow2->next->par == row->par) {
+           tmprow2 = tmprow2->next;
+        }
+        while (tmprow2 != row) {
+           tmprow2 = tmprow2->previous;
+           RemoveRow(tmprow2->next);
+        }
+        not_ready = false;
+      }
+       
+      /* set the dimensions of the row */ 
+      tmprow->fill = Fill(tmprow, paperwidth);
+      SetHeightOfRow(tmprow);
+   } while (not_ready);
+}
+
+
+/* this is just a little changed version of break again */ 
+void LyXText::BreakAgainOneRow(Row * row)
+{
+   /* get the next breakpoint */
+   LyXParagraph::size_type z = NextBreakPoint(row, paperwidth);
+   Row * tmprow = row;
+   
+   if (z < row->par->Last() ) {
+      if (!row->next || (row->next && row->next->par != row->par)) {
+        /* insert a new row */ 
+        ++z;
+        InsertRow(row, row->par, z);
+        row = row->next;
+        row->height = 0;
+      }
+      else  {
+        row= row->next;
+        ++z;
+        if (row->pos != z)
+           row->pos = z;
+      }
+   }
+   else {
+      /* if there are some rows too much, delete them */
+      /* only if you broke the whole paragraph! */ 
+      Row * tmprow2 = row;
+      while (tmprow2->next && tmprow2->next->par == row->par) {
+        tmprow2 = tmprow2->next;
+      }
+      while (tmprow2 != row) {
+        tmprow2 = tmprow2->previous;
+        RemoveRow(tmprow2->next);
+      }
+   }
+   
+   /* set the dimensions of the row */ 
+   tmprow->fill = Fill(tmprow, paperwidth);
+   SetHeightOfRow(tmprow);
+}
+
+
+void LyXText::BreakParagraph(char keep_layout)
+{
+   LyXLayout const & layout = textclasslist.Style(parameters->textclass,
+                                     cursor.par->GetLayout());
+   
+   /* table stuff -- begin */
+   if (cursor.par->table) {
+       // breaking of tables is only allowed at the beginning or the end */
+       if (cursor.pos && cursor.pos < cursor.par->size() &&
+           !cursor.par->table->ShouldBeVeryLastCell(NumberOfCell(cursor.par, cursor.pos)))
+              return; // no breaking of tables allowed
+   }
+   /* table stuff -- end */
+
+   // this is only allowed, if the current paragraph is not empty or caption
+   if ((cursor.par->Last() <= 0 && !cursor.par->IsDummy())
+       && 
+       layout.labeltype!= LABEL_SENSITIVE)
+     return;
+
+   SetUndo(Undo::INSERT, 
+          cursor.par->ParFromPos(cursor.pos)->previous, 
+          cursor.par->ParFromPos(cursor.pos)->next); 
+
+   /* table stuff -- begin */
+   if (cursor.par->table) {
+       int cell = NumberOfCell(cursor.par, cursor.pos);
+       if (cursor.par->table->ShouldBeVeryLastCell(cell))
+           SetCursor(cursor.par, cursor.par->text.size());
+   }
+   /* table stuff -- end */
+   
+   // please break always behind a space
+   if (cursor.pos < cursor.par->Last()
+       && cursor.par->IsLineSeparator(cursor.pos))
+     cursor.pos++;
+   
+   // break the paragraph
+   if (keep_layout)
+     keep_layout = 2;
+   else        
+     keep_layout = layout.isEnvironment();
+   cursor.par->BreakParagraph(cursor.pos, keep_layout);
+
+   /* table stuff -- begin */
+   if (cursor.par->table){
+     // the table should stay with the contents
+     if (!cursor.pos){
+       cursor.par->Next()->table = cursor.par->table;
+       cursor.par->table = 0;
+     }
+   }
+   /* table stuff -- end */
+
+   // well this is the caption hack since one caption is really enough
+   if (layout.labeltype == LABEL_SENSITIVE){
+     if (!cursor.pos)
+            cursor.par->SetLayout(0); // set to standard-layout
+     else
+            cursor.par->Next()->SetLayout(0); // set to standard-layout
+   }
+   
+   /* if the cursor is at the beginning of a row without prior newline, 
+    * move one row up! 
+    * This touches only the screen-update. Otherwise we would may have
+    * an empty row on the screen */
+   if (cursor.pos && !cursor.row->par->IsNewline(cursor.row->pos -1) &&
+       cursor.row->pos == cursor.pos) {
+     CursorLeft();
+   } 
+   
+   status = LyXText::NEED_MORE_REFRESH;
+   refresh_row = cursor.row;
+   refresh_y = cursor.y - cursor.row->baseline;
+   
+   // Do not forget the special right address boxes
+   if (layout.margintype == MARGIN_RIGHT_ADDRESS_BOX) {
+      while (refresh_row->previous &&
+            refresh_row->previous->par == refresh_row->par) {
+               refresh_row = refresh_row->previous;
+               refresh_y -= refresh_row->height;
+            }
+   }
+   RemoveParagraph(cursor.row);
+   
+   // set the dimensions of the cursor row
+   cursor.row->fill = Fill(cursor.row, paperwidth);
+
+   SetHeightOfRow(cursor.row);
+   
+   while (!cursor.par->Next()->table && cursor.par->Next()->Last()
+         && cursor.par->Next()->IsNewline(0))
+     cursor.par->Next()->Erase(0);
+   
+   InsertParagraph(cursor.par->Next(), cursor.row);
+
+   UpdateCounters(cursor.row->previous);
+   
+   /* This check is necessary. Otherwise the new empty paragraph will
+    * be deleted automatically. And it is more friendly for the user! */ 
+   if (cursor.pos)
+     SetCursor(cursor.par->Next(), 0);
+   else
+     SetCursor(cursor.par, 0);
+   
+   if (cursor.row->next)
+     BreakAgain(cursor.row->next);
+
+   need_break_row = 0;
+}
+
+
+void LyXText::OpenFootnote()
+{
+   LyXParagraph * endpar,* tmppar;
+   Row * row;
+   
+   LyXParagraph * par = cursor.par->ParFromPos(cursor.pos);
+   
+   /* if there is no footnote in this paragraph, just return. */ 
+   if (!par->next
+       || par->next->footnoteflag != LyXParagraph::CLOSED_FOOTNOTE)
+     return;
+   
+   /* ok, move the cursor right before the footnote */ 
+   
+   /* just a little faster than using CursorRight() */
+   for (cursor.pos = 0;
+       cursor.par->ParFromPos(cursor.pos) != par; cursor.pos++);
+   /* now the cursor is at the beginning of the physical par */
+   SetCursor(cursor.par,
+            cursor.pos + cursor.par->ParFromPos(cursor.pos)->text.size());
+   
+   /* the cursor must be exactly before the footnote */ 
+   par = cursor.par->ParFromPos(cursor.pos);
+   
+   status = LyXText::NEED_MORE_REFRESH;
+   refresh_row = cursor.row;
+   refresh_y = cursor.y - cursor.row->baseline;
    
    tmppar = cursor.par;
    endpar = cursor.par->Next();
@@ -3101,405 +3680,1092 @@ void LyXText::DeleteLineForward()
 }
 
 
-// Change the case of a word at cursor position. The meaning of action
-// is:
-// 0  change to lowercase
-// 1  capitalize word
-// 2  change to uppercase
-// This function directly manipulates LyXParagraph::text because there
-// is no LyXParagraph::SetChar currently. I did what I could to ensure
-// that it is correct. I guess part of it should be moved to
-// LyXParagraph, but it will have to change for 1.1 anyway. At least
-// it does not access outside of the allocated array as the older
-// version did. (JMarc) 
-void LyXText::ChangeWordCase(LyXText::TextCase action) 
+// Change the case of a word at cursor position. The meaning of action
+// is:
+// 0  change to lowercase
+// 1  capitalize word
+// 2  change to uppercase
+// This function directly manipulates LyXParagraph::text because there
+// is no LyXParagraph::SetChar currently. I did what I could to ensure
+// that it is correct. I guess part of it should be moved to
+// LyXParagraph, but it will have to change for 1.1 anyway. At least
+// it does not access outside of the allocated array as the older
+// version did. (JMarc) 
+void LyXText::ChangeWordCase(LyXText::TextCase action) 
+{
+       LyXParagraph * tmppar = cursor.par->ParFromPos(cursor.pos);
+
+       SetUndo(Undo::FINISH, tmppar->previous, tmppar->next); 
+
+       LyXParagraph::size_type tmppos = 
+               cursor.par->PositionInParFromPos(cursor.pos);
+       while (tmppos < tmppar->size()) {
+               unsigned char c = tmppar->text[tmppos];
+               if (IsKommaChar(c) || IsLineSeparatorChar(c))
+                       break;
+               if (c != LyXParagraph::META_INSET) {
+                       switch (action) {
+                       case text_lowercase:
+                               c = tolower(c);
+                               break;
+                       case text_capitalization:
+                               c = toupper(c);
+                               action = text_lowercase;
+                               break;
+                       case text_uppercase:
+                               c = toupper(c);
+                               break;
+                       }
+               }
+               
+               tmppar->text[tmppos] = c;
+               ++tmppos;
+       }
+       CheckParagraph(tmppar, tmppos);
+       CursorRightOneWord();
+}
+
+
+void LyXText::Delete()
+{
+       // this is a very easy implementation
+
+       LyXCursor old_cursor = cursor;
+       int old_cur_par_id = old_cursor.par->id();
+       int old_cur_par_prev_id = old_cursor.par->previous ?
+               old_cursor.par->previous->id() : 0;
+       
+       // just move to the right
+       CursorRightIntern();
+
+       // This check is not very good...
+       // The CursorRightIntern calls DeleteEmptyParagrapgMechanism
+       // and that can very well delete the par or par->previous in
+       // old_cursor. Will a solution where we compare paragraph id's
+       //work better?
+#if 1
+       if ((cursor.par->previous ? cursor.par->previous->id() : 0)
+           == old_cur_par_prev_id
+           && cursor.par->id() != old_cur_par_id)
+               return; // delete-empty-paragraph-mechanism has done it
+#else
+       if (cursor.par->previous == old_cursor.par->previous
+           && cursor.par != old_cursor.par)
+               return; // delete-empty-paragraph-mechanism has done it
+#endif
+       // if you had success make a backspace
+       if (old_cursor.par != cursor.par || old_cursor.pos != cursor.pos) {
+               LyXCursor tmpcursor = cursor;
+               cursor = old_cursor; // to make sure undo gets the right cursor position
+               SetUndo(Undo::DELETE, 
+                       cursor.par->ParFromPos(cursor.pos)->previous, 
+                       cursor.par->ParFromPos(cursor.pos)->next); 
+               cursor = tmpcursor;
+               Backspace();
+       }
+}
+
+
+void  LyXText::Backspace()
+{
+       LyXParagraph * tmppar;
+       Row * tmprow, * row;
+       long y;
+       int tmpheight;
+
+       /* table stuff -- begin */
+       if (cursor.par->table) {
+               BackspaceInTable();
+               return;
+       }
+       /* table stuff -- end */
+       
+       LyXFont rawtmpfont = current_font;
+       LyXFont realtmpfont = real_current_font;
+   
+       // Get the font that is used to calculate the baselineskip
+       int const lastpos = cursor.par->Last();
+       LyXFont rawparfont = cursor.par->GetFontSettings(lastpos - 1);
+
+       if (cursor.pos == 0) {
+               // we may paste some paragraphs
+      
+               // is it an empty paragraph?
+      
+               if ((lastpos == 0
+                    || (lastpos == 1 && cursor.par->IsSeparator(0)))
+                   && !(cursor.par->Next() 
+                        && cursor.par->footnoteflag == 
+                        LyXParagraph::NO_FOOTNOTE
+                        && cursor.par->Next()->footnoteflag == 
+                        LyXParagraph::OPEN_FOOTNOTE)) {
+                       
+                       if (cursor.par->previous) {
+                               tmppar = cursor.par->previous->FirstPhysicalPar();
+                               if (cursor.par->GetLayout() == tmppar->GetLayout()
+                                   && cursor.par->footnoteflag == tmppar->footnoteflag
+                                   && cursor.par->GetAlign() == tmppar->GetAlign()) {
+                                       
+                                       tmppar->line_bottom = cursor.par->line_bottom;
+                                       tmppar->added_space_bottom = cursor.par->added_space_bottom;
+                                       tmppar->pagebreak_bottom = cursor.par->pagebreak_bottom;
+                               }
+                               
+                               CursorLeftIntern();
+                    
+                               // the layout things can change the height of a row !
+                               tmpheight = cursor.row->height;
+                               SetHeightOfRow(cursor.row);
+                               if (cursor.row->height != tmpheight) {
+                                       refresh_y = cursor.y - cursor.row->baseline;
+                                       refresh_row = cursor.row;
+                                       status = LyXText::NEED_MORE_REFRESH;
+                               }
+                               return;
+                       }
+               }
+               if (cursor.par->ParFromPos(cursor.pos)->previous){
+                       SetUndo(Undo::DELETE,
+                               cursor.par->ParFromPos(cursor.pos)->previous->previous,
+                               cursor.par->ParFromPos(cursor.pos)->next);
+               }
+               tmppar = cursor.par;
+               tmprow = cursor.row;
+               CursorLeftIntern();
+               /* Pasting is not allowed, if the paragraphs have different
+                  layout. I think it is a real bug of all other
+                  word processors to allow it. It confuses the user.
+                  Even so with a footnote paragraph and a non-footnote
+                  paragraph. I will not allow pasting in this case, 
+                  because the user would be confused if the footnote behaves 
+                  different wether it is open or closed.
+                 
+                  Correction: Pasting is always allowed with standard-layout
+               */
+               if (cursor.par != tmppar
+                   && (cursor.par->GetLayout() == tmppar->GetLayout()
+                       || !tmppar->GetLayout())
+                   && cursor.par->footnoteflag == tmppar->footnoteflag
+                   /* table stuff -- begin*/
+                   && !cursor.par->table /* no pasting of tables */ 
+                   /* table stuff -- end*/
+                   && cursor.par->GetAlign() == tmppar->GetAlign()) {
+                       
+                       cursor.par->PasteParagraph();
+                       
+                       if (!(cursor.pos &&
+                             cursor.par->IsSeparator(cursor.pos - 1)))
+                               cursor.par->InsertChar(cursor.pos, ' ');
+                       else
+                               if (cursor.pos)
+                                       cursor.pos--;
+                       
+                       status = LyXText::NEED_MORE_REFRESH;
+                       refresh_row = cursor.row;
+                       refresh_y = cursor.y - cursor.row->baseline;
+                       
+                       // remove the lost paragraph
+                       RemoveParagraph(tmprow);
+                       RemoveRow(tmprow);  
+                       
+                       AppendParagraph(cursor.row);
+                       UpdateCounters(cursor.row);
+                       
+                       // the row may have changed, block, hfills etc.
+                       SetCursor(cursor.par, cursor.pos);
+               }
+       } else {
+               /* this is the code for a normal backspace, not pasting
+                * any paragraphs */ 
+               SetUndo(Undo::DELETE, 
+                       cursor.par->ParFromPos(cursor.pos)->previous, 
+                       cursor.par->ParFromPos(cursor.pos)->next); 
+               CursorLeftIntern();
+               
+               // some insets are undeletable here
+               if (cursor.par->GetChar(cursor.pos) == LyXParagraph::META_INSET) {
+                       if (!cursor.par->GetInset(cursor.pos)->Deletable())
+                               return; 
+                       // force complete redo when erasing display insets
+                       // this is a cruel mathod but save..... Matthias 
+                       if (cursor.par->GetInset(cursor.pos)->display()){
+                               cursor.par->Erase(cursor.pos);
+                               RedoParagraph();
+                               return;
+                       }
+               }
+               
+               row = cursor.row;
+               y = cursor.y - row->baseline;
+               LyXParagraph::size_type z;
+               /* remember that a space at the end of a row doesnt count
+                * when calculating the fill */ 
+               if (cursor.pos < RowLast(row) ||
+                   !cursor.par->IsLineSeparator(cursor.pos)) {
+                       row->fill += SingleWidth(cursor.par, cursor.pos);
+               }
+               
+               /* some special code when deleting a newline. This is similar
+                * to the behavior when pasting paragraphs */ 
+               if (cursor.pos && cursor.par->IsNewline(cursor.pos)) {
+                       cursor.par->Erase(cursor.pos);
+                       // refresh the positions
+                       tmprow = row;
+                       while (tmprow->next && tmprow->next->par == row->par) {
+                               tmprow = tmprow->next;
+                               tmprow->pos--;
+                       }
+                       if (cursor.par->IsLineSeparator(cursor.pos - 1))
+                               cursor.pos--;
+                       
+                       if (cursor.pos < cursor.par->Last() && !cursor.par->IsSeparator(cursor.pos)) {
+                               cursor.par->InsertChar(cursor.pos, ' ');
+                               // refresh the positions
+                               tmprow = row;
+                               while (tmprow->next && tmprow->next->par == row->par) {
+                                       tmprow = tmprow->next;
+                                       tmprow->pos++;
+                               }
+                       }
+               } else {
+                       cursor.par->Erase(cursor.pos);
+                       
+                       // refresh the positions
+                       tmprow = row;
+                       while (tmprow->next && tmprow->next->par == row->par) {
+                               tmprow = tmprow->next;
+                               tmprow->pos--;
+                       }
+
+#ifndef FIX_DOUBLE_SPACE
+                       // delete superfluous blanks 
+                       if (cursor.pos < cursor.par->Last() - 1 &&
+                           (cursor.par->IsLineSeparator(cursor.pos))) {
+                               
+                               if (cursor.pos == BeginningOfMainBody(cursor.par)
+                                   || !cursor.pos 
+                                   || cursor.par->IsLineSeparator(cursor.pos - 1)) {
+                                       cursor.par->Erase(cursor.pos);
+                                       // refresh the positions
+                                       tmprow = row;
+                                       while (tmprow->next && 
+                                              tmprow->next->par == row->par) {
+                                               tmprow = tmprow->next;
+                                               tmprow->pos--;
+                                       }
+                                       if (cursor.pos)   // move one character left
+                                               cursor.pos--;
+                               }
+                       }
+#endif
+                       
+                       // delete newlines at the beginning of paragraphs
+                       while (cursor.par->Last() &&
+                              cursor.par->IsNewline(cursor.pos) &&
+                              cursor.pos == BeginningOfMainBody(cursor.par)) {
+                               cursor.par->Erase(cursor.pos);
+                               // refresh the positions
+                               tmprow = row;
+                               while (tmprow->next && 
+                                      tmprow->next->par == row->par) {
+                                       tmprow = tmprow->next;
+                                       tmprow->pos--;
+                               }
+                       }
+               }
+               
+               // is there a break one row above
+               if (row->previous && row->previous->par == row->par) {
+                       z = NextBreakPoint(row->previous, paperwidth);
+                       if ( z >= row->pos) {
+                               row->pos = z + 1;
+                               
+                               tmprow = row->previous;
+                               
+                               // maybe the current row is now empty
+                               if (row->pos >= row->par->Last()) {
+                                       // remove it
+                                       RemoveRow(row);
+                                       need_break_row = 0;
+                               } else {
+                                       BreakAgainOneRow(row);
+                                       if (row->next && row->next->par == row->par)
+                                               need_break_row = row->next;
+                                       else
+                                               need_break_row = 0;
+                               }
+                               
+                               // set the dimensions of the row above
+                               y -= tmprow->height;
+                               tmprow->fill = Fill(tmprow, paperwidth);
+                               SetHeightOfRow(tmprow);
+                               
+                               refresh_y = y;
+                               refresh_row = tmprow;
+                               status = LyXText::NEED_MORE_REFRESH;
+                               current_font = rawtmpfont;
+                               real_current_font = realtmpfont;
+                               SetCursor(cursor.par, cursor.pos, false);
+                               // check, whether the last character's font has changed.
+                               rawtmpfont = cursor.par->GetFontSettings(cursor.par->Last() - 1);
+                               if (rawparfont != rawtmpfont)
+                                       RedoHeightOfParagraph(cursor);
+                               return;
+                       }
+               }
+               
+               // break the cursor row again
+               z = NextBreakPoint(row, paperwidth);
+               
+               if (z != RowLast(row) || 
+                   (row->next && row->next->par == row->par &&
+                    RowLast(row) == row->par->Last() - 1)){
+                       
+                       /* it can happen that a paragraph loses one row
+                        * without a real breakup. This is when a word
+                        * is to long to be broken. Well, I don t care this 
+                        * hack ;-) */ 
+                       if (row->next && row->next->par == row->par &&
+                           RowLast(row) == row->par->Last() - 1)
+                               RemoveRow(row->next);
+                       
+                       refresh_y = y;
+                       refresh_row = row;
+                       status = LyXText::NEED_MORE_REFRESH;
+                       
+                       BreakAgainOneRow(row);
+                       current_font = rawtmpfont; 
+                       real_current_font = realtmpfont;
+                       SetCursor(cursor.par, cursor.pos, false);
+                       // cursor MUST be in row now
+                       
+                       if (row->next && row->next->par == row->par)
+                               need_break_row = row->next;
+                       else
+                               need_break_row = 0;
+               } else  {
+                       // set the dimensions of the row
+                       row->fill = Fill(row, paperwidth);
+                       int tmpheight = row->height;
+                       SetHeightOfRow(row);
+                       if (tmpheight == row->height)
+                               status = LyXText::NEED_VERY_LITTLE_REFRESH;
+                       else
+                               status = LyXText::NEED_MORE_REFRESH;
+                       refresh_y = y;
+                       refresh_row = row;
+                       current_font = rawtmpfont; 
+                       real_current_font = realtmpfont;
+                       SetCursor(cursor.par, cursor.pos, false);
+               }
+       }
+   
+       // restore the current font
+       // That is what a user expects!
+       current_font = rawtmpfont; 
+       real_current_font = realtmpfont;
+       
+       // check, wether the last characters font has changed.
+       rawtmpfont = cursor.par->GetFontSettings(cursor.par->Last() - 1);
+       if (rawparfont != rawtmpfont) {
+               RedoHeightOfParagraph(cursor);
+       } else {
+               // now the special right address boxes
+               if (textclasslist.Style(parameters->textclass,
+                                       cursor.par->GetLayout()).margintype == MARGIN_RIGHT_ADDRESS_BOX) {
+                       RedoDrawingOfParagraph(cursor); 
+               }
+       }
+}
+
+
+#ifdef USE_PAINTER
+void LyXText::GetVisibleRow(int offset, 
+                           Row * row_ptr, long y)
 {
-       LyXParagraph * tmppar = cursor.par->ParFromPos(cursor.pos);
+       /* returns a printed row */
+       Painter & pain = owner_->painter();
+       
+       LyXDirection direction = row_ptr->par->getParDirection();
+       LyXParagraph::size_type vpos, pos, pos_end;
+       float x, tmpx;
+       int y_top, y_bottom;
+       float fill_separator, fill_hfill, fill_label_hfill;
+       LyXParagraph * par, * firstpar;
+       LyXFont font;
+       int maxdesc;
+       if (row_ptr->height <= 0) {
+               lyxerr << "LYX_ERROR: row.height: " << row_ptr->height << endl;
+               return;
+       }
+       PrepareToPrint(row_ptr, x, fill_separator,
+                      fill_hfill, fill_label_hfill);
 
-       SetUndo(Undo::FINISH, tmppar->previous, tmppar->next); 
+       /* initialize the pixmap */
+       
+       pain.fillRectangle(0, offset, paperwidth, row_ptr->height);
+       
+       // check for NOT FAST SELECTION
+       if (!fast_selection && !mono_video && selection) {
+               /* selection code */ 
+               if (sel_start_cursor.row == row_ptr &&
+                   sel_end_cursor.row == row_ptr) {
+                       if (sel_start_cursor.x < sel_end_cursor.x)
+                               pain.fillRectangle(sel_start_cursor.x, offset,
+                                                  sel_end_cursor.x,
+                                                  row_ptr->height,
+                                                  LColor::selection);
+                       else
+                               pain.fillRectangle(sel_end_cursor.x, offset,
+                                                  sel_start_cursor.x,
+                                                  row_ptr->height,
+                                                  LColor::selection);
+               }
+               else if (sel_start_cursor.row == row_ptr) {
+                    if (direction == LYX_DIR_LEFT_TO_RIGHT)
+                            pain.fillRectangle(sel_start_cursor.x, offset,
+                                               paperwidth - sel_start_cursor.x,
+                                               row_ptr->height,
+                                               LColor::selection);
+                    else
+                            pain.fillRectangle(0, offset,
+                                               sel_start_cursor.x,
+                                               row_ptr->height,
+                                               LColor::selection);
+               } else if (sel_end_cursor.row == row_ptr) {
+                    if (direction == LYX_DIR_LEFT_TO_RIGHT)
+                            pain.fillRectangle(0, offset,
+                                               sel_end_cursor.x,
+                                               row_ptr->height,
+                                               LColor::selection);
+                    else
+                            pain.fillRectangle(sel_end_cursor.x, offset,
+                                               paperwidth - sel_end_cursor.x,
+                                               row_ptr->height,
+                                               LColor::selection);
 
-       LyXParagraph::size_type tmppos = 
-               cursor.par->PositionInParFromPos(cursor.pos);
-       while (tmppos < tmppar->size()) {
-               unsigned char c = tmppar->text[tmppos];
-               if (IsKommaChar(c) || IsLineSeparatorChar(c))
-                       break;
-               if (c != LyXParagraph::META_INSET) {
-                       switch (action) {
-                       case text_lowercase:
-                               c = tolower(c);
+               } else if (y > sel_start_cursor.y && y < sel_end_cursor.y) {
+                       pain.fillRectangle(0, offset,
+                                          paperwidth, row_ptr->height,
+                                          LColor::selection);
+               }
+       } // end of NOT FAST SELECTION code
+       
+       if (row_ptr->par->appendix){
+               pain.line(1, offset,
+                         1, offset + row_ptr->height,
+                         LColor::appendixline);
+               pain.line(paperwidth - 2, offset,
+                         paperwidth - 2, offset + row_ptr->height,
+                         LColor::appendixline);
+       }
+
+       if (row_ptr->par->pextra_type == LyXParagraph::PEXTRA_MINIPAGE) {
+               /* draw a marker at the left margin! */ 
+               LyXFont font = GetFont(row_ptr->par, 0);
+               int asc = font.maxAscent();
+               int x = (LYX_PAPER_MARGIN - font.width('|')) / 2;
+               int y1 = (offset + row_ptr->baseline);
+               int y2 = (offset + row_ptr->baseline) - asc;
+               pain.line(x, y1, x, y2, LColor::minipageline);
+       }       
+       if (row_ptr->par->footnoteflag == LyXParagraph::OPEN_FOOTNOTE) {
+               LyXFont font(LyXFont::ALL_SANE);
+               font.setSize(LyXFont::SIZE_FOOTNOTE);
+               font.setColor(LColor::red);
+               
+               int box_x = LYX_PAPER_MARGIN;
+               box_x += font.textWidth(" wide-tab ", 10);
+               if (row_ptr->previous && 
+                   row_ptr->previous->par->footnoteflag != LyXParagraph::OPEN_FOOTNOTE){
+                       string fs;
+                       switch (row_ptr->par->footnotekind) {
+                       case LyXParagraph::MARGIN:
+                               fs = " margin";
                                break;
-                       case text_capitalization:
-                               c = toupper(c);
-                               action = text_lowercase;
+                       case LyXParagraph::FIG:
+                               fs = " fig";
                                break;
-                       case text_uppercase:
-                               c = toupper(c);
+                       case LyXParagraph::TAB:
+                               fs = " tab";
+                               break;
+                       case LyXParagraph::WIDE_FIG:
+                               fs = " wide-fig";
+                               break;
+                       case LyXParagraph::WIDE_TAB:
+                               fs = " wide-tab";
+                               break;
+                       case LyXParagraph::ALGORITHM:
+                               fs = " alg";
+                               break;
+                       case LyXParagraph::FOOTNOTE:
+                               fs = " foot";
                                break;
                        }
-               }
-               
-               tmppar->text[tmppos] = c;
-               ++tmppos;
-       }
-       CheckParagraph(tmppar, tmppos);
-       CursorRightOneWord();
-}
-
-
-void LyXText::Delete()
-{
-       // this is a very easy implementation
-
-       LyXCursor old_cursor = cursor;
-       int old_cur_par_id = old_cursor.par->id();
-       int old_cur_par_prev_id = old_cursor.par->previous ?
-               old_cursor.par->previous->id() : 0;
-       
-       // just move to the right
-       CursorRightIntern();
 
-       // This check is not very good...
-       // The CursorRightIntern calls DeleteEmptyParagrapgMechanism
-       // and that can very well delete the par or par->previous in
-       // old_cursor. Will a solution where we compare paragraph id's
-       //work better?
-#if 1
-       if ((cursor.par->previous ? cursor.par->previous->id() : 0)
-           == old_cur_par_prev_id
-           && cursor.par->id() != old_cur_par_id)
-               return; // delete-empty-paragraph-mechanism has done it
-#else
-       if (cursor.par->previous == old_cursor.par->previous
-           && cursor.par != old_cursor.par)
-               return; // delete-empty-paragraph-mechanism has done it
+#if 0
+                       // Determine background color.
+                       gc_type back = gc_lighted;
+                       if (mono_video) {
+                               back = gc_clear;
+                       }
 #endif
-       // if you had success make a backspace
-       if (old_cursor.par != cursor.par || old_cursor.pos != cursor.pos) {
-               LyXCursor tmpcursor = cursor;
-               cursor = old_cursor; // to make sure undo gets the right cursor position
-               SetUndo(Undo::DELETE, 
-                       cursor.par->ParFromPos(cursor.pos)->previous, 
-                       cursor.par->ParFromPos(cursor.pos)->next); 
-               cursor = tmpcursor;
-               Backspace();
-       }
-}
-
+                       pain.fillRectangle(LYX_PAPER_MARGIN,
+                                          offset + 1,
+                                          box_x - LYX_PAPER_MARGIN,
+                                          int(font.maxAscent()
+                                              + font.maxDescent()),
+                                          LColor::footnotebg);
+
+                       pain.line(LYX_PAPER_MARGIN, offset,
+                                 paperwidth - LYX_PAPER_MARGIN, offset,
+                                 LColor::footnoteframe);
+
+                       pain.text(LYX_PAPER_MARGIN,
+                                 offset + int(font.maxAscent()) + 1,
+                                 fs, font);
+
+                       pain.line(LYX_PAPER_MARGIN, offset,
+                                 LYX_PAPER_MARGIN,
+                                 offset + int(font.maxAscent()
+                                              + font.maxDescent()),
+                                 LColor::footnoteframe);
+
+                       pain.line(LYX_PAPER_MARGIN,
+                                 offset + int(font.maxAscent()
+                                              + font.maxDescent()) + 1,
+                                 box_x,
+                                 offset + int(font.maxAscent()
+                                              + font.maxDescent()) + 1,
+                                 LColor::footnoteframe);
+                       
+               }
+               
+               /* draw the open floats in a red box */
+               pain.line(box_x, offset,
+                         box_x, offset + row_ptr->height,
+                         LColor::footnoteframe);
+
+               pain.line(paperwidth - LYX_PAPER_MARGIN,
+                         offset,
+                         paperwidth - LYX_PAPER_MARGIN,
+                         offset + row_ptr->height,
+                         LColor::footnoteframe);
+       } else  {
+               if (row_ptr->previous &&
+                   row_ptr->previous->par->footnoteflag == LyXParagraph::OPEN_FOOTNOTE) {
+                       LyXFont font(LyXFont::ALL_SANE);
+                       font.setSize(LyXFont::SIZE_FOOTNOTE);
 
-void  LyXText::Backspace()
-{
-       LyXParagraph * tmppar;
-       Row * tmprow, * row;
-       long y;
-       int tmpheight;
+                       int box_x = LYX_PAPER_MARGIN;
+                       box_x += font.textWidth(" wide-tab ", 10);
 
-       /* table stuff -- begin */
-       if (cursor.par->table) {
-               BackspaceInTable();
-               return;
+                       pain.line(box_x, offset,
+                                 paperwidth - LYX_PAPER_MARGIN,
+                                 offset, LColor::footnote);
+               }
        }
-       /* table stuff -- end */
        
-       LyXFont rawtmpfont = current_font;
-       LyXFont realtmpfont = real_current_font;
-   
-       // Get the font that is used to calculate the baselineskip
-       int const lastpos = cursor.par->Last();
-       LyXFont rawparfont = cursor.par->GetFontSettings(lastpos - 1);
-
-       if (cursor.pos == 0) {
-               // we may paste some paragraphs
-      
-               // is it an empty paragraph?
-      
-               if ((lastpos == 0
-                    || (lastpos == 1 && cursor.par->IsSeparator(0)))
-                   && !(cursor.par->Next() 
-                        && cursor.par->footnoteflag == 
-                        LyXParagraph::NO_FOOTNOTE
-                        && cursor.par->Next()->footnoteflag == 
-                        LyXParagraph::OPEN_FOOTNOTE)) {
-                       
-                       if (cursor.par->previous) {
-                               tmppar = cursor.par->previous->FirstPhysicalPar();
-                               if (cursor.par->GetLayout() == tmppar->GetLayout()
-                                   && cursor.par->footnoteflag == tmppar->footnoteflag
-                                   && cursor.par->GetAlign() == tmppar->GetAlign()) {
-                                       
-                                       tmppar->line_bottom = cursor.par->line_bottom;
-                                       tmppar->added_space_bottom = cursor.par->added_space_bottom;
-                                       tmppar->pagebreak_bottom = cursor.par->pagebreak_bottom;
-                               }
-                               
-                               CursorLeftIntern();
-                    
-                               // the layout things can change the height of a row !
-                               tmpheight = cursor.row->height;
-                               SetHeightOfRow(cursor.row);
-                               if (cursor.row->height != tmpheight) {
-                                       refresh_y = cursor.y - cursor.row->baseline;
-                                       refresh_row = cursor.row;
-                                       status = LyXText::NEED_MORE_REFRESH;
-                               }
-                               return;
-                       }
+       LyXLayout const & layout = textclasslist.Style(parameters->textclass,
+                                          row_ptr->par->GetLayout());
+       firstpar = row_ptr->par->FirstPhysicalPar();
+       
+       y_top = 0;
+       y_bottom = row_ptr->height;
+       
+       /* is it a first row? */ 
+       if (row_ptr->pos == 0
+           && row_ptr->par == firstpar) {
+               
+                /* start of appendix? */
+               if (row_ptr->par->start_of_appendix){
+                       owner_->painter().line(1, offset,
+                                              paperwidth - 2, offset,
+                                              LColor::appendixline);
                }
-               if (cursor.par->ParFromPos(cursor.pos)->previous){
-                       SetUndo(Undo::DELETE,
-                               cursor.par->ParFromPos(cursor.pos)->previous->previous,
-                               cursor.par->ParFromPos(cursor.pos)->next);
+
+               /* think about the margins */ 
+               if (!row_ptr->previous)
+                       y_top += LYX_PAPER_MARGIN;
+               
+               if (row_ptr->par->pagebreak_top){ /* draw a top pagebreak  */
+                       pain.line(0, offset + y_top + 2 * DefaultHeight(),
+                                 paperwidth, offset + y_top + 2 * DefaultHeight(),
+                                 LColor::pagebreak, Painter::line_onoffdash);
+                       y_top += 3 * DefaultHeight();
                }
-               tmppar = cursor.par;
-               tmprow = cursor.row;
-               CursorLeftIntern();
-               /* Pasting is not allowed, if the paragraphs have different
-                  layout. I think it is a real bug of all other
-                  word processors to allow it. It confuses the user.
-                  Even so with a footnote paragraph and a non-footnote
-                  paragraph. I will not allow pasting in this case, 
-                  because the user would be confused if the footnote behaves 
-                  different wether it is open or closed.
-                 
-                  Correction: Pasting is always allowed with standard-layout
-               */
-               if (cursor.par != tmppar
-                   && (cursor.par->GetLayout() == tmppar->GetLayout()
-                       || !tmppar->GetLayout())
-                   && cursor.par->footnoteflag == tmppar->footnoteflag
-                   /* table stuff -- begin*/
-                   && !cursor.par->table /* no pasting of tables */ 
-                   /* table stuff -- end*/
-                   && cursor.par->GetAlign() == tmppar->GetAlign()) {
-                       
-                       cursor.par->PasteParagraph();
-                       
-                       if (!(cursor.pos &&
-                             cursor.par->IsSeparator(cursor.pos - 1)))
-                               cursor.par->InsertChar(cursor.pos, ' ');
-                       else
-                               if (cursor.pos)
-                                       cursor.pos--;
-                       
-                       status = LyXText::NEED_MORE_REFRESH;
-                       refresh_row = cursor.row;
-                       refresh_y = cursor.y - cursor.row->baseline;
+               
+               if (row_ptr->par->added_space_top.kind() == VSpace::VFILL) {
+                       /* draw a vfill top  */
+                       pain.line(0, offset + 2 + y_top,
+                                 LYX_PAPER_MARGIN, offset + 2 + y_top,
+                                 LColor::vfillline);
                        
-                       // remove the lost paragraph
-                       RemoveParagraph(tmprow);
-                       RemoveRow(tmprow);  
+                       pain.line(0, offset + y_top + 3 * DefaultHeight(),
+                                 LYX_PAPER_MARGIN,
+                                 offset + y_top + 3 * DefaultHeight(),
+                                 LColor::vfillline);
                        
-                       AppendParagraph(cursor.row);
-                       UpdateCounters(cursor.row);
+                       pain.line(LYX_PAPER_MARGIN / 2, offset + 2 + y_top,
+                                 LYX_PAPER_MARGIN / 2,
+                                 offset + y_top + 3 * DefaultHeight(),
+                                 LColor::vfillline);
                        
-                       // the row may have changed, block, hfills etc.
-                       SetCursor(cursor.par, cursor.pos);
+                       y_top += 3 * DefaultHeight();
                }
-       } else {
-               /* this is the code for a normal backspace, not pasting
-                * any paragraphs */ 
-               SetUndo(Undo::DELETE, 
-                       cursor.par->ParFromPos(cursor.pos)->previous, 
-                       cursor.par->ParFromPos(cursor.pos)->next); 
-               CursorLeftIntern();
                
-               // some insets are undeletable here
-               if (cursor.par->GetChar(cursor.pos) == LyXParagraph::META_INSET) {
-                       if (!cursor.par->GetInset(cursor.pos)->Deletable())
-                               return; 
-                       // force complete redo when erasing display insets
-                       // this is a cruel mathod but save..... Matthias 
-                       if (cursor.par->GetInset(cursor.pos)->display()){
-                               cursor.par->Erase(cursor.pos);
-                               RedoParagraph();
-                               return;
-                       }
-               }
+               /* think about user added space */ 
+               y_top += int(row_ptr->par->added_space_top.inPixels());
                
-               row = cursor.row;
-               y = cursor.y - row->baseline;
-               LyXParagraph::size_type z;
-               /* remember that a space at the end of a row doesnt count
-                * when calculating the fill */ 
-               if (cursor.pos < RowLast(row) ||
-                   !cursor.par->IsLineSeparator(cursor.pos)) {
-                       row->fill += SingleWidth(cursor.par, cursor.pos);
+               /* think about the parskip */ 
+               /* some parskips VERY EASY IMPLEMENTATION */ 
+               if (parameters->paragraph_separation == BufferParams::PARSEP_SKIP) {
+                       if (layout.latextype == LATEX_PARAGRAPH
+                           && firstpar->GetDepth() == 0
+                           && firstpar->Previous())
+                               y_top += parameters->getDefSkip().inPixels();
+                       else if (firstpar->Previous()
+                                && textclasslist.Style(parameters->textclass,
+                                                  firstpar->Previous()->GetLayout()).latextype == LATEX_PARAGRAPH
+                                && firstpar->Previous()->GetDepth() == 0)
+                               // is it right to use defskip here, too? (AS) 
+                               y_top += parameters->getDefSkip().inPixels();
                }
                
-               /* some special code when deleting a newline. This is similar
-                * to the behavior when pasting paragraphs */ 
-               if (cursor.pos && cursor.par->IsNewline(cursor.pos)) {
-                       cursor.par->Erase(cursor.pos);
-                       // refresh the positions
-                       tmprow = row;
-                       while (tmprow->next && tmprow->next->par == row->par) {
-                               tmprow = tmprow->next;
-                               tmprow->pos--;
-                       }
-                       if (cursor.par->IsLineSeparator(cursor.pos - 1))
-                               cursor.pos--;
-                       
-                       if (cursor.pos < cursor.par->Last() && !cursor.par->IsSeparator(cursor.pos)) {
-                               cursor.par->InsertChar(cursor.pos, ' ');
-                               // refresh the positions
-                               tmprow = row;
-                               while (tmprow->next && tmprow->next->par == row->par) {
-                                       tmprow = tmprow->next;
-                                       tmprow->pos++;
-                               }
-                       }
-               } else {
-                       cursor.par->Erase(cursor.pos);
-                       
-                       // refresh the positions
-                       tmprow = row;
-                       while (tmprow->next && tmprow->next->par == row->par) {
-                               tmprow = tmprow->next;
-                               tmprow->pos--;
-                       }
+               if (row_ptr->par->line_top) {      /* draw a top line  */
+                       y_top +=  GetFont(row_ptr->par, 0).ascent('x');
 
-#ifndef FIX_DOUBLE_SPACE
-                       // delete superfluous blanks 
-                       if (cursor.pos < cursor.par->Last() - 1 &&
-                           (cursor.par->IsLineSeparator(cursor.pos))) {
+                       pain.line(0, offset + y_top,
+                                 paperwidth, offset + y_top,
+                                 LColor::topline,
+                                 Painter::line_solid,
+                                 Painter::line_thick);
+                       
+                       y_top +=  GetFont(row_ptr->par, 0).ascent('x');
+               }
+               
+               /* should we print a label? */ 
+               if (layout.labeltype >= LABEL_STATIC
+                   && (layout.labeltype != LABEL_STATIC
+                       || layout.latextype != LATEX_ENVIRONMENT
+                       || row_ptr->par->IsFirstInSequence())) {
+                       font = GetFont(row_ptr->par, -2);
+                       if (!row_ptr->par->GetLabestring().empty()) {
+                               tmpx = x;
+                               string tmpstring = row_ptr->par->GetLabestring();
                                
-                               if (cursor.pos == BeginningOfMainBody(cursor.par)
-                                   || !cursor.pos 
-                                   || cursor.par->IsLineSeparator(cursor.pos - 1)) {
-                                       cursor.par->Erase(cursor.pos);
-                                       // refresh the positions
-                                       tmprow = row;
-                                       while (tmprow->next && 
-                                              tmprow->next->par == row->par) {
-                                               tmprow = tmprow->next;
-                                               tmprow->pos--;
+                               if (layout.labeltype == LABEL_COUNTER_CHAPTER) {
+                                       if (parameters->secnumdepth >= 0){
+                                               /* this is special code for the chapter layout. This is printed in
+                                                * an extra row and has a pagebreak at the top. */
+                                               maxdesc = int(font.maxDescent() * layout.spacing.getValue() * parameters->spacing.getValue())
+                                                       + int(layout.parsep) * DefaultHeight();
+                                               if (direction == LYX_DIR_RIGHT_TO_LEFT)
+                                                       tmpx = paperwidth - LeftMargin(row_ptr) - 
+                                                               font.stringWidth(tmpstring);
+                                               pain.text(int(tmpx),
+                                                         offset + row_ptr->baseline - row_ptr->ascent_of_text - maxdesc,
+                                                         tmpstring, font);
                                        }
-                                       if (cursor.pos)   // move one character left
-                                               cursor.pos--;
+                               } else {
+                                       if (direction == LYX_DIR_LEFT_TO_RIGHT)
+                                               tmpx = x - font.stringWidth(layout.labelsep)
+                                                       - font.stringWidth(tmpstring);
+                                       else {
+                                               tmpx = paperwidth - LeftMargin(row_ptr)
+                                                       + font.stringWidth(layout.labelsep);
+                                               if (row_ptr->par->footnoteflag == LyXParagraph::OPEN_FOOTNOTE)  {
+                                                       LyXFont font(LyXFont::ALL_SANE);
+                                                       font.setSize(LyXFont::SIZE_SMALL);
+                                                       tmpx += font.textWidth("Mwide-figM", 10);
+                                               }
+                                       }
+                                       /* draw it! */
+                                       pain.text(int(tmpx),
+                                                 offset + row_ptr->baseline,
+                                                 tmpstring, font);
                                }
                        }
-#endif
-                       
-                       // delete newlines at the beginning of paragraphs
-                       while (cursor.par->Last() &&
-                              cursor.par->IsNewline(cursor.pos) &&
-                              cursor.pos == BeginningOfMainBody(cursor.par)) {
-                               cursor.par->Erase(cursor.pos);
-                               // refresh the positions
-                               tmprow = row;
-                               while (tmprow->next && 
-                                      tmprow->next->par == row->par) {
-                                       tmprow = tmprow->next;
-                                       tmprow->pos--;
+                       /* the labels at the top of an environment. More or less for bibliography */ 
+               } else if (layout.labeltype == LABEL_TOP_ENVIRONMENT ||
+                          layout.labeltype == LABEL_BIBLIO ||
+                          layout.labeltype == LABEL_CENTERED_TOP_ENVIRONMENT) {
+                       if (row_ptr->par->IsFirstInSequence()) {
+                               font = GetFont(row_ptr->par, -2);
+                               if (!row_ptr->par->GetLabestring().empty()) {
+                                       string tmpstring = row_ptr->par->GetLabestring();
+                                       
+                                       maxdesc = int(font.maxDescent() * layout.spacing.getValue() * parameters->spacing.getValue()
+                                                        + (layout.labelbottomsep * DefaultHeight()));
+                                       
+                                       tmpx = x;
+                                       if (layout.labeltype == LABEL_CENTERED_TOP_ENVIRONMENT){
+                                               tmpx = ( ((direction == LYX_DIR_LEFT_TO_RIGHT)
+                                                         ? x : LeftMargin(row_ptr) )
+                                                        + paperwidth - RightMargin(row_ptr) ) / 2; 
+                                               tmpx -= (font.stringWidth(tmpstring)/2);
+                                       } else if (direction == LYX_DIR_RIGHT_TO_LEFT)
+                                               tmpx = paperwidth - LeftMargin(row_ptr) - 
+                                                       font.stringWidth(tmpstring);
+                                       pain.text(int(tmpx),
+                                                 offset + row_ptr->baseline
+                                                 - row_ptr->ascent_of_text
+                                                 - maxdesc,
+                                                 tmpstring, font);
                                }
                        }
                }
+               if (layout.labeltype == LABEL_BIBLIO) { // ale970302
+                       if (row_ptr->par->bibkey) {
+                               font = GetFont(row_ptr->par, -1);
+                               if (direction == LYX_DIR_LEFT_TO_RIGHT)
+                                       tmpx = x - font.stringWidth(layout.labelsep)
+                                               - row_ptr->par->bibkey->width(owner_->painter(), font);
+                               else
+                                       tmpx = paperwidth - LeftMargin(row_ptr)
+                                               + font.stringWidth(layout.labelsep);
+                               row_ptr->par->bibkey->draw(owner_->painter(),
+                                                          font,
+                                                          offset + row_ptr->baseline, 
+                                                          tmpx);
+                       }
+               } 
+       }
+       
+       /* is it a last row? */
+       par = row_ptr->par->LastPhysicalPar();
+       if (row_ptr->par->ParFromPos(RowLast(row_ptr) + 1) == par
+           && (!row_ptr->next || row_ptr->next->par != row_ptr->par)) {     
+               
+               /* think about the margins */ 
+               if (!row_ptr->next)
+                       y_bottom -= LYX_PAPER_MARGIN;
+               
+               /* draw a bottom pagebreak */ 
+               if (firstpar->pagebreak_bottom) {
+                       pain.line(0, offset + y_bottom - 2 * DefaultHeight(),
+                                 paperwidth,
+                                 offset + y_bottom - 2 * DefaultHeight(),
+                                 LColor::pagebreak);
+                       y_bottom -= 3 * DefaultHeight();
+               }
+               
+               if (firstpar->added_space_bottom.kind() == VSpace::VFILL) {
+                       /* draw a vfill bottom  */
+                       pain.line(0, offset + y_bottom - 3 * DefaultHeight(),
+                                 LYX_PAPER_MARGIN,
+                                 offset + y_bottom - 3 * DefaultHeight(),
+                                 LColor::vfillline);
+                       pain.line(0, offset + y_bottom - 2,
+                                 LYX_PAPER_MARGIN,
+                                 offset + y_bottom - 2,
+                                 LColor::vfillline);
+                       pain.line(LYX_PAPER_MARGIN / 2,
+                                 offset + y_bottom - 3 * DefaultHeight(),
+                                 LYX_PAPER_MARGIN / 2,
+                                 offset + y_bottom - 2,
+                                 LColor::vfillline);
+                       y_bottom -= 3* DefaultHeight();
+               }
+               
+               /* think about user added space */ 
+               y_bottom -= int(firstpar->added_space_bottom.inPixels());
+               
+               if (firstpar->line_bottom) {
+                       /* draw a bottom line */
+                       y_bottom -= GetFont(par, par->Last() - 1).ascent('x');
+                       pain.line(0, offset + y_bottom,
+                                 paperwidth, offset + y_bottom,
+                                 LColor::topline, Painter::line_solid,
+                                 Painter::line_thick);
+                       y_bottom -= GetFont(par, par->Last() - 1).ascent('x');
+               }
+       }
+       
+       /* draw the text in the pixmap */  
+       pos_end = RowLast(row_ptr);
+       
+       vpos = row_ptr->pos;
+       /* table stuff -- begin*/
+       if (row_ptr->par->table) {
+               bool on_off;
+               int cell = NumberOfCell(row_ptr->par, row_ptr->pos);
+               float x_old = x;
+               x += row_ptr->par->table->GetBeginningOfTextInCell(cell);
                
-               // is there a break one row above
-               if (row->previous && row->previous->par == row->par) {
-                       z = NextBreakPoint(row->previous, paperwidth);
-                       if ( z >= row->pos) {
-                               row->pos = z + 1;
+               while (vpos <= pos_end)  {
+                       pos = vis2log(vpos);
+                       if (row_ptr->par->IsNewline(pos)) {
                                
-                               tmprow = row->previous;
+                               x = x_old + row_ptr->par->table->WidthOfColumn(cell);
+                               /* draw the table lines, still very simple */
+                               on_off = !row_ptr->par->table->TopLine(cell);
+                               if ((!on_off ||
+                                    !row_ptr->par->table->TopAlreadyDrawed(cell)) &&
+                                   !row_ptr->par->table->IsContRow(cell))
+                                       pain.line(int(x_old),
+                                                 offset + row_ptr->baseline - row_ptr->ascent_of_text,
+                                                 int(x - x_old),
+                                                 offset + row_ptr->baseline - row_ptr->ascent_of_text,
+                                                 LColor::tableline);
                                
-                               // maybe the current row is now empty
-                               if (row->pos >= row->par->Last()) {
-                                       // remove it
-                                       RemoveRow(row);
-                                       need_break_row = 0;
-                               } else {
-                                       BreakAgainOneRow(row);
-                                       if (row->next && row->next->par == row->par)
-                                               need_break_row = row->next;
-                                       else
-                                               need_break_row = 0;
-                               }
+                               on_off = !row_ptr->par->table->BottomLine(cell);
+                               if ((!on_off && !row_ptr->par->table->RowHasContRow(cell)) ||
+                                   row_ptr->par->table->VeryLastRow(cell))
+
+                                       pain.line(int(x_old),
+                                                 offset + y_bottom - 1,
+                                                 int(x - x_old),
+                                                 offset + y_bottom - 1,
+                                                 LColor::tableline);
+
+                               on_off = !row_ptr->par->table->LeftLine(cell);
+
+                               pain.line(int(x_old),
+                                         offset + row_ptr->baseline - row_ptr->ascent_of_text,
+                                         int(x_old),
+                                         offset + y_bottom,
+                                         LColor::tableline,
+                                         Painter::line_onoffdash);
                                
-                               // set the dimensions of the row above
-                               y -= tmprow->height;
-                               tmprow->fill = Fill(tmprow, paperwidth);
-                               SetHeightOfRow(tmprow);
+                               on_off = !row_ptr->par->table->RightLine(cell);
+
+                               pain.line(int(x) - row_ptr->par->table->AdditionalWidth(cell),
+                                         offset + row_ptr->baseline - row_ptr->ascent_of_text,
+                                         int(x) - row_ptr->par->table->AdditionalWidth(cell),
+                                         offset + y_bottom - 1,
+                                         LColor::tableline,
+                                         Painter::line_onoffdash);
                                
-                               refresh_y = y;
-                               refresh_row = tmprow;
-                               status = LyXText::NEED_MORE_REFRESH;
-                               current_font = rawtmpfont;
-                               real_current_font = realtmpfont;
-                               SetCursor(cursor.par, cursor.pos, false);
-                               // check, whether the last character's font has changed.
-                               rawtmpfont = cursor.par->GetFontSettings(cursor.par->Last() - 1);
-                               if (rawparfont != rawtmpfont)
-                                       RedoHeightOfParagraph(cursor);
-                               return;
+                               x_old = x;
+                /* take care about the alignment and other spaces */
+                               ++cell;
+                               x += row_ptr->par->table->GetBeginningOfTextInCell(cell);
+                               if (row_ptr->par->table->IsFirstCell(cell))
+                                       --cell; // little hack, sorry
+                               ++vpos;
+                       } else if (row_ptr->par->IsHfill(pos)) {
+                               x += 1;
+
+                               pain.line(int(x),
+                                         offset + row_ptr->baseline - DefaultHeight() / 2,
+                                         int(x),
+                                         offset + row_ptr->baseline,
+                                         LColor::vfillline);
+                               
+                               x += 2;
+                               ++vpos;
+                       } else {
+                               if (row_ptr->par->IsSeparator(pos)) {
+                                       tmpx = x;
+                                       x+= SingleWidth(row_ptr->par, pos);
+                                       /* -------> Only draw protected spaces when not in
+                                        * free-spacing mode. */
+                                       if (row_ptr->par->GetChar(pos) == LyXParagraph::META_PROTECTED_SEPARATOR && !layout.free_spacing) {
+                                               pain.line(int(tmpx),
+                                                         offset + row_ptr->baseline - 3,
+                                                         int(tmpx),
+                                                         offset + row_ptr->baseline - 1,
+                                                         LColor::vfillline);
+                                               
+                                               pain.line(int(tmpx),
+                                                         offset + row_ptr->baseline - 1,
+                                                         int(x - tmpx - 2),
+                                                         offset + row_ptr->baseline - 1,
+                                                         LColor::vfillline);
+                                               
+                                               pain.line(int(x - 2),
+                                                         offset + row_ptr->baseline - 3,
+                                                         int(x - 2),
+                                                         offset + row_ptr->baseline - 1,
+                                                         LColor::vfillline);
+                                               
+                                               /* what about underbars? */
+                                               font = GetFont(row_ptr->par, pos); 
+                                               if (font.underbar() == LyXFont::ON
+                                                   && font.latex() != LyXFont::ON) {
+                                                       pain.line(int(tmpx),
+                                                                 offset + row_ptr->baseline + 2,
+                                                                 int(x - tmpx),
+                                                                 offset + row_ptr->baseline + 2);
+                                               }
+                                       }
+                                       ++vpos;
+                               } else
+                                       draw(row_ptr, vpos, offset, x);
                        }
                }
                
-               // break the cursor row again
-               z = NextBreakPoint(row, paperwidth);
-               
-               if (z != RowLast(row) || 
-                   (row->next && row->next->par == row->par &&
-                    RowLast(row) == row->par->Last() - 1)){
-                       
-                       /* it can happen that a paragraph loses one row
-                        * without a real breakup. This is when a word
-                        * is to long to be broken. Well, I don t care this 
-                        * hack ;-) */ 
-                       if (row->next && row->next->par == row->par &&
-                           RowLast(row) == row->par->Last() - 1)
-                               RemoveRow(row->next);
-                       
-                       refresh_y = y;
-                       refresh_row = row;
-                       status = LyXText::NEED_MORE_REFRESH;
+               /* do not forget the very last cell. This has no NEWLINE so 
+                * ignored by the code above*/ 
+               if (cell == row_ptr->par->table->GetNumberOfCells()-1){
+                       x = x_old + row_ptr->par->table->WidthOfColumn(cell);
+                       on_off = !row_ptr->par->table->TopLine(cell);
+                       if ((!on_off ||
+                            !row_ptr->par->table->TopAlreadyDrawed(cell)) &&
+                           !row_ptr->par->table->IsContRow(cell))
+
+                               pain.line(int(x_old),
+                                         offset + row_ptr->baseline - row_ptr->ascent_of_text,
+                                         int(x - x_old),
+                                         offset + row_ptr->baseline - row_ptr->ascent_of_text,
+                                         LColor::tableline,
+                                         Painter::line_onoffdash);
+                       on_off = !row_ptr->par->table->BottomLine(cell);
+                       if ((!on_off && !row_ptr->par->table->RowHasContRow(cell)) ||
+                           row_ptr->par->table->VeryLastRow(cell))
+
+                               pain.line(int(x_old),
+                                         offset + y_bottom - 1,
+                                         int(x - x_old),
+                                         offset + y_bottom - 1,
+                                         LColor::tableline,
+                                         Painter::line_onoffdash);
                        
-                       BreakAgainOneRow(row);
-                       current_font = rawtmpfont; 
-                       real_current_font = realtmpfont;
-                       SetCursor(cursor.par, cursor.pos, false);
-                       // cursor MUST be in row now
+                       on_off = !row_ptr->par->table->LeftLine(cell);
+
+                       pain.line(int(x_old),
+                                 offset + row_ptr->baseline - row_ptr->ascent_of_text,
+                                 int(x_old),
+                                 offset + y_bottom - 1,
+                                 LColor::tableline,
+                                 Painter::line_onoffdash);
                        
-                       if (row->next && row->next->par == row->par)
-                               need_break_row = row->next;
-                       else
-                               need_break_row = 0;
-               } else  {
-                       // set the dimensions of the row
-                       row->fill = Fill(row, paperwidth);
-                       int tmpheight = row->height;
-                       SetHeightOfRow(row);
-                       if (tmpheight == row->height)
-                               status = LyXText::NEED_VERY_LITTLE_REFRESH;
-                       else
-                               status = LyXText::NEED_MORE_REFRESH;
-                       refresh_y = y;
-                       refresh_row = row;
-                       current_font = rawtmpfont; 
-                       real_current_font = realtmpfont;
-                       SetCursor(cursor.par, cursor.pos, false);
+                       on_off = !row_ptr->par->table->RightLine(cell);
+
+                       pain.line(int(x) - row_ptr->par->table->AdditionalWidth(cell),
+                                 offset + row_ptr->baseline - row_ptr->ascent_of_text,
+                                 int(x) - row_ptr->par->table->AdditionalWidth(cell),
+                                 offset + y_bottom - 1,
+                                 LColor::tableline,
+                                 Painter::line_onoffdash);
                }
-       }
-   
-       // restore the current font
-       // That is what a user expects!
-       current_font = rawtmpfont; 
-       real_current_font = realtmpfont;
-       
-       // check, wether the last characters font has changed.
-       rawtmpfont = cursor.par->GetFontSettings(cursor.par->Last() - 1);
-       if (rawparfont != rawtmpfont) {
-               RedoHeightOfParagraph(cursor);
        } else {
-               // now the special right address boxes
-               if (textclasslist.Style(parameters->textclass,
-                                       cursor.par->GetLayout()).margintype == MARGIN_RIGHT_ADDRESS_BOX) {
-                       RedoDrawingOfParagraph(cursor); 
+               /* table stuff -- end*/
+               LyXParagraph::size_type main_body = 
+                       BeginningOfMainBody(row_ptr->par);
+               if (main_body > 0 &&
+                   (main_body-1 > pos_end || 
+                    !row_ptr->par->IsLineSeparator(main_body-1)))
+                       main_body = 0;
+
+               while (vpos <= pos_end)  {
+                       pos = vis2log(vpos);
+                       if (main_body > 0 && pos == main_body-1) {
+                               x += fill_label_hfill
+                                       + GetFont(row_ptr->par, -2).stringWidth(layout.labelsep)
+                                       - SingleWidth(row_ptr->par, main_body-1);
+                       }
+
+                       if (row_ptr->par->IsHfill(pos)) {
+                               x += 1;
+                               pain.line(int(x),
+                                         offset + row_ptr->baseline - DefaultHeight() / 2,
+                                         int(x),
+                                         offset + row_ptr->baseline,
+                                         LColor::vfillline);
+                               
+                               if (HfillExpansion(row_ptr, pos)) {
+                                       if (pos >= main_body) {
+                                               pain.line(int(x),
+                                                         offset + row_ptr->baseline - DefaultHeight() / 4,
+                                                         int(fill_hfill),
+                                                         offset + row_ptr->baseline - DefaultHeight() / 4,
+                                                         LColor::vfillline,
+                                                         Painter::line_onoffdash);
+                                               x += fill_hfill;
+                    } else {
+                           pain.line(int(x),
+                                     offset + row_ptr->baseline - DefaultHeight() / 4,
+                                     int(fill_label_hfill),
+                                     offset + row_ptr->baseline - DefaultHeight() / 4,
+                                     LColor::vfillline,
+                                     Painter::line_onoffdash);
+                           
+                           x += fill_label_hfill;
+                    }
+                                       pain.line(int(x),
+                                                 offset + row_ptr->baseline - DefaultHeight() / 2,
+                                                 int(x),
+                                                 offset + row_ptr->baseline,
+                                                 LColor::vfillline);
+                               }
+                               x += 2;
+                               ++vpos;
+                       } else {
+                               if (row_ptr->par->IsSeparator(pos)) {
+                                       tmpx = x;
+                                       x+= SingleWidth(row_ptr->par, pos);
+                                       if (pos >= main_body)
+                                               x+= fill_separator;
+                                       /* -------> Only draw protected spaces when not in
+                                        * free-spacing mode. */
+                                       if (row_ptr->par->GetChar(pos) == LyXParagraph::META_PROTECTED_SEPARATOR && !layout.free_spacing) {
+
+                                               pain.line(int(tmpx),
+                                                         offset + row_ptr->baseline - 3,
+                                                         int(tmpx),
+                                                         offset + row_ptr->baseline - 1,
+                                                         LColor::vfillline);
+                                               
+                                               pain.line(int(tmpx),
+                                                         offset + row_ptr->baseline - 1,
+                                                         int(tmpx),
+                                                         offset + row_ptr->baseline - 1,
+                                                         LColor::vfillline);
+
+                                               pain.line(int(x - 2),
+                                                         offset + row_ptr->baseline - 3,
+                                                         int(x - 2),
+                                                         offset + row_ptr->baseline - 1,
+                                                         LColor::vfillline);
+                                               
+                                               /* what about underbars? */
+                                               font = GetFont(row_ptr->par, pos); 
+                                               if (font.underbar() == LyXFont::ON
+                                                   && font.latex() != LyXFont::ON) {
+                                                       pain.line(int(tmpx),
+                                                                 offset + row_ptr->baseline + 2,
+                                                                 int(x - tmpx),
+                                                                 offset + row_ptr->baseline + 2);
+                                               }
+                                       }
+                                       ++vpos;
+                               } else
+                                       draw(row_ptr, vpos, offset, x);
+                       }
+               }
+       }
+#if 0
+       // check for FAST SELECTION
+       if (fast_selection || mono_video) {
+               if (selection) {
+                       
+                       /* selection code */ 
+                       if (sel_start_cursor.row == row_ptr && sel_end_cursor.row == row_ptr) {
+                               scr.fillRectangle(gc_select, sel_start_cursor.x, offset,
+                                                 sel_end_cursor.x - sel_start_cursor.x,
+                                                 row_ptr->height); 
+                       } else if (sel_start_cursor.row == row_ptr) {
+                               scr.fillRectangle(gc_select, sel_start_cursor.x, offset,
+                                                 paperwidth - sel_start_cursor.x,
+                                                 row_ptr->height);
+                       } else if (sel_end_cursor.row == row_ptr) {
+                               scr.fillRectangle(gc_select, 0, offset,
+                                                 sel_end_cursor.x,
+                                                 row_ptr->height);
+                       } else if (y > sel_start_cursor.y && y < sel_end_cursor.y) {
+                               scr.fillRectangle(gc_select, 0, offset,
+                                                 paperwidth, row_ptr->height);
+                               
+                       }
                }
        }
+// end of FAST SELECTION code
+       /* thats it */
+#endif
 }
-
-
+#else
 void LyXText::GetVisibleRow(LyXScreen & scr, int offset, 
                            Row * row_ptr, long y)
 {
@@ -3582,7 +4848,11 @@ void LyXText::GetVisibleRow(LyXScreen & scr, int offset,
        if (row_ptr->par->footnoteflag == LyXParagraph::OPEN_FOOTNOTE) {
                LyXFont font(LyXFont::ALL_SANE);
                font.setSize(LyXFont::SIZE_FOOTNOTE);
+#ifdef USE_PAINTER
+               font.setColor(LColor::footnote);
+#else
                font.setColor(LyXFont::RED);
+#endif
                
                int box_x = LYX_PAPER_MARGIN;
                box_x += font.textWidth(" wide-tab ", 10);
@@ -4105,7 +5375,7 @@ void LyXText::GetVisibleRow(LyXScreen & scr, int offset,
 // end of FAST SELECTION code
        /* thats it */ 
 }
-
+#endif
 
 int LyXText::DefaultHeight() const
 {
index 249607947a2dbcd5681cd1941a04fb207d2a7150..4652c1c803e7b9e81ab39273c0b0fa5cf0bfb9a0 100644 (file)
@@ -42,8 +42,9 @@ extern BufferView * current_view;
 
 using std::copy;
 
-LyXText::LyXText(int pw, Buffer * p)
+LyXText::LyXText(BufferView * bv, int pw, Buffer * p)
 {
+       owner_ = bv;
        firstrow = 0;
        lastrow = 0;
        currentrow = 0;
@@ -96,6 +97,12 @@ LyXText::~LyXText()
 }
 
 
+void LyXText::owner(BufferView * bv)
+{
+       if (owner_) lyxerr << "LyXText::owner_ already set!" << endl;
+       owner_ = bv;
+}
+
 // Gets the fully instantiated font at a given position in a paragraph
 // Basically the same routine as LyXParagraph::getFont() in paragraph.C.
 // The difference is that this one is used for displaying, and thus we