[cairo-commit] cairo-demo/qcairo .cvsignore, 1.1, 1.2 ChangeLog, NONE, 1.1 controlwidgetbase.ui, 1.1, 1.2 mainwindow.cpp, 1.1, 1.2 mainwindow.h, 1.1, 1.2 qcairo.cpp, 1.1, NONE qcairo.h, 1.1, NONE qcairo.pro, 1.1, 1.2 qcairowidget.cpp, NONE, 1.1 qcairowidget.h, NONE, 1.1 qkapow.cpp, NONE, 1.1 qkapow.h, NONE, 1.1

Carl Worth commit at pdx.freedesktop.org
Fri Jul 1 12:49:09 PDT 2005


Committed by: cworth

Update of /cvs/cairo/cairo-demo/qcairo
In directory gabe:/tmp/cvs-serv16108

Modified Files:
	.cvsignore controlwidgetbase.ui mainwindow.cpp mainwindow.h 
	qcairo.pro 
Added Files:
	ChangeLog qcairowidget.cpp qcairowidget.h qkapow.cpp qkapow.h 
Removed Files:
	qcairo.cpp qcairo.h 
Log Message:

        From 2005-01-25 Zack Rusin <zack at kde.org>:

        * .cvsignore:
        * controlwidgetbase.ui:
        * mainwindow.cpp:
        * mainwindow.h:
        * qcairo.cpp:
        * qcairo.h:
        * qcairo.pro:
        * qcairowidget.cpp:
        * qcairowidget.h:
        * qkapow.cpp:
        * qkapow.h:

        1) I created a QCairoWidget which has a
        virtual void cairoPaint(cairo_t *)
        method which essentially replaces the QWidget::paintEvent. It's done
        essentially to enable people to just take the widget, stick it in their
        app and just use Cairo (either duble-buffered or not).
        2) Instead of the old demo code it uses now kapow. It's a little bit
        more attractive and nicely shows how to use QCairoWidget.


Index: .cvsignore
===================================================================
RCS file: /cvs/cairo/cairo-demo/qcairo/.cvsignore,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -d -r1.1 -r1.2
--- .cvsignore	25 Jan 2005 20:57:21 -0000	1.1
+++ .cvsignore	1 Jul 2005 19:49:07 -0000	1.2
@@ -1,2 +1,6 @@
 Makefile
 qcairo
+.tmp
+controlwidgetbase.cpp
+controlwidgetbase.h
+

--- NEW FILE: ChangeLog ---
2005-07-01  Carl Worth  <cworth at cworth.org>

	From 2005-01-25 Zack Rusin <zack at kde.org>:

	* .cvsignore:
	* controlwidgetbase.ui:
	* mainwindow.cpp:
	* mainwindow.h:
	* qcairo.cpp:
	* qcairo.h:
	* qcairo.pro:
	* qcairowidget.cpp:
	* qcairowidget.h:
	* qkapow.cpp:
	* qkapow.h:

	1) I created a QCairoWidget which has a
	virtual void cairoPaint(cairo_t *)
	method which essentially replaces the QWidget::paintEvent. It's done
	essentially to enable people to just take the widget, stick it in their
	app and just use Cairo (either duble-buffered or not).
	2) Instead of the old demo code it uses now kapow. It's a little bit
	more attractive and nicely shows how to use QCairoWidget.
	

Index: controlwidgetbase.ui
===================================================================
RCS file: /cvs/cairo/cairo-demo/qcairo/controlwidgetbase.ui,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -d -r1.1 -r1.2
--- controlwidgetbase.ui	25 Jan 2005 20:24:22 -0000	1.1
+++ controlwidgetbase.ui	1 Jul 2005 19:49:07 -0000	1.2
@@ -21,6 +21,29 @@
         </property>
         <widget class="QLayoutWidget">
             <property name="name">
+                <cstring>layout3</cstring>
+            </property>
+            <hbox>
+                <property name="name">
+                    <cstring>unnamed</cstring>
+                </property>
+                <widget class="QLabel">
+                    <property name="name">
+                        <cstring>textLabel1</cstring>
+                    </property>
+                    <property name="text">
+                        <string>Text:</string>
+                    </property>
+                </widget>
+                <widget class="QLineEdit">
+                    <property name="name">
+                        <cstring>m_textEdit</cstring>
+                    </property>
+                </widget>
+            </hbox>
+        </widget>
+        <widget class="QLayoutWidget">
+            <property name="name">
                 <cstring>layout2</cstring>
             </property>
             <hbox>
@@ -32,19 +55,19 @@
                         <cstring>textLabel1_2</cstring>
                     </property>
                     <property name="text">
-                        <string>Base length:</string>
+                        <string>Width:</string>
                     </property>
                 </widget>
                 <widget class="QSpinBox">
                     <property name="name">
-                        <cstring>m_baseSpin</cstring>
+                        <cstring>m_width</cstring>
                     </property>
                 </widget>
             </hbox>
         </widget>
         <widget class="QLayoutWidget">
             <property name="name">
-                <cstring>layout1</cstring>
+                <cstring>layout3</cstring>
             </property>
             <hbox>
                 <property name="name">
@@ -52,18 +75,15 @@
                 </property>
                 <widget class="QLabel">
                     <property name="name">
-                        <cstring>textLabel1</cstring>
+                        <cstring>textLabel2</cstring>
                     </property>
                     <property name="text">
-                        <string>Line width:</string>
-                    </property>
-                    <property name="buddy" stdset="0">
-                        <cstring>m_lineSpin</cstring>
+                        <string>Height:</string>
                     </property>
                 </widget>
                 <widget class="QSpinBox">
                     <property name="name">
-                        <cstring>m_lineSpin</cstring>
+                        <cstring>m_height</cstring>
                     </property>
                 </widget>
             </hbox>

Index: mainwindow.cpp
===================================================================
RCS file: /cvs/cairo/cairo-demo/qcairo/mainwindow.cpp,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -d -r1.1 -r1.2
--- mainwindow.cpp	25 Jan 2005 20:24:22 -0000	1.1
+++ mainwindow.cpp	1 Jul 2005 19:49:07 -0000	1.2
@@ -1,11 +1,13 @@
 #include "mainwindow.h"
 
 #include "controlwidgetbase.h"
-#include "qcairo.h"
+#include "qkapow.h"
 
 #include <qapplication.h>
-#include <qdockwindow.h>
+#include <qscrollview.h>
 #include <qspinbox.h>
+#include <qdockwindow.h>
+#include <qlineedit.h>
 #include <qcheckbox.h>
 #include <qpushbutton.h>
 #include <qpopupmenu.h>
@@ -21,8 +23,10 @@
 
 void MainWindow::createGUI()
 {
-    m_qcairo = new QCairo( this );
-    setCentralWidget( m_qcairo );
+    QScrollView *view = new QScrollView( this );
+    m_qcairo = new QKapow( view );
+    view->addChild( m_qcairo );
+    setCentralWidget( view );
 
     QDockWindow *dockWindow = new QDockWindow( QDockWindow::InDock, this,
                                                "controldock" );
@@ -31,9 +35,15 @@
     dockWindow->setWidget( m_control );
     addDockWindow( dockWindow, Qt::DockLeft );
 
-    m_control->m_baseSpin->setValue( m_qcairo->baseLength() );
-    m_control->m_lineSpin->setValue( m_qcairo->lineWidth() );
-    m_control->m_dbCB->setChecked( m_qcairo->doubleBuffer() );
+    m_control->m_width->setMinValue( 100 );
+    m_control->m_height->setMinValue( 100 );
+    m_control->m_width->setMaxValue( 1000 );
+    m_control->m_height->setMaxValue( 1000 );
+
+    m_control->m_textEdit->setText( "sample" );
+    m_control->m_width->setValue( m_qcairo->width() );
+    m_control->m_height->setValue( m_qcairo->height() );
+    m_control->m_dbCB->setChecked( m_qcairo->doubleBuffered() );
 
     connect( m_control->m_updateBtn, SIGNAL(clicked()),
              SLOT(updateWidget()) );
@@ -49,8 +59,9 @@
 
 void MainWindow::updateWidget()
 {
-    m_qcairo->setBaseLength( m_control->m_baseSpin->value() );
-    m_qcairo->setLineWidth( m_control->m_lineSpin->value() );
-    m_qcairo->setDoubleBuffer( m_control->m_dbCB->isChecked() );
+    m_qcairo->setText( m_control->m_textEdit->text() );
+    m_qcairo->setDoubleBuffered( m_control->m_dbCB->isChecked() );
+    m_qcairo->resize( m_control->m_width->value(),
+                      m_control->m_height->value() );
     m_qcairo->update();
 }

Index: mainwindow.h
===================================================================
RCS file: /cvs/cairo/cairo-demo/qcairo/mainwindow.h,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -d -r1.1 -r1.2
--- mainwindow.h	25 Jan 2005 20:24:22 -0000	1.1
+++ mainwindow.h	1 Jul 2005 19:49:07 -0000	1.2
@@ -3,7 +3,7 @@
 
 #include <qmainwindow.h>
 
-class QCairo;
+class QKapow;
 class ControlWidgetBase;
 
 class MainWindow : public QMainWindow
@@ -19,7 +19,7 @@
     void createActions();
 
 private:
-    QCairo *m_qcairo;
+    QKapow *m_qcairo;
     ControlWidgetBase *m_control;
 };
 

--- qcairo.cpp DELETED ---

--- qcairo.h DELETED ---

Index: qcairo.pro
===================================================================
RCS file: /cvs/cairo/cairo-demo/qcairo/qcairo.pro,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -d -r1.1 -r1.2
--- qcairo.pro	25 Jan 2005 20:24:22 -0000	1.1
+++ qcairo.pro	1 Jul 2005 19:49:07 -0000	1.2
@@ -7,8 +7,8 @@
 LIBS += $$CAIROLIBS
 
 # Input
-HEADERS += qcairo.h mainwindow.h
-SOURCES += main.cpp qcairo.cpp mainwindow.cpp
+HEADERS += qcairowidget.h  mainwindow.h qkapow.h
+SOURCES += main.cpp mainwindow.cpp qcairowidget.cpp qkapow.cpp
 FORMS += controlwidgetbase.ui
 
 OBJECTS_DIR     = .tmp

--- NEW FILE: qcairowidget.cpp ---
#include "qcairowidget.h"

QCairoWidget::QCairoWidget( QWidget *parent, const char *name )
    : QWidget( parent, name )
{
    setDoubleBuffered( true );
    m_cr = cairo_create();
}

QCairoWidget::~QCairoWidget()
{
    cairo_destroy( m_cr );
    m_cr = 0;
}

void QCairoWidget::setDoubleBuffered( bool db )
{
    m_doubleBuffer = db;
    if ( m_doubleBuffer )
        setBackgroundMode( Qt::NoBackground );
}

void QCairoWidget::cairoPaint( cairo_t *, const QRect & )
{

}

void QCairoWidget::paintEvent( QPaintEvent *e )
{
    //the save/restore is a little silly...
    cairo_save( m_cr );

    Display *dpy = x11AppDisplay();
    Drawable drw = handle();

    if ( m_doubleBuffer ) {
        m_buffer = QPixmap( size() );
        m_buffer.fill( this, 0, 0 );
        dpy = m_buffer.x11AppDisplay();
        drw = m_buffer.handle();
    }

    cairo_set_target_drawable( m_cr, dpy, drw );

    cairoPaint( m_cr, e->rect() );

    if ( cairo_status( m_cr ) ) {
	qDebug("Cairo is unhappy: %s\n", cairo_status_string( m_cr ) );
	exit(0);
    }

    if ( m_doubleBuffer )
        bitBlt( this, 0, 0, &m_buffer );

    cairo_restore( m_cr );
}

--- NEW FILE: qcairowidget.h ---
#ifndef QCAIROWIDGET_H
#define QCAIROWIDGET_H

#include <qwidget.h>
#include <qpixmap.h>

#include <cairo.h>
#include <cairo-xlib.h>

class QCairoWidget : public QWidget
{
    Q_OBJECT
public:
    QCairoWidget( QWidget *parent, const char *name=0 );
    ~QCairoWidget();

    bool doubleBuffered() const;
    void setDoubleBuffered( bool db );

protected:
    virtual void cairoPaint( cairo_t *cr, const QRect &invalidatedArea );

protected:
    void paintEvent( QPaintEvent *e );

private:
    cairo_t *m_cr;
    QPixmap m_buffer;
    bool m_doubleBuffer;
};

inline bool QCairoWidget::doubleBuffered() const
{
    return m_doubleBuffer;
}

#endif

--- NEW FILE: qkapow.cpp ---
#include "qkapow.h"

#include <stdio.h>
#include <stdlib.h>
#include <libgen.h>
#include <cairo.h>
#include <math.h>

const char fontname[] = "Sans";
const char default_text[] = "KAPOW";

#define IMAGE_WIDTH  384
#define IMAGE_HEIGHT 256

#define SPIKES 10
#define SHADOW_OFFSET 10

#define X_FUZZ 16
#define Y_FUZZ 16

void QKapow::make_star_path(cairo_t *cr)
{
    double x;
    double y;
    int i;

    srand (45);

    double X_OUTER_RADIUS  = (width() / 2 - X_FUZZ - SHADOW_OFFSET);
    double Y_OUTER_RADIUS  = (height() / 2 - Y_FUZZ - SHADOW_OFFSET);
    double X_INNER_RADIUS  = (X_OUTER_RADIUS * 0.7);
    double Y_INNER_RADIUS  = (Y_OUTER_RADIUS * 0.7);

    for (i = 0; i < SPIKES * 2; i++) {

	x = width() / 2 + cos (M_PI * i / SPIKES) * X_INNER_RADIUS +
	    (double) rand() * X_FUZZ / RAND_MAX;
	y = height() / 2 + sin (M_PI * i / SPIKES) * Y_INNER_RADIUS +
	    (double) rand() * Y_FUZZ / RAND_MAX;

	if (i == 0)
	    cairo_move_to (cr, x, y);
	else
	    cairo_line_to (cr, x, y);

	i++;

	x = width() / 2 + cos (M_PI * i / SPIKES) * X_OUTER_RADIUS +
	    (double) rand() * X_FUZZ / RAND_MAX;
	y = height() / 2 + sin (M_PI * i / SPIKES) * Y_OUTER_RADIUS +
	    (double) rand() * Y_FUZZ / RAND_MAX;

	cairo_line_to (cr, x, y);
    }

    cairo_close_path (cr);
}

void QKapow::bend_it (double x, double y, double *new_x, double *new_y)
{
    const double cx = width() / 2, cy = 500;
    double angle, radius, t;

    /* We're going to wrap the points around a big circle with center
     * at (cx, cy), with cy being somewhere well below the visible area.
     * On top of that, we'll scale up the letters going left to right.
     */

    angle = M_PI / 2 - (double) (x - cx) / width();
    t = 3 * M_PI / 4 - angle + 0.05;
    angle = 3 * M_PI / 4 - pow (t, 1.8);
    radius = cy - (height() / 2 + (y - height() / 2) * t * 2);

    *new_x = cx + cos (angle) * radius;
    *new_y = cy - sin (angle) * radius;
}

static void move_to_callback(void *data, double x, double y)
{
    QKapow *ctx = (QKapow*)data;
    double new_x, new_y;

    if (ctx->first()) {
	cairo_new_path (ctx->cr());
	ctx->setFirst( 0 );
    }

    ctx->bend_it(x, y, &new_x, &new_y);
    cairo_move_to (ctx->cr(), new_x, new_y);
}

static void line_to_callback(void *data, double x, double y)
{
    QKapow *ctx = (QKapow*)data;
    double new_x, new_y;

    ctx->bend_it (x, y, &new_x, &new_y);
    cairo_line_to (ctx->cr(), new_x, new_y);
}

static void close_path_callback(void *data)
{
    QKapow *ctx = (QKapow*)data;

    cairo_close_path (ctx->cr());
}

void QKapow::make_text_path (cairo_t *cr, double x, double y, const char *text)
{
    m_first = 1;
    m_cr = cr;
    cairo_move_to (cr, x, y);
    cairo_text_path (cr, ( const unsigned char* ) text);
    cairo_current_path_flat (cr, move_to_callback, line_to_callback,
			     close_path_callback, this);
}


QKapow::QKapow( QWidget *parent )
    : QCairoWidget( parent ),
      m_text( "sample" )
{
    resize( IMAGE_WIDTH, IMAGE_HEIGHT );
}

void QKapow::cairoPaint( cairo_t *cr, const QRect & )
{
    double x;
    double y;
    QString text = m_text.left(20);
    cairo_text_extents_t extents;
    cairo_pattern_t *pattern;

    cairo_set_line_width (cr, 2);

    cairo_save (cr);
    cairo_translate (cr, SHADOW_OFFSET, SHADOW_OFFSET);
    make_star_path (cr);
    cairo_set_alpha (cr, 0.5);
    cairo_set_rgb_color (cr, 0, 0, 0);
    cairo_fill (cr);
    cairo_restore (cr);

    make_star_path (cr);
    cairo_set_alpha (cr, 1);
    pattern =
	cairo_pattern_create_radial (width() / 2, height() / 2, 10,
				     width() / 2, height() / 2, 230);
    cairo_pattern_add_color_stop (pattern, 0, 1, 1, 0.2, 1);
    cairo_pattern_add_color_stop (pattern, 1, 1, 0, 0, 1);
    cairo_set_pattern (cr, pattern);
    cairo_fill (cr);

    make_star_path (cr);
    cairo_set_rgb_color (cr, 0, 0, 0);
    cairo_stroke (cr);

    cairo_select_font (cr, fontname,
		       CAIRO_FONT_SLANT_NORMAL,
		       CAIRO_FONT_WEIGHT_BOLD);

    cairo_scale_font (cr, 50);
    cairo_text_extents (cr, ( const unsigned char* )text.latin1(), &extents);
    x = width() / 2 - (extents.width / 2 + extents.x_bearing);
    y = height() / 2 - (extents.height / 2 + extents.y_bearing);

    make_text_path (cr, x, y, text.latin1());

    pattern =
	cairo_pattern_create_linear (width() / 2 - 10, height() / 4,
				     width() / 2 + 10, 3 * height() / 4);
    cairo_pattern_add_color_stop (pattern, 0, 1, 1, 1, 1);
    cairo_pattern_add_color_stop (pattern, 1, 0, 0, 0.4, 1);
    cairo_set_pattern (cr, pattern);

    cairo_fill (cr);

    make_text_path (cr, x, y, text.latin1());
    cairo_set_rgb_color (cr, 0, 0, 0);
    cairo_stroke (cr);

    cairo_show_page (cr);
}

QSize QKapow::sizeHint() const
{
    return size();
}

--- NEW FILE: qkapow.h ---
#ifndef QKAPOW_H
#define QKAPOW_H

#include "qcairowidget.h"

#include <qsize.h>
#include <qstring.h>

typedef struct _cairo cairo_t;
class QRect;

class QKapow : public QCairoWidget
{
    Q_OBJECT
public:
    QKapow( QWidget *parent );

    virtual QSize sizeHint () const;

    void setText( const QString &text )
    {
        m_text = text;
    }
    int first() const
    {
        return m_first;
    }
    void setFirst( int i )
    {
        m_first = i;
    }

    cairo_t *cr() const
    {
        return m_cr;
    }
    void bend_it(double x, double y, double *new_x, double *new_y);

protected:
    virtual void cairoPaint( cairo_t *cr, const QRect &rect );

protected:
    void make_text_path (cairo_t *cr, double x, double y, const char *text);
    void make_star_path(cairo_t *cr);

private:
    QString   m_text;
    QSize     m_defaultSize;
    int       m_first;
    cairo_t  *m_cr;
};

#endif




More information about the cairo-commit mailing list