+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
src/latexoptions.C
src/layout.C
src/layout_forms.C
+src/LColor.C
src/Literate.C
src/LyXAction.C
src/lyx.C
src/menus.C
src/minibuffer.C
src/minibuffer.h
+src/Painter.C
src/PaperLayout.C
src/paragraph.C
src/ParagraphExtra.C
#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"
#include "intl.h"
#include "lyxrc.h"
#include "lyxrow.h"
+#include "WorkArea.h"
using std::find_if;
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)
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;
delete text;
}
-
+
+#ifdef USE_PAINTER
+Painter & BufferView::painter()
+{
+ return workarea->getPainter();
+}
+#endif
+
+
void BufferView::buffer(Buffer * b)
{
lyxerr[Debug::INFO] << "Setting buffer in BufferView ("
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
{
// 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()
}
+#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();
}
* 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;
}
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);
} else
fl_set_slider_size(scrollbar, hfloat);
fl_set_slider_precision(scrollbar, 0);
+#endif
}
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";
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();
}
+#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)
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)
// Remove the blue feedback rectangle
fl_set_pixmapbutton_focus_outline(obj, 0);
-
+#endif
//
// TIMERS
//
// 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);
view->ScrollUp(time++); break;
}
}
+#endif
static inline
// 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);
}
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);
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;
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;
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;
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;
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)
}
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*/)
}
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 &&
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*/)
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())
}
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)
owner_->updateLayoutChoice();
return 1;
}
+#endif
// Callback for cursor timer
}
+#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*/)
}
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;
+ 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;
getScreen()->Draw(text->cursor.y
- text->cursor.row->baseline);
}
+#endif
bool BufferView::available() const
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();
+}
#include "LaTeX.h"
#include "undo.h"
+#define NEW_WA 1
+
class LyXView;
class Buffer;
class LyXScreen;
class Inset;
class LyXText;
+class WorkArea;
///
class BufferView {
~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();
///
///
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);
///
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);
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,
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_;
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
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;
}
--- /dev/null
+// -*- 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
--- /dev/null
+// -*- 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
// 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;
}
#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;
ImportLaTeX.h \
ImportNoweb.C \
ImportNoweb.h \
+ LColor.C \
+ LColor.h \
LString.h \
LaTeX.C \
LaTeX.h \
LyXView.C \
LyXView.h \
Makefile.in \
+ Painter.C \
+ Painter.h \
+ PainterBase.C \
+ PainterBase.h \
PaperLayout.C \
ParagraphExtra.C \
Spacing.C \
TableLayout.C \
TextCache.C \
TextCache.h \
+ WorkArea.C \
+ WorkArea.h \
bibforms.h \
bmtable.c \
bmtable.h \
--- /dev/null
+// -*- 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
--- /dev/null
+// -*- 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
--- /dev/null
+/* 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
--- /dev/null
+// -*- 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
--- /dev/null
+/* 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;
+}
--- /dev/null
+// -*- 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
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);
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,
XFreePixmap(fl_display, dummy_shapemask);
}
}
- XFlush(fl_display);
}
}
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);
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;
XFreePixmap(fl_display, dummy_shapemask);
}
}
- XFlush(fl_display);
+ //XFlush(fl_display);
}
}
#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;
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)
{
//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(
// 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
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 "
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 "
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) {
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()) {
void DoneFigures()
{
- //free(figures);
- //free(bitmaps);
delete[] figures;
delete[] bitmaps;
figarrsize = 0;
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
}
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)),
DefaultScreenOfDisplay(fl_display)),
background_pixels);
}
+#endif
XChangeProperty(tempdisp,
fl_get_canvas_id(figinset_canvas),
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;
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;
<< figures[i]->inset
<< endl;
}
- //UpdateInset(figures[i]->inset);
// add inset figures[i]->inset into to_update list
PutInsetIntoInsetUpdateList(figures[i]->inset);
}
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;
}
+#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();
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) {
}
x += Width(font); // ?
}
+#endif
void InsetFig::Write(ostream & os)
cmd = "\\fbox{\\rule[-0.5in]{0pt}{1in}";
cmd += _("empty figure path");
cmd += '}';
- //if (form) fl_set_object_label(form->cmd, "");
return;
}
}
cmd = cmdbuf;
-
- //if (form) fl_set_object_label(form->cmd, cmd.c_str());
}
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 += '}';
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;
///
int Width(LyXFont const & font) const;
///
void Draw(LyXFont font, LyXScreen & scr, int baseline, float & x);
+#endif
///
void Write(ostream &);
///
// 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;
}
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;
return "99";
}
+#endif
* LyX, The Document Processor
*
* Copyright 1995 Matthias Ettrich
- * Copyright 1995-1999 The LyX Team.
+ * Copyright 1995-2000 The LyX Team.
*
* ====================================================== */
#include "insetcommand.h"
#include "lyxdraw.h"
#include "debug.h"
+#include "Painter.h"
InsetCommand::InsetCommand()
{
}
+#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;
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)
{
x += Width(font) - 3;
}
+#endif
// In lyxf3 this will be just LaTeX
*
* LyX, The Document Processor
*
- * Copyright 1995 Matthias Ettrich
- * Copyright 1996-2000 The LyX Team.
+ * Copyright 1995 Matthias Ettrich
+ * Copyright 1995-2000 The LyX Team.
*
* ====================================================== */
///
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;
///
int Width(LyXFont const & font) const;
///
void Draw(LyXFont, LyXScreen & scr, int baseline, float & x);
+#endif
///
void Write(ostream &);
/// Parse the command.
#include "lyxdraw.h"
#include "gettext.h"
#include "lyx_gui_misc.h" // CancelCloseBoxCB
+#include "Painter.h"
/* Error, used for the LaTeX-Error Messages */
}
+#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)
{
x += Width(font) - 1;
}
-
+#endif
void InsetError::Write(ostream &)
{
*
* LyX, The Document Processor
*
- * Copyright (C) 1995 Matthias Ettrich
+ * Copyright 1995 Matthias Ettrich
+ * Copyright 1995-2000 The LyX Team.
*
* ====================================================== */
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;
///
int Width(LyXFont const & font) const;
///
void Draw(LyXFont font, LyXScreen & scr, int baseline, float & x);
+#endif
///
void Write(ostream &);
///
#include "lyx_gui_misc.h" // CancelCloseBoxCB
#include "buffer.h"
#include "support/lstrings.h"
+#include "Painter.h"
/* Info, used for the Info boxes */
}
+#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)
{
scr.drawString(font, _("Note"), baseline, int(x+2));
x += Width(font) - 1;
}
+#endif
void InsetInfo::Write(ostream & os)
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;
///
int Width(LyXFont const & font) const;
///
void Draw(LyXFont font, LyXScreen & scr, int baseline, float & x);
+#endif
///
void Write(ostream &);
///
#include "lyxrc.h"
#include "lyxdraw.h"
#include "support/lstrings.h"
+#include "Painter.h"
extern LyXRC * lyxrc;
}
+#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
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;
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)
else
return font.stringWidth(contents) + 4;
}
+#endif
int InsetLatexAccent::Lbearing(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,
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,
}
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);
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
}
x += Width(font);
}
+#endif
void InsetLatexAccent::Write(ostream & os)
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 &);
///
/// add something to descent - underlined char
bool plusdesc;
/// international char
- char ic;
+ mutable char ic;
};
bool InsetLatexAccent::CanDisplay()
#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.
}
+#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();
return w;
}
+#endif
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)
{
scr.drawString(font, text, baseline, int(x));
x += Width(font);
}
+#endif
void InsetQuotes::Write(ostream & os)
/// 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;
///
int Width(LyXFont const & font) const;
///
void Draw(LyXFont font, LyXScreen & scr, int baseline, float & x);
+#endif
///
LyXFont ConvertFont(LyXFont font);
///
#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;
}
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;
}
}
}
+#endif
// In lyxf3 this will be just LaTeX
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;
///
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
*
* LyX, The Document Processor
*
- * Copyright (C) 1997 LyX Team (this file was created this year)
+ * Copyright 1997-2000 The LyX Team.
*
* ====================================================== */
#include "lyxlex.h"
#include "lyxscreen.h"
+//#define USE_PAINTER 1
+
+#ifdef USE_PAINTER
+class Painter;
+#endif
class Buffer;
struct LaTeXFeatures;
///
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;
///
///
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");}
///
bool isCursorVisible() const { return cursor_visible; }
protected:
///
- bool cursor_visible;
+ mutable bool cursor_visible;
};
#endif
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();
}
}
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;
case 10: font.setColor(LyXFont::YELLOW); break;
case 11: font.setColor(LyXFont::INHERIT_COLOR); break;
}
-
+#endif
return font;
}
// 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
}
+
#include <config.h>
+#ifndef USE_PAINTER
+
#include "lyxdraw.h"
#include "debug.h"
}
+#ifdef USE_PAINTER
+GC GetColorGC(LColor::color color)
+#else
GC GetColorGC(LyXFont::FONT_COLOR color)
+#endif
{
if (color_gc[color]) return color_gc[color];
}
return gc;
}
+
+#endif
// -*- C++ -*-
+#ifndef USE_PAINTER
#ifndef LYX_DRAW_H
#define LYX_DRAW_H
extern GC GetColorGC(LyXFont::FONT_COLOR color);
#endif
+
+#endif
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
//
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
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()
lyxerr <<"Can't LyXFont::decSize on IGNORE_SIZE" << endl;
break;
}
- return (*this);
+ return *this;
}
lyxerr <<"Can't LyXFont::incSize on IGNORE_SIZE" << endl;
break;
}
- return (*this);
+ return *this;
}
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
}
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);
}
/// 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) {
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);
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 &&
color() != INHERIT_COLOR &&
direction() != INHERIT_DIR);
}
+#endif
/// Build GUI description of font state
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)
/// 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;
} else
lyxerr << "LyXFont::setLyXColor: Unknown Color `"
<< s << '\'' << endl;
+#endif
return *this;
}
/// 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() &&
} else
lyxerr << "LyXFont::setGUISize: Unknown Size `"
<< s << '\'' << endl;
+#endif
return *this;
}
error = true;
}
}
- return * this;
+ return *this;
}
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;
/// 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);
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()];
count += LaTeXColorNames[f.color()].length() + 13;
env = true; //We have opened a new environment
}
+#endif
if (f.emph() == ON) {
file += "\\emph{";
count += 6;
/// 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)
++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;
}
+#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
{
}
+#ifndef USE_PAINTER
GC LyXFont::getGC() const
{
GC gc;
XSetFont(fl_display, gc, getXFontstruct()->fid);
return gc;
}
+#endif
XFontStruct * LyXFont::getXFontstruct() 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
{
return x - sx;
}
}
+#endif
int LyXFont::drawString(string const & s, Pixmap pm, int baseline, int x) const
#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
class LyXLex;
+#define NEW_BITS 1
+
///
class LyXFont {
public:
///
IGNORE
};
-
+
+#ifndef USE_PAINTER
///
enum FONT_COLOR {
///
///
IGNORE_COLOR
};
-
+#endif
+
/// Trick to overload constructor and make it megafast
enum FONT_INIT1 {
///
///
FONT_MISC_STATE latex() const;
-
+
+#ifdef USE_PAINTER
+ ///
+ LColor::color color() const;
+#else
///
FONT_COLOR color() const;
+#endif
///
FONT_DIRECTION direction() const;
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);
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;
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) {
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 {
///
///
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
| 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);
LyXFont::FONT_SHAPE realShape() const;
///
- XFontStruct* getXFontstruct() const;
+ XFontStruct * getXFontstruct() const;
};
ostream & operator<<(ostream &, LyXFont::FONT_MISC_STATE);
}
+#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);
}
-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
{
}
+#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)
{
bits |= ui32(d) << Dir_Pos;
return *this;
}
+#endif
#endif
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;
}
#include "ImportLaTeX.h"
#include "ImportNoweb.h"
#include "layout.h"
+#include "WorkArea.h"
extern bool cursor_follows_scrollbar;
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);
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;
owner->view()->text->FinishUndo();
moveCursorUpdate(false);
owner->getMiniBuffer()->Set(CurrentState());
+#endif
}
break;
// 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);
*
* LyX, The Document Processor
*
- * Copyright 1995 Matthias Ettrich
- * Copyright 1995-1999 The LyX Team
+ * Copyright 1995 Matthias Ettrich
+ * Copyright 1995-2000 The LyX Team
*
* ====================================================== */
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.
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();
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
///
int drawString(LyXFont const & font, string const & str,
int baseline, int x);
-
+#endif
/// first visible pixel-row
long first;
/// y is a coordinate of the text
void DrawOneRow(Row * row, long & y_text);
+ ///
+ BufferView * owner;
+
///
LyXText * text;
///
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)
{
{
return font.drawString(str, foreground, baseline, x);
}
+#endif
#endif
class BufferParams;
class LyXScreen;
class Row;
+class BufferView;
/**
This class holds the mapping between buffer paragraphs and screen rows.
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;
/** 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: */
///
///
unsigned short paperWidth() const { return paperwidth; }
private:
+ ///
+ BufferView * owner_;
+
/// width of the paper
unsigned short paperwidth;
///
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;
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
}
/// 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
#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);
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;
}
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) {
} else
mathGC = f.getGC();
}
+#endif
int mathed_string_width(short type, int size, byte const * s, int ls)
// 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);
XDrawString(fl_display, pm, gc, x, y, reinterpret_cast<char*>(s), ls);
XFlush(fl_display);
}
+#endif
InsetFormula::InsetFormula(bool display)
}
+#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
}
cursor_visible = false;
}
+#endif
void InsetFormula::Edit(int x, int y)
}
+#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)
{
font.drawString(name, pm, y, x);
}
}
-
+#endif
void MathFuncInset::Metrics()
{
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;
///
int Width(LyXFont const & font) const;
///
void Draw(LyXFont font, LyXScreen & scr, int baseline, float & x);
+#endif
///
void Write(ostream &);
///
#include "lyxscreen.h"
#include "lyxdraw.h"
#include "gettext.h"
+#include "Painter.h"
InsetFormulaMacro::InsetFormulaMacro()
}
+#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) {
}
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) {
}
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) {
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)
{
x += Width(font) - 1;
}
}
+#endif
void InsetFormulaMacro::Edit(int x, int y)
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;
///
int Width(LyXFont const & font) const;
///
void Draw(LyXFont font, LyXScreen & scr, int baseline, float & x);
+#endif
///
void Read(LyXLex & lex);
///
#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);
}
+#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 << "] ";
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;
MathParInset::pm = win;
par->Draw(x, y);
}
+#endif
bool MathedCursor::Left(bool sel)
}
+#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) {
return &point[0];
}
-
+#endif
void MathedCursor::setAccent(int ac)
///
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();
///
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();
///
///
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; }
///
#include "array.h"
+class Painter;
+
///
enum math_align {
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;
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:
///
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;
///
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 &);
MathedInset * Clone();
///
virtual ~MathMatrixInset();
+#ifdef USE_PAINTER
+ ///
+ void draw(Painter &, int, int);
+#else
///
void Draw(int, int);
+#endif
///
void Write(ostream &);
///
#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:
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;
}
} 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)
{
else
mathed_draw_deco(pm, x, y-ascent, dw, Height(), right);
}
+#endif
+
void
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
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)
{
x += (code == LM_not) ? (width-dw)/2: 2;
mathed_draw_deco(pm, x, y-dy, dw, dh, code);
}
+#endif
+
void
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)
{
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()
#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&);
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)
{
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)
{
XFlush(fl_display);
}
}
+#endif
void
}
+#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()
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)
{
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()
}
+#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)
{
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()
{
width = mathed_string_width(t, size, reinterpret_cast<const unsigned char*>(s), ls);
if (sym == LM_oint) width += 2;
}
+#endif
}
+#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()
~MathFuncInset();
///
MathedInset * Clone();
+#ifdef USE_PAINTER
+ ///
+ void draw(Painter &, int, int);
+#else
///
void Draw(int, int);
+#endif
///
void Write(ostream &);
///
~MathAccentInset();
///
MathedInset * Clone();
+#ifdef USE_PAINTER
+ ///
+ void draw(Painter &, int, int);
+#else
///
void Draw(int, int);
+#endif
///
void Write(ostream &);
///
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 &);
///
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 &);
///
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 &);
///
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 &);
///
~MathFracInset();
///
MathedInset * Clone();
+#ifdef USE_PAINTER
+ ///
+ void draw(Painter &, int x, int baseline);
+#else
///
void Draw(int x, int baseline);
+#endif
///
void Write(ostream &);
///
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 &);
///
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 &);
///
}
+#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;
for (int i = 0; i < nargs; ++i)
tmplate->GetMacroXY(i, args[i].x, args[i].y);
}
+#endif
int MathMacro::GetColumns()
}
+#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) {
drawStr(LM_TC_TEX, size, x, baseline, &s[0], 2);
}
}
+#endif
void MathMacroArgument::Metrics()
}
+#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;
args[i].setExpand(expnd);
}
}
+#endif
void MathMacroTemplate::Metrics()
MathMacro(MathMacro *);
///
~MathMacro();
+#ifdef USE_PAINTER
+ ///
+ void draw(Painter &, int, int);
+#else
///
void Draw(int, int);
+#endif
///
void Metrics();
///
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 &);
///
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();
///
}
+#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;
XFlush(fl_display);
idx = idxp;
}
+#endif
void MathRootInset::SetStyle(short st)
~MathRootInset();
///
MathedInset * Clone();
+#ifdef USE_PAINTER
+ ///
+ void draw(Painter &, int x, int baseline);
+#else
///
void Draw(int x, int baseline);
+#endif
///
void Write(ostream &);
///
{
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 ;
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:
// ale970405
+#ifdef USE_PAINTER
+extern string bibitemWidthest(Painter &);
+#else
extern string bibitemWidthest();
+#endif
// this is a minibuffer
static char minibuffer_char;
<< 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: "
} 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) {
#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)
{
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
}
}
+#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,
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;
y2 - y);
}
}
+#endif
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;
}
/* 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();
expose(0, 0, _width, _height);
}
}
+#endif
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,
cursor_visible = true;
}
} else {
+#endif
if (cursor_pixmap){
XFreePixmap(fl_display, cursor_pixmap);
cursor_pixmap = 0;
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,
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
}
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,
y2+_offset_y);
}
} else {
+#endif
if (cursor_pixmap){
XFreePixmap(fl_display, cursor_pixmap);
cursor_pixmap = 0;
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,
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,
cursor_pixmap_w, cursor_pixmap_h,
cursor_pixmap_x + _offset_x,
cursor_pixmap_y + _offset_y);
+#endif
}
cursor_visible = false;
+#ifndef USE_PAINTER
}
+#endif
}
/* 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
long top = 0;
long bottom = 0;
-
+#ifndef USE_PAINTER
if (fast_selection || mono_video) {
/* selection only in one row ?*/
}
}
} else {
+#endif
top = text->sel_start_cursor.y
- text->sel_start_cursor.row->baseline;
bottom = text->sel_end_cursor.y
text->selection = 0;
DrawFromTo(top - first, bottom - first);
expose(0, top - first, _width, bottom - first - (top - first));
+#ifndef USE_PAINTER
}
+#endif
}
&& text->toggle_cursor.pos == text->toggle_end_cursor.pos)
return;
+#ifndef USE_PAINTER
if (fast_selection || mono_video) {
/* selection only in one row ?*/
}
}
} else {
+#endif
top = text->toggle_cursor.y
- text->toggle_cursor.row->baseline;
bottom = text->toggle_end_cursor.y
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;
x + length,
baseline);
}
+#endif
-
+
+#ifndef USE_PAINTER
void LyXScreen::drawVerticalTableLine(int x, int y1, int y2, bool on_off)
{
GC gc;
x,
y2);
}
+#endif
+#ifndef USE_PAINTER
void LyXScreen::drawFrame(int /*ft*/, int x, int y, int w, int h,
FL_COLOR /*col*/, int /*b*/)
{
fl_gc, pr, 4,
Convex, CoordModeOrigin);
}
+#endif
#include "lyxrc.h"
#include "LyXView.h"
#include "lyxrow.h"
+#include "Painter.h"
using std::max;
using std::min;
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
}
+#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
{
c = 'n';
return font.width(c);
}
+#endif
// Returns the paragraph position of the last character in the specified 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)
{
// 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;
// routines should go here. (Asger)
// Why shouldn't LyXFont::drawText handle it internally?
}
+#endif
// Returns the left beginning of the text.
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
}
}
}
+#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;
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();
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) {
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)
* 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()
/* 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;
/* 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();
}
-// 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)
{
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);
// end of FAST SELECTION code
/* thats it */
}
-
+#endif
int LyXText::DefaultHeight() const
{
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;
}
+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