demos/composition/composition.cpp
changeset 0 1918ee327afb
child 3 41300fa6a67c
equal deleted inserted replaced
-1:000000000000 0:1918ee327afb
       
     1 /****************************************************************************
       
     2 **
       
     3 ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
       
     4 ** All rights reserved.
       
     5 ** Contact: Nokia Corporation (qt-info@nokia.com)
       
     6 **
       
     7 ** This file is part of the demonstration applications of the Qt Toolkit.
       
     8 **
       
     9 ** $QT_BEGIN_LICENSE:LGPL$
       
    10 ** No Commercial Usage
       
    11 ** This file contains pre-release code and may not be distributed.
       
    12 ** You may use this file in accordance with the terms and conditions
       
    13 ** contained in the Technology Preview License Agreement accompanying
       
    14 ** this package.
       
    15 **
       
    16 ** GNU Lesser General Public License Usage
       
    17 ** Alternatively, this file may be used under the terms of the GNU Lesser
       
    18 ** General Public License version 2.1 as published by the Free Software
       
    19 ** Foundation and appearing in the file LICENSE.LGPL included in the
       
    20 ** packaging of this file.  Please review the following information to
       
    21 ** ensure the GNU Lesser General Public License version 2.1 requirements
       
    22 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
       
    23 **
       
    24 ** In addition, as a special exception, Nokia gives you certain additional
       
    25 ** rights.  These rights are described in the Nokia Qt LGPL Exception
       
    26 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
       
    27 **
       
    28 ** If you have questions regarding the use of this file, please contact
       
    29 ** Nokia at qt-info@nokia.com.
       
    30 **
       
    31 **
       
    32 **
       
    33 **
       
    34 **
       
    35 **
       
    36 **
       
    37 **
       
    38 ** $QT_END_LICENSE$
       
    39 **
       
    40 ****************************************************************************/
       
    41 
       
    42 #include "composition.h"
       
    43 #include <QBoxLayout>
       
    44 #include <QRadioButton>
       
    45 #include <QTimer>
       
    46 #include <QDateTime>
       
    47 #include <QSlider>
       
    48 #include <QMouseEvent>
       
    49 #include <qmath.h>
       
    50 
       
    51 CompositionWidget::CompositionWidget(QWidget *parent)
       
    52     : QWidget(parent)
       
    53 {
       
    54     CompositionRenderer *view = new CompositionRenderer(this);
       
    55 
       
    56     QGroupBox *mainGroup = new QGroupBox(parent);
       
    57     mainGroup->setTitle(tr("Composition Modes"));
       
    58 
       
    59     QGroupBox *modesGroup = new QGroupBox(mainGroup);
       
    60     modesGroup->setTitle(tr("Mode"));
       
    61 
       
    62     rbClear = new QRadioButton(tr("Clear"), modesGroup);
       
    63     connect(rbClear, SIGNAL(clicked()), view, SLOT(setClearMode()));
       
    64     rbSource = new QRadioButton(tr("Source"), modesGroup);
       
    65     connect(rbSource, SIGNAL(clicked()), view, SLOT(setSourceMode()));
       
    66     rbDest = new QRadioButton(tr("Destination"), modesGroup);
       
    67     connect(rbDest, SIGNAL(clicked()), view, SLOT(setDestMode()));
       
    68     rbSourceOver = new QRadioButton(tr("Source Over"), modesGroup);
       
    69     connect(rbSourceOver, SIGNAL(clicked()), view, SLOT(setSourceOverMode()));
       
    70     rbDestOver = new QRadioButton(tr("Destination Over"), modesGroup);
       
    71     connect(rbDestOver, SIGNAL(clicked()), view, SLOT(setDestOverMode()));
       
    72     rbSourceIn = new QRadioButton(tr("Source In"), modesGroup);
       
    73     connect(rbSourceIn, SIGNAL(clicked()), view, SLOT(setSourceInMode()));
       
    74     rbDestIn = new QRadioButton(tr("Dest In"), modesGroup);
       
    75     connect(rbDestIn, SIGNAL(clicked()), view, SLOT(setDestInMode()));
       
    76     rbSourceOut = new QRadioButton(tr("Source Out"), modesGroup);
       
    77     connect(rbSourceOut, SIGNAL(clicked()), view, SLOT(setSourceOutMode()));
       
    78     rbDestOut = new QRadioButton(tr("Dest Out"), modesGroup);
       
    79     connect(rbDestOut, SIGNAL(clicked()), view, SLOT(setDestOutMode()));
       
    80     rbSourceAtop = new QRadioButton(tr("Source Atop"), modesGroup);
       
    81     connect(rbSourceAtop, SIGNAL(clicked()), view, SLOT(setSourceAtopMode()));
       
    82     rbDestAtop = new QRadioButton(tr("Dest Atop"), modesGroup);
       
    83     connect(rbDestAtop, SIGNAL(clicked()), view, SLOT(setDestAtopMode()));
       
    84     rbXor = new QRadioButton(tr("Xor"), modesGroup);
       
    85     connect(rbXor, SIGNAL(clicked()), view, SLOT(setXorMode()));
       
    86 
       
    87     rbPlus = new QRadioButton(tr("Plus"), modesGroup);
       
    88     connect(rbPlus, SIGNAL(clicked()), view, SLOT(setPlusMode()));
       
    89     rbMultiply = new QRadioButton(tr("Multiply"), modesGroup);
       
    90     connect(rbMultiply, SIGNAL(clicked()), view, SLOT(setMultiplyMode()));
       
    91     rbScreen = new QRadioButton(tr("Screen"), modesGroup);
       
    92     connect(rbScreen, SIGNAL(clicked()), view, SLOT(setScreenMode()));
       
    93     rbOverlay = new QRadioButton(tr("Overlay"), modesGroup);
       
    94     connect(rbOverlay, SIGNAL(clicked()), view, SLOT(setOverlayMode()));
       
    95     rbDarken = new QRadioButton(tr("Darken"), modesGroup);
       
    96     connect(rbDarken, SIGNAL(clicked()), view, SLOT(setDarkenMode()));
       
    97     rbLighten = new QRadioButton(tr("Lighten"), modesGroup);
       
    98     connect(rbLighten, SIGNAL(clicked()), view, SLOT(setLightenMode()));
       
    99     rbColorDodge = new QRadioButton(tr("Color Dodge"), modesGroup);
       
   100     connect(rbColorDodge, SIGNAL(clicked()), view, SLOT(setColorDodgeMode()));
       
   101     rbColorBurn = new QRadioButton(tr("Color Burn"), modesGroup);
       
   102     connect(rbColorBurn, SIGNAL(clicked()), view, SLOT(setColorBurnMode()));
       
   103     rbHardLight = new QRadioButton(tr("Hard Light"), modesGroup);
       
   104     connect(rbHardLight, SIGNAL(clicked()), view, SLOT(setHardLightMode()));
       
   105     rbSoftLight = new QRadioButton(tr("Soft Light"), modesGroup);
       
   106     connect(rbSoftLight, SIGNAL(clicked()), view, SLOT(setSoftLightMode()));
       
   107     rbDifference = new QRadioButton(tr("Difference"), modesGroup);
       
   108     connect(rbDifference, SIGNAL(clicked()), view, SLOT(setDifferenceMode()));
       
   109     rbExclusion = new QRadioButton(tr("Exclusion"), modesGroup);
       
   110     connect(rbExclusion, SIGNAL(clicked()), view, SLOT(setExclusionMode()));
       
   111 
       
   112     QGroupBox *circleColorGroup = new QGroupBox(mainGroup);
       
   113     circleColorGroup->setTitle(tr("Circle color"));
       
   114     QSlider *circleColorSlider = new QSlider(Qt::Horizontal, circleColorGroup);
       
   115     circleColorSlider->setRange(0, 359);
       
   116     circleColorSlider->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Fixed);
       
   117     connect(circleColorSlider, SIGNAL(valueChanged(int)), view, SLOT(setCircleColor(int)));
       
   118 
       
   119     QGroupBox *circleAlphaGroup = new QGroupBox(mainGroup);
       
   120     circleAlphaGroup->setTitle(tr("Circle alpha"));
       
   121     QSlider *circleAlphaSlider = new QSlider(Qt::Horizontal, circleAlphaGroup);
       
   122     circleAlphaSlider->setRange(0, 255);
       
   123     circleAlphaSlider->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Fixed);
       
   124     connect(circleAlphaSlider, SIGNAL(valueChanged(int)), view, SLOT(setCircleAlpha(int)));
       
   125 
       
   126     QPushButton *showSourceButton = new QPushButton(mainGroup);
       
   127     showSourceButton->setText(tr("Show Source"));
       
   128 #if defined(QT_OPENGL_SUPPORT) && !defined(QT_OPENGL_ES)
       
   129     QPushButton *enableOpenGLButton = new QPushButton(mainGroup);
       
   130     enableOpenGLButton->setText(tr("Use OpenGL"));
       
   131     enableOpenGLButton->setCheckable(true);
       
   132     enableOpenGLButton->setChecked(view->usesOpenGL());
       
   133 
       
   134     if (!QGLFormat::hasOpenGL() || !QGLPixelBuffer::hasOpenGLPbuffers())
       
   135         enableOpenGLButton->hide();
       
   136 #endif
       
   137     QPushButton *whatsThisButton = new QPushButton(mainGroup);
       
   138     whatsThisButton->setText(tr("What's This?"));
       
   139     whatsThisButton->setCheckable(true);
       
   140 
       
   141     QPushButton *animateButton = new QPushButton(mainGroup);
       
   142     animateButton->setText(tr("Animated"));
       
   143     animateButton->setCheckable(true);
       
   144     animateButton->setChecked(true);
       
   145 
       
   146     QHBoxLayout *viewLayout = new QHBoxLayout(this);
       
   147     viewLayout->addWidget(view);
       
   148     viewLayout->addWidget(mainGroup);
       
   149 
       
   150     QVBoxLayout *mainGroupLayout = new QVBoxLayout(mainGroup);
       
   151     mainGroupLayout->addWidget(circleColorGroup);
       
   152     mainGroupLayout->addWidget(circleAlphaGroup);
       
   153     mainGroupLayout->addWidget(modesGroup);
       
   154     mainGroupLayout->addStretch();
       
   155     mainGroupLayout->addWidget(animateButton);
       
   156     mainGroupLayout->addWidget(whatsThisButton);
       
   157     mainGroupLayout->addWidget(showSourceButton);
       
   158 #if defined(QT_OPENGL_SUPPORT) && !defined(QT_OPENGL_ES)
       
   159     mainGroupLayout->addWidget(enableOpenGLButton);
       
   160 #endif
       
   161 
       
   162     QGridLayout *modesLayout = new QGridLayout(modesGroup);
       
   163     modesLayout->addWidget(rbClear,             0,      0);
       
   164     modesLayout->addWidget(rbSource,            1,      0);
       
   165     modesLayout->addWidget(rbDest,              2,      0);
       
   166     modesLayout->addWidget(rbSourceOver,        3,      0);
       
   167     modesLayout->addWidget(rbDestOver,          4,      0);
       
   168     modesLayout->addWidget(rbSourceIn,          5,      0);
       
   169     modesLayout->addWidget(rbDestIn,            6,      0);
       
   170     modesLayout->addWidget(rbSourceOut,         7,      0);
       
   171     modesLayout->addWidget(rbDestOut,           8,      0);
       
   172     modesLayout->addWidget(rbSourceAtop,        9,      0);
       
   173     modesLayout->addWidget(rbDestAtop,         10,      0);
       
   174     modesLayout->addWidget(rbXor,              11,      0);
       
   175 
       
   176     modesLayout->addWidget(rbPlus,              0,      1);
       
   177     modesLayout->addWidget(rbMultiply,          1,      1);
       
   178     modesLayout->addWidget(rbScreen,            2,      1);
       
   179     modesLayout->addWidget(rbOverlay,           3,      1);
       
   180     modesLayout->addWidget(rbDarken,            4,      1);
       
   181     modesLayout->addWidget(rbLighten,           5,      1);
       
   182     modesLayout->addWidget(rbColorDodge,        6,      1);
       
   183     modesLayout->addWidget(rbColorBurn,         7,      1);
       
   184     modesLayout->addWidget(rbHardLight,         8,      1);
       
   185     modesLayout->addWidget(rbSoftLight,         9,      1);
       
   186     modesLayout->addWidget(rbDifference,       10,      1);
       
   187     modesLayout->addWidget(rbExclusion,        11,      1);
       
   188 
       
   189 
       
   190     QVBoxLayout *circleColorLayout = new QVBoxLayout(circleColorGroup);
       
   191     circleColorLayout->addWidget(circleColorSlider);
       
   192 
       
   193     QVBoxLayout *circleAlphaLayout = new QVBoxLayout(circleAlphaGroup);
       
   194     circleAlphaLayout->addWidget(circleAlphaSlider);
       
   195 
       
   196     view->loadDescription(":res/composition/composition.html");
       
   197     view->loadSourceFile(":res/composition/composition.cpp");
       
   198 
       
   199     connect(whatsThisButton, SIGNAL(clicked(bool)), view, SLOT(setDescriptionEnabled(bool)));
       
   200     connect(view, SIGNAL(descriptionEnabledChanged(bool)), whatsThisButton, SLOT(setChecked(bool)));
       
   201     connect(showSourceButton, SIGNAL(clicked()), view, SLOT(showSource()));
       
   202 #if defined(QT_OPENGL_SUPPORT) && !defined(QT_OPENGL_ES)
       
   203     connect(enableOpenGLButton, SIGNAL(clicked(bool)), view, SLOT(enableOpenGL(bool)));
       
   204 #endif
       
   205     connect(animateButton, SIGNAL(toggled(bool)), view, SLOT(setAnimationEnabled(bool)));
       
   206 
       
   207     circleColorSlider->setValue(270);
       
   208     circleAlphaSlider->setValue(200);
       
   209     rbSourceOut->animateClick();
       
   210 
       
   211     setWindowTitle(tr("Composition Modes"));
       
   212 }
       
   213 
       
   214 
       
   215 void CompositionWidget::nextMode()
       
   216 {
       
   217     /*
       
   218       if (!m_animation_enabled)
       
   219       return;
       
   220       if (rbClear->isChecked()) rbSource->animateClick();
       
   221       if (rbSource->isChecked()) rbDest->animateClick();
       
   222       if (rbDest->isChecked()) rbSourceOver->animateClick();
       
   223       if (rbSourceOver->isChecked()) rbDestOver->animateClick();
       
   224       if (rbDestOver->isChecked()) rbSourceIn->animateClick();
       
   225       if (rbSourceIn->isChecked()) rbDestIn->animateClick();
       
   226       if (rbDestIn->isChecked()) rbSourceOut->animateClick();
       
   227       if (rbSourceOut->isChecked()) rbDestOut->animateClick();
       
   228       if (rbDestOut->isChecked()) rbSourceAtop->animateClick();
       
   229       if (rbSourceAtop->isChecked()) rbDestAtop->animateClick();
       
   230       if (rbDestAtop->isChecked()) rbXor->animateClick();
       
   231       if (rbXor->isChecked()) rbClear->animateClick();
       
   232     */
       
   233 }
       
   234 
       
   235 CompositionRenderer::CompositionRenderer(QWidget *parent)
       
   236     : ArthurFrame(parent)
       
   237 {
       
   238     m_animation_enabled = true;
       
   239 #ifdef Q_WS_QWS
       
   240     m_image = QPixmap(":res/composition/flower.jpg");
       
   241     m_image.setAlphaChannel(QPixmap(":res/composition/flower_alpha.jpg"));
       
   242 #else
       
   243     m_image = QImage(":res/composition/flower.jpg");
       
   244     m_image.setAlphaChannel(QImage(":res/composition/flower_alpha.jpg"));
       
   245 #endif
       
   246     m_circle_alpha = 127;
       
   247     m_circle_hue = 255;
       
   248     m_current_object = NoObject;
       
   249     m_composition_mode = QPainter::CompositionMode_SourceOut;
       
   250 
       
   251     m_circle_pos = QPoint(200, 100);
       
   252 
       
   253     setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
       
   254 #ifdef QT_OPENGL_SUPPORT
       
   255     m_pbuffer = 0;
       
   256     m_pbuffer_size = 1024;
       
   257 #endif
       
   258 }
       
   259 
       
   260 QRectF rectangle_around(const QPointF &p, const QSizeF &size = QSize(250, 200))
       
   261 {
       
   262     QRectF rect(p, size);
       
   263     rect.translate(-size.width()/2, -size.height()/2);
       
   264     return rect;
       
   265 }
       
   266 
       
   267 void CompositionRenderer::updateCirclePos()
       
   268 {
       
   269     if (m_current_object != NoObject)
       
   270         return;
       
   271     QDateTime dt = QDateTime::currentDateTime();
       
   272     qreal t = (dt.toTime_t() * 1000 + dt.time().msec()) / 1000.0;
       
   273 
       
   274     qreal x = width() / qreal(2) + (qCos(t*8/11) + qSin(-t)) * width() / qreal(4);
       
   275     qreal y = height() / qreal(2) + (qSin(t*6/7) + qCos(t * qreal(1.5))) * height() / qreal(4);
       
   276 
       
   277     setCirclePos(QLineF(m_circle_pos, QPointF(x, y)).pointAt(0.02));
       
   278 }
       
   279 
       
   280 void CompositionRenderer::drawBase(QPainter &p)
       
   281 {
       
   282     p.setPen(Qt::NoPen);
       
   283 
       
   284     QLinearGradient rect_gradient(0, 0, 0, height());
       
   285     rect_gradient.setColorAt(0, Qt::red);
       
   286     rect_gradient.setColorAt(.17, Qt::yellow);
       
   287     rect_gradient.setColorAt(.33, Qt::green);
       
   288     rect_gradient.setColorAt(.50, Qt::cyan);
       
   289     rect_gradient.setColorAt(.66, Qt::blue);
       
   290     rect_gradient.setColorAt(.81, Qt::magenta);
       
   291     rect_gradient.setColorAt(1, Qt::red);
       
   292     p.setBrush(rect_gradient);
       
   293     p.drawRect(width() / 2, 0, width() / 2, height());
       
   294 
       
   295     QLinearGradient alpha_gradient(0, 0, width(), 0);
       
   296     alpha_gradient.setColorAt(0, Qt::white);
       
   297     alpha_gradient.setColorAt(0.2, Qt::white);
       
   298     alpha_gradient.setColorAt(0.5, Qt::transparent);
       
   299     alpha_gradient.setColorAt(0.8, Qt::white);
       
   300     alpha_gradient.setColorAt(1, Qt::white);
       
   301 
       
   302     p.setCompositionMode(QPainter::CompositionMode_DestinationIn);
       
   303     p.setBrush(alpha_gradient);
       
   304     p.drawRect(0, 0, width(), height());
       
   305 
       
   306     p.setCompositionMode(QPainter::CompositionMode_DestinationOver);
       
   307 
       
   308     p.setPen(Qt::NoPen);
       
   309     p.setRenderHint(QPainter::SmoothPixmapTransform);
       
   310 #ifdef Q_WS_QWS
       
   311     p.drawPixmap(rect(), m_image);
       
   312 #else
       
   313     p.drawImage(rect(), m_image);
       
   314 #endif
       
   315 }
       
   316 
       
   317 void CompositionRenderer::drawSource(QPainter &p)
       
   318 {
       
   319     p.setPen(Qt::NoPen);
       
   320     p.setRenderHint(QPainter::Antialiasing);
       
   321     p.setCompositionMode(m_composition_mode);
       
   322 
       
   323     QRectF circle_rect = rectangle_around(m_circle_pos);
       
   324     QColor color = QColor::fromHsvF(m_circle_hue / 360.0, 1, 1, m_circle_alpha / 255.0);
       
   325     QLinearGradient circle_gradient(circle_rect.topLeft(), circle_rect.bottomRight());
       
   326     circle_gradient.setColorAt(0, color.light());
       
   327     circle_gradient.setColorAt(0.5, color);
       
   328     circle_gradient.setColorAt(1, color.dark());
       
   329     p.setBrush(circle_gradient);
       
   330 
       
   331     p.drawEllipse(circle_rect);
       
   332 }
       
   333 
       
   334 void CompositionRenderer::paint(QPainter *painter)
       
   335 {
       
   336 #if defined(QT_OPENGL_SUPPORT) && !defined(QT_OPENGL_ES)
       
   337     if (usesOpenGL()) {
       
   338 
       
   339         int new_pbuf_size = m_pbuffer_size;
       
   340         if (size().width() > m_pbuffer_size ||
       
   341             size().height() > m_pbuffer_size)
       
   342             new_pbuf_size *= 2;
       
   343 
       
   344         if (size().width() < m_pbuffer_size/2 &&
       
   345             size().height() < m_pbuffer_size/2)
       
   346             new_pbuf_size /= 2;
       
   347 
       
   348         if (!m_pbuffer || new_pbuf_size != m_pbuffer_size) {
       
   349             if (m_pbuffer) {
       
   350                 m_pbuffer->deleteTexture(m_base_tex);
       
   351                 m_pbuffer->deleteTexture(m_compositing_tex);
       
   352                 delete m_pbuffer;
       
   353             }
       
   354 
       
   355             m_pbuffer = new QGLPixelBuffer(QSize(new_pbuf_size, new_pbuf_size), QGLFormat::defaultFormat(), glWidget());
       
   356             m_pbuffer->makeCurrent();
       
   357             m_base_tex = m_pbuffer->generateDynamicTexture();
       
   358             m_compositing_tex = m_pbuffer->generateDynamicTexture();
       
   359             m_pbuffer_size = new_pbuf_size;
       
   360         }
       
   361 
       
   362         if (size() != m_previous_size) {
       
   363             m_previous_size = size();
       
   364             QPainter p(m_pbuffer);
       
   365             p.setCompositionMode(QPainter::CompositionMode_Source);
       
   366             p.fillRect(QRect(0, 0, m_pbuffer->width(), m_pbuffer->height()), Qt::transparent);
       
   367             drawBase(p);
       
   368             p.end();
       
   369             m_pbuffer->updateDynamicTexture(m_base_tex);
       
   370         }
       
   371 
       
   372         qreal x_fraction = width()/float(m_pbuffer->width());
       
   373         qreal y_fraction = height()/float(m_pbuffer->height());
       
   374 
       
   375         {
       
   376             QPainter p(m_pbuffer);
       
   377             p.setCompositionMode(QPainter::CompositionMode_Source);
       
   378             p.fillRect(QRect(0, 0, m_pbuffer->width(), m_pbuffer->height()), Qt::transparent);
       
   379 
       
   380             p.save(); // Needed when using the GL1 engine
       
   381             p.beginNativePainting(); // Needed when using the GL2 engine
       
   382 
       
   383             glBindTexture(GL_TEXTURE_2D, m_base_tex);
       
   384             glEnable(GL_TEXTURE_2D);
       
   385             glColor4f(1.,1.,1.,1.);
       
   386 
       
   387             glBegin(GL_QUADS);
       
   388             {
       
   389                 glTexCoord2f(0, 1.0);
       
   390                 glVertex2f(0, 0);
       
   391 
       
   392                 glTexCoord2f(x_fraction, 1.0);
       
   393                 glVertex2f(width(), 0);
       
   394 
       
   395                 glTexCoord2f(x_fraction, 1.0-y_fraction);
       
   396                 glVertex2f(width(), height());
       
   397 
       
   398                 glTexCoord2f(0, 1.0-y_fraction);
       
   399                 glVertex2f(0, height());
       
   400             }
       
   401             glEnd();
       
   402 
       
   403             glDisable(GL_TEXTURE_2D);
       
   404 
       
   405             p.endNativePainting(); // Needed when using the GL2 engine
       
   406             p.restore(); // Needed when using the GL1 engine
       
   407 
       
   408             drawSource(p);
       
   409             p.end();
       
   410             m_pbuffer->updateDynamicTexture(m_compositing_tex);
       
   411         }
       
   412 
       
   413         painter->beginNativePainting(); // Needed when using the GL2 engine
       
   414         glWidget()->makeCurrent(); // Needed when using the GL1 engine
       
   415         glBindTexture(GL_TEXTURE_2D, m_compositing_tex);
       
   416         glEnable(GL_TEXTURE_2D);
       
   417         glEnable(GL_BLEND);
       
   418         glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
       
   419         glColor4f(1.,1.,1.,1.);
       
   420         glBegin(GL_QUADS);
       
   421         {
       
   422             glTexCoord2f(0, 1.0);
       
   423             glVertex2f(0, 0);
       
   424 
       
   425             glTexCoord2f(x_fraction, 1.0);
       
   426             glVertex2f(width(), 0);
       
   427 
       
   428             glTexCoord2f(x_fraction, 1.0-y_fraction);
       
   429             glVertex2f(width(), height());
       
   430 
       
   431             glTexCoord2f(0, 1.0-y_fraction);
       
   432             glVertex2f(0, height());
       
   433         }
       
   434         glEnd();
       
   435         glDisable(GL_TEXTURE_2D);
       
   436         painter->endNativePainting(); // Needed when using the GL2 engine
       
   437     } else
       
   438 #endif
       
   439     {
       
   440         // using a QImage
       
   441         if (m_buffer.size() != size()) {
       
   442 #ifdef Q_WS_QWS
       
   443             m_base_buffer = QPixmap(size());
       
   444             m_base_buffer.fill(Qt::transparent);
       
   445 #else
       
   446             m_buffer = QImage(size(), QImage::Format_ARGB32_Premultiplied);
       
   447             m_base_buffer = QImage(size(), QImage::Format_ARGB32_Premultiplied);
       
   448 
       
   449             m_base_buffer.fill(0);
       
   450 #endif
       
   451 
       
   452             QPainter p(&m_base_buffer);
       
   453 
       
   454             drawBase(p);
       
   455         }
       
   456 
       
   457 #ifdef Q_WS_QWS
       
   458         m_buffer = m_base_buffer;
       
   459 #else
       
   460         memcpy(m_buffer.bits(), m_base_buffer.bits(), m_buffer.numBytes());
       
   461 #endif
       
   462 
       
   463         {
       
   464             QPainter p(&m_buffer);
       
   465             drawSource(p);
       
   466         }
       
   467 
       
   468 #ifdef Q_WS_QWS
       
   469         painter->drawPixmap(0, 0, m_buffer);
       
   470 #else
       
   471         painter->drawImage(0, 0, m_buffer);
       
   472 #endif
       
   473     }
       
   474 
       
   475     if (m_animation_enabled && m_current_object == NoObject) {
       
   476         updateCirclePos();
       
   477     }
       
   478 }
       
   479 
       
   480 void CompositionRenderer::mousePressEvent(QMouseEvent *e)
       
   481 {
       
   482     setDescriptionEnabled(false);
       
   483 
       
   484     QRectF circle = rectangle_around(m_circle_pos);
       
   485 
       
   486     if (circle.contains(e->pos())) {
       
   487         m_current_object = Circle;
       
   488         m_offset = circle.center() - e->pos();
       
   489     } else {
       
   490         m_current_object = NoObject;
       
   491     }
       
   492 }
       
   493 
       
   494 void CompositionRenderer::mouseMoveEvent(QMouseEvent *e)
       
   495 {
       
   496     if (m_current_object == Circle) setCirclePos(e->pos() + m_offset);
       
   497 }
       
   498 
       
   499 void CompositionRenderer::mouseReleaseEvent(QMouseEvent *)
       
   500 {
       
   501     m_current_object = NoObject;
       
   502 
       
   503     if (m_animation_enabled)
       
   504         updateCirclePos();
       
   505 }
       
   506 
       
   507 void CompositionRenderer::setCirclePos(const QPointF &pos)
       
   508 {
       
   509     const QRect oldRect = rectangle_around(m_circle_pos).toAlignedRect();
       
   510     m_circle_pos = pos;
       
   511     const QRect newRect = rectangle_around(m_circle_pos).toAlignedRect();
       
   512 #if defined(QT_OPENGL_SUPPORT) && !defined(QT_OPENGL_ES)
       
   513     if (usesOpenGL())
       
   514         update();
       
   515     else
       
   516 #endif
       
   517         update(oldRect | newRect);
       
   518 }
       
   519