From 4a5053d34e8ace31de50f19e530da51dd99f55e4 Mon Sep 17 00:00:00 2001 From: Abdelrazak Younes Date: Mon, 20 Mar 2006 10:43:21 +0000 Subject: [PATCH] * qscreen.[Ch]: - Cursor handing is done on the server -> *cursor are QPixmap - Use new drawScreen and copyScreen methods. * QWorkArea.[Ch]: - Pixel manipulation is done on the client -> paint_device_ is a QImage - an intermediate Screen device is updated whenever expose is called -> sreen_device_ is a QPixmap. This screen_device is the one that is painted on screen in QWorkArea::repaintEvent(). - new update, drawScreen and copyScreen methods. * QLPainter.C: use the new paintDevice interface. git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/trunk@13428 a592a061-630c-0410-9148-cb99ea01b6c8 --- src/frontends/qt4/QLPainter.C | 70 ++++++++--------------------- src/frontends/qt4/QLPainter.h | 23 ++++++---- src/frontends/qt4/QWorkArea.C | 39 +++++++++++++--- src/frontends/qt4/QWorkArea.h | 38 +++++++++------- src/frontends/qt4/qscreen.C | 85 ++++++++++++----------------------- src/frontends/qt4/qscreen.h | 20 ++++----- 6 files changed, 126 insertions(+), 149 deletions(-) diff --git a/src/frontends/qt4/QLPainter.C b/src/frontends/qt4/QLPainter.C index 877f07fde9..3c0b334e6a 100644 --- a/src/frontends/qt4/QLPainter.C +++ b/src/frontends/qt4/QLPainter.C @@ -39,21 +39,10 @@ QLPainter::~QLPainter() } QLPainter::QLPainter(QWorkArea * qwa) - : Painter(), paint_check_(0), qwa_(qwa) + : Painter(), qwa_(qwa) { } -void QLPainter::start() -{ -} - - -void QLPainter::end() -{ -// if (qp_->isActive()) -// qp_->end(); -} - int QLPainter::paperWidth() const { @@ -66,29 +55,6 @@ int QLPainter::paperHeight() const return qwa_->viewport()->height(); } -/* -QPainter & QLPainter::setPen(LColor_color c, - Painter::line_style ls, Painter::line_width lw) -{ - QPen pen = qp_->pen(); - - pen.setColor(lcolorcache.get(c)); - - switch (ls) { - case line_solid: pen.setStyle(Qt::SolidLine); break; - case line_onoffdash: pen.setStyle(Qt::DotLine); break; - } - - switch (lw) { - case line_thin: pen.setWidth(0); break; - case line_thick: pen.setWidth(3); break; - } - - qp_->setPen(pen); - - return *qp_; -} -*/ QPainter & QLPainter::setQPainterPen(QPainter & qp, LColor_color c, Painter::line_style ls, Painter::line_width lw) { @@ -113,7 +79,7 @@ QPainter & QLPainter::setQPainterPen(QPainter & qp, LColor_color c, void QLPainter::point(int x, int y, LColor_color c) { - QPainter qp(qwa_->pixmap()); + QPainter qp(qwa_->paintDevice()); setQPainterPen(qp, c).drawPoint(x, y); } @@ -123,7 +89,7 @@ void QLPainter::line(int x1, int y1, int x2, int y2, line_style ls, line_width lw) { - QPainter qp(qwa_->pixmap()); + QPainter qp(qwa_->paintDevice()); setQPainterPen(qp, col, ls, lw).drawLine(x1, y1, x2, y2); } @@ -143,7 +109,7 @@ void QLPainter::lines(int const * xp, int const * yp, int np, points[i].setY(yp[i]); } - QPainter qp(qwa_->pixmap()); + QPainter qp(qwa_->paintDevice()); setQPainterPen(qp, col, ls, lw).drawPolyline(points.get(), np); } @@ -153,18 +119,14 @@ void QLPainter::rectangle(int x, int y, int w, int h, line_style ls, line_width lw) { - QPainter qp(qwa_->pixmap()); + QPainter qp(qwa_->paintDevice()); setQPainterPen(qp, col, ls, lw).drawRect(x, y, w, h); } void QLPainter::fillRectangle(int x, int y, int w, int h, LColor_color col) { -// lyxerr[Debug::GRAPHICS] << BOOST_CURRENT_FUNCTION -// << "\nx=" << x << " y=" << y << " w=" << w << " h=" << h -// << " LColor " << col << endl; - - QPainter qp(qwa_->pixmap()); + QPainter qp(qwa_->paintDevice()); qp.fillRect(x, y, w, h, lcolorcache.get(col)); } @@ -180,7 +142,7 @@ void QLPainter::fillPolygon(int const * xp, int const * yp, points[i].setY(yp[i]); } - QPainter qp(qwa_->pixmap()); + QPainter qp(qwa_->paintDevice()); setQPainterPen(qp, col); qp.setBrush(lcolorcache.get(col)); qp.drawPolygon(points.get(), np); @@ -192,7 +154,7 @@ void QLPainter::arc(int x, int y, unsigned int w, unsigned int h, int a1, int a2, LColor_color col) { // LyX usings 1/64ths degree, Qt usings 1/16th - QPainter qp(qwa_->pixmap()); + QPainter qp(qwa_->paintDevice()); setQPainterPen(qp, col).drawArc(x, y, w, h, a1 / 4, a2 / 4); } @@ -205,7 +167,7 @@ void QLPainter::image(int x, int y, int w, int h, fillRectangle(x, y, w, h, LColor::graphicsbg); - QPainter qp(qwa_->pixmap()); + QPainter qp(qwa_->paintDevice()); qp.drawImage(x, y, qlimage.qimage(), 0, 0, w, h); } @@ -234,7 +196,7 @@ void QLPainter::smallCapsText(int x, int y, QFontMetrics const & qfontm = QFontMetrics(qfont); QFontMetrics const & qsmallfontm = QFontMetrics(qsmallfont); - QPainter qp(qwa_->pixmap()); + QPainter qp(qwa_->paintDevice()); int tmpx = x; size_t ls = s.length(); for (size_t i = 0; i < ls; ++i) { @@ -256,7 +218,7 @@ void QLPainter::smallCapsText(int x, int y, void QLPainter::text(int x, int y, char const * s, size_t ls, LyXFont const & f) { - QPainter qp(qwa_->pixmap()); + QPainter qp(qwa_->paintDevice()); setQPainterPen(qp, f.realColor()); Encoding const * encoding = f.language()->encoding(); @@ -288,8 +250,14 @@ void QLPainter::text(int x, int y, char const * s, size_t ls, } /// draw a pixmap from the image cache -void QLPainter::pixmap(int x, int y, QPixmap const & pixmap) +void QLPainter::drawPixmap(int x, int y, QPixmap const & pixmap) { - QPainter qp(qwa_->pixmap()); + QPainter qp(qwa_->paintDevice()); qp.drawPixmap(x, y, pixmap); } + +void QLPainter::drawImage(int x, int y, QImage const & image) +{ + QPainter qp(qwa_->paintDevice()); + qp.drawImage(x, y, image); +} diff --git a/src/frontends/qt4/QLPainter.h b/src/frontends/qt4/QLPainter.h index 0e4ad5651f..6a9f7a0dc8 100644 --- a/src/frontends/qt4/QLPainter.h +++ b/src/frontends/qt4/QLPainter.h @@ -21,7 +21,8 @@ class LyXFont; class QPaintDevice; class QPainter; class QString; -class QPixmap; +class QPixmap; +class QImage; class QWorkArea; /** @@ -33,11 +34,17 @@ public: ~QLPainter(); - /// begin painting - virtual void start(); + /// begin painting + /** + Not used in the the Qt4 frontend. + */ + virtual void start() {} /// end painting - virtual void end(); + /** + Not used in the the Qt4 frontend. + */ + virtual void end() {} /// return the width of the work area in pixels virtual int paperWidth() const; @@ -120,8 +127,11 @@ public: char c, LyXFont const & f); /// draw a pixmap from the image cache - virtual void pixmap(int x, int y, QPixmap const & pixmap); + virtual void drawPixmap(int x, int y, QPixmap const & pixmap); + /// draw a pixmap from the image cache + virtual void drawImage(int x, int y, QImage const & image); + private: /// draw small caps text void smallCapsText(int x, int y, @@ -135,9 +145,6 @@ private: /// our qt painter boost::scoped_ptr qp_; - /// recursion check - int paint_check_; - /// the working area QWorkArea * qwa_; }; diff --git a/src/frontends/qt4/QWorkArea.C b/src/frontends/qt4/QWorkArea.C index c438ca0ee5..998ca295b5 100644 --- a/src/frontends/qt4/QWorkArea.C +++ b/src/frontends/qt4/QWorkArea.C @@ -492,10 +492,12 @@ void QWorkArea::resizeEvent(QResizeEvent * resizeEvent) verticalScrollBar()->setPageStep(viewport()->height()); - pixmap_.reset(new QPixmap(viewport()->width(), viewport()->height())); + screen_device_ = QPixmap(viewport()->width(), viewport()->height()); + paint_device_ = QImage(viewport()->width(), viewport()->height(), QImage::Format_RGB32); this->workAreaResize(); - + + /* lyxerr[Debug::GUI] << BOOST_CURRENT_FUNCTION << "\n QWidget width\t" << this->QWidget::width() << "\n QWidget height\t" << this->QWidget::height() @@ -503,11 +505,22 @@ void QWorkArea::resizeEvent(QResizeEvent * resizeEvent) << "\n viewport height\t" << viewport()->height() << "\n QResizeEvent rect left\t" << rect().left() << "\n QResizeEvent rect right\t" << rect().right() - << endl; + << endl; + */ } +void QWorkArea::update(int x, int y, int w, int h) +{ + //screen_device_.fromImage(paint_device_); + QPainter q(&screen_device_); + q.drawImage(x, y, paint_device_.copy(x, y, w, h)); + + viewport()->update(x, y, w, h); +} + void QWorkArea::paintEvent(QPaintEvent * e) -{ +{ + /* lyxerr[Debug::GUI] << BOOST_CURRENT_FUNCTION << "\n QWidget width\t" << this->width() << "\n QWidget height\t" << this->height() @@ -519,11 +532,23 @@ void QWorkArea::paintEvent(QPaintEvent * e) << "\n QPaintEvent y\t" << e->rect().y() << "\n QPaintEvent w\t" << e->rect().width() << "\n QPaintEvent h\t" << e->rect().height() - << endl; - + << endl; + */ QPainter q(viewport()); - q.drawPixmap(e->rect(), *pixmap_.get(), e->rect()); + q.drawPixmap(e->rect(), screen_device_, e->rect()); } + +QPixmap QWorkArea::copyScreen(int x, int y, int w, int h) const +{ + return screen_device_.copy(x, y, w, h); +} + +void QWorkArea::drawScreen(int x, int y, QPixmap pixmap) +{ + QPainter q(&screen_device_); + q.drawPixmap(x, y, pixmap); + viewport()->update(x, y, pixmap.width(), pixmap.height()); +} /////////////////////////////////////////////////////////////// diff --git a/src/frontends/qt4/QWorkArea.h b/src/frontends/qt4/QWorkArea.h index aa1cf5b89c..a419ceb43d 100644 --- a/src/frontends/qt4/QWorkArea.h +++ b/src/frontends/qt4/QWorkArea.h @@ -22,13 +22,13 @@ #undef emit #endif -#include "funcrequest.h" -#include "frontends/Timeout.h" - #include "WorkArea.h" #include "QLPainter.h" #include "LyXView.h" +#include "funcrequest.h" +#include "frontends/Timeout.h" + #include #include #include @@ -36,8 +36,8 @@ #include #include #include - -#include +#include +#include #include @@ -130,18 +130,21 @@ public: /// return the widget's painter virtual Painter & getPainter() { return (Painter &) painter_; } - /// - //virtual QPaintDevice & paintDevice() { return content_->pixmap(); } - /// return the backing pixmap - QPixmap * pixmap() const { return pixmap_.get(); } + QPaintDevice * paintDevice() { return &paint_device_; } + + /// update the passed area. + void update(int x, int y, int w, int h); - /// return the widget's painter - //virtual QLPainter & getQLPainter() const { return painter_; } - - /// get the content pane widget - QWidget * getContent() const { return viewport(); } + /// return a screen copy of the defined area. + QPixmap copyScreen(int x, int y, int w, int h) const; + /// Draw a pixmap onto the backing pixmap. + /** + QPixmap is implicitely shared so no need to pass by reference. + */ + void drawScreen(int x, int y, QPixmap pixmap); + protected: /// repaint part of the widget @@ -198,9 +201,12 @@ private: /// SyntheticMouseEvent synthetic_mouse_event_; - /// the double buffered pixmap - boost::scoped_ptr pixmap_; + /// Our client side painting device. + QImage paint_device_; + /// Our server side painting device. + QPixmap screen_device_; + /// \todo remove QTimer step_timer_; diff --git a/src/frontends/qt4/qscreen.C b/src/frontends/qt4/qscreen.C index 460a0118ba..48a9a8a291 100644 --- a/src/frontends/qt4/qscreen.C +++ b/src/frontends/qt4/qscreen.C @@ -9,19 +9,18 @@ * Full author contact details are available in file CREDITS. */ -#include - -#include "QWorkArea.h" -#include "qscreen.h" -//Added by qt3to4: -#include -#include - -#include "debug.h" -#include "lcolorcache.h" +#include +#include "QWorkArea.h" +#include "qscreen.h" + +#include +#include #include +#include "debug.h" +#include "lcolorcache.h" + namespace { @@ -29,7 +28,7 @@ namespace { QScreen::QScreen(QWorkArea & o) - : LyXScreen(), owner_(o), nocursor_pixmap_(0,0) + : LyXScreen(), owner_(o), nocursor_(0,0) { } @@ -46,13 +45,12 @@ WorkArea & QScreen::workarea() const void QScreen::expose(int x, int y, int w, int h) { - lyxerr[Debug::GUI] << "expose " << w << 'x' << h << '+' << x << '+' << y << std::endl; + lyxerr[Debug::GUI] << "expose " << w << 'x' << h + << '+' << x << '+' << y << std::endl; - owner_.viewport()->update(x, y, w, h); -// owner_.update(); + owner_.update(x, y, w, h); } - void QScreen::showCursor(int x, int y, int h, Cursor_Shape shape) { if (!qApp->focusWidget()) @@ -60,11 +58,7 @@ void QScreen::showCursor(int x, int y, int h, Cursor_Shape shape) if (x==cursor_x_ && y==cursor_y_ && h==cursor_h_) { // Draw the new (vertical) cursor using the cached store. - QLPainter * lp = (QLPainter *) &(owner_.getPainter()); - lp->pixmap(cursor_x_, cursor_y_, vcursor_pixmap_); - owner_.viewport()->update( - cursor_x_, cursor_y_, - cursor_w_, cursor_h_); + owner_.drawScreen(cursor_x_, cursor_y_, vcursor_); return; } @@ -91,46 +85,34 @@ void QScreen::showCursor(int x, int y, int h, Cursor_Shape shape) // 1 the rectangle of the original screen. // 2 the vertical line of the cursor. // 3 the horizontal line of the L-shaped cursor (if necessary). - - // Initialise storage for these pixmaps as necessary. - if (cursor_w_ != nocursor_pixmap_.width() || - cursor_h_ != nocursor_pixmap_.height()) { - nocursor_pixmap_.resize(cursor_w_, cursor_h_); - } - + QColor const & required_color = lcolorcache.get(LColor::cursor); bool const cursor_color_changed = required_color != cursor_color_; if (cursor_color_changed) - cursor_color_ = required_color; - -// if (cursor_h_ != vcursor_pixmap_.height() || cursor_color_changed) { -// if (cursor_h_ != vcursor_pixmap_.height()) - vcursor_pixmap_.resize(cursor_w_, cursor_h_); - vcursor_pixmap_.fill(cursor_color_); -// } + cursor_color_ = required_color; + + vcursor_ = QPixmap(cursor_w_, cursor_h_); + vcursor_ .fill(cursor_color_); switch (shape) { case BAR_SHAPE: break; case REVERSED_L_SHAPE: case L_SHAPE: - if (cursor_w_ != hcursor_pixmap_.width() || + if (cursor_w_ != hcursor_.width() || cursor_color_changed) { - if (cursor_w_ != hcursor_pixmap_.width()) - hcursor_pixmap_.resize(cursor_w_, 1); - hcursor_pixmap_.fill(cursor_color_); + if (cursor_w_ != hcursor_.width()) + hcursor_ = QPixmap(cursor_w_, 1); + hcursor_.fill(cursor_color_); } break; } - // Save the old area (no cursor). - QPainter qp(&nocursor_pixmap_); - qp.drawPixmap(0, 0, *owner_.pixmap(), - cursor_x_, cursor_y_, cursor_w_, cursor_h_); + // Save the old area (no cursor). + nocursor_ = owner_.copyScreen(cursor_x_, cursor_y_, cursor_w_, cursor_h_); // Draw the new (vertical) cursor using the cached store. - QLPainter * lp = (QLPainter *) &(owner_.getPainter()); - lp->pixmap(cursor_x_, cursor_y_, vcursor_pixmap_); + owner_.drawScreen(cursor_x_, cursor_y_, vcursor_); // Draw the new (horizontal) cursor if necessary. switch (shape) { @@ -138,26 +120,17 @@ void QScreen::showCursor(int x, int y, int h, Cursor_Shape shape) break; case REVERSED_L_SHAPE: case L_SHAPE: - lp->pixmap(cursor_x_, y + h - 1, hcursor_pixmap_); + owner_.drawScreen(cursor_x_, y + h - 1, hcursor_); break; } - - owner_.viewport()->update( - cursor_x_, cursor_y_, - cursor_w_, cursor_h_); } void QScreen::removeCursor() { // before first showCursor - if (nocursor_pixmap_.isNull()) + if (nocursor_.isNull()) return; - QLPainter * lp = (QLPainter *) &(owner_.getPainter()); - lp->pixmap(cursor_x_, cursor_y_, nocursor_pixmap_); - - owner_.viewport()->update( - cursor_x_, cursor_y_, - cursor_w_, cursor_h_); + owner_.drawScreen(cursor_x_, cursor_y_, nocursor_); } diff --git a/src/frontends/qt4/qscreen.h b/src/frontends/qt4/qscreen.h index 7e9ea46fc5..4e6af549ba 100644 --- a/src/frontends/qt4/qscreen.h +++ b/src/frontends/qt4/qscreen.h @@ -4,7 +4,7 @@ * This file is part of LyX, the document processor. * Licence details can be found in the file COPYING. * - * \author John Levon + * \author John Levon * * Full author contact details are available in file CREDITS. */ @@ -12,10 +12,12 @@ #ifndef QSCREEN_H #define QSCREEN_H -#include "screen.h" -#include + +#include "screen.h" -#include +#include + +class QColor; class QWorkArea; class WorkArea; @@ -47,13 +49,9 @@ private: /// our owning widget QWorkArea & owner_; -// QRegion nocursor_region_; -// QRegion hcursor_region_; -// QRegion vcursor_region_; - - QPixmap nocursor_pixmap_; - QPixmap hcursor_pixmap_; - QPixmap vcursor_pixmap_; + QPixmap nocursor_; + QPixmap hcursor_; + QPixmap vcursor_; //@{ the cursor pixmap position/size int cursor_x_;