Skip to content
qwt_symbol.cpp 43.2 KiB
Newer Older
pixhawk's avatar
pixhawk committed
/* -*- mode: C++ ; c-file-style: "stroustrup" -*- *****************************
 * Qwt Widget Library
 * Copyright (C) 1997   Josef Wilgen
 * Copyright (C) 2002   Uwe Rathmann
pixhawk's avatar
pixhawk committed
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the Qwt License, Version 1.0
 *****************************************************************************/

#include "qwt_symbol.h"
Bryant's avatar
Bryant committed
#include "qwt_painter.h"
#include "qwt_graphic.h"
#include <qapplication.h>
#include <qpainter.h>
#include <qpainterpath.h>
#include <qpixmap.h>
#include <qpaintengine.h>
#include <qmath.h>
#ifndef QWT_NO_SVG
#include <qsvgrenderer.h>
#endif

namespace QwtTriangle
{
    enum Type
    {
        Left,
        Right,
        Up,
        Down
    };
}

static QwtGraphic qwtPathGraphic( const QPainterPath &path, 
    const QPen &pen, const QBrush& brush )
{
    QwtGraphic graphic;
    graphic.setRenderHint( QwtGraphic::RenderPensUnscaled );

    QPainter painter( &graphic );
    painter.setPen( pen );
    painter.setBrush( brush );
    painter.drawPath( path );
    painter.end();

    return graphic;
}

static inline QRectF qwtScaledBoundingRect( 
    const QwtGraphic &graphic, const QSizeF size )
{
    QSizeF scaledSize = size;
    if ( scaledSize.isEmpty() )
        scaledSize = graphic.defaultSize();
        
    const QSizeF sz = graphic.controlPointRect().size();

    double sx = 1.0;
    if ( sz.width() > 0.0 )
        sx = scaledSize.width() / sz.width();
    
    double sy = 1.0;
    if ( sz.height() > 0.0 )
        sy = scaledSize.height() / sz.height();

    return graphic.scaledBoundingRect( sx, sy );
}

static inline void qwtDrawPixmapSymbols( QPainter *painter,
    const QPointF *points, int numPoints, const QwtSymbol &symbol )
{
    QSize size = symbol.size();
    if ( size.isEmpty() )
        size = symbol.pixmap().size();

    const QTransform transform = painter->transform();
    if ( transform.isScaling() )
    {
        const QRect r( 0, 0, size.width(), size.height() );
        size = transform.mapRect( r ).size();
    }

    QPixmap pm = symbol.pixmap();
    if ( pm.size() != size )
        pm = pm.scaled( size );
    
    QPointF pinPoint( 0.5 * size.width(), 0.5 * size.height() );
    if ( symbol.isPinPointEnabled() )
        pinPoint = symbol.pinPoint();

    painter->resetTransform();

    for ( int i = 0; i < numPoints; i++ )
    {
        const QPointF pos = transform.map( points[i] ) - pinPoint;

        QwtPainter::drawPixmap( painter, 
            QRect( pos.toPoint(), pm.size() ), pm );
    }
}

#ifndef QWT_NO_SVG

static inline void qwtDrawSvgSymbols( QPainter *painter, 
    const QPointF *points, int numPoints, 
    QSvgRenderer *renderer, const QwtSymbol &symbol )
{
    if ( renderer == NULL || !renderer->isValid() )
        return;

    const QRectF viewBox = renderer->viewBoxF();
    if ( viewBox.isEmpty() )
        return;

    QSizeF sz = symbol.size();
    if ( !sz.isValid() )
        sz = viewBox.size();

    const double sx = sz.width() / viewBox.width();
    const double sy = sz.height() / viewBox.height();

    QPointF pinPoint = viewBox.center();
    if ( symbol.isPinPointEnabled() )
        pinPoint = symbol.pinPoint();

    const double dx = sx * ( pinPoint.x() - viewBox.left() );
    const double dy = sy * ( pinPoint.y() - viewBox.top() );

    for ( int i = 0; i < numPoints; i++ )
    {
        const double x = points[i].x() - dx;
        const double y = points[i].y() - dy;

        renderer->render( painter, 
            QRectF( x, y, sz.width(), sz.height() ) );
    }
}

#endif

static inline void qwtDrawGraphicSymbols( QPainter *painter, 
    const QPointF *points, int numPoints, const QwtGraphic &graphic,
    const QwtSymbol &symbol )
{
    const QRectF pointRect = graphic.controlPointRect();
    if ( pointRect.isEmpty() )
        return;

    double sx = 1.0;
    double sy = 1.0;

    const QSize sz = symbol.size();
    if ( sz.isValid() )
    {
        sx = sz.width() / pointRect.width();
        sy = sz.height() / pointRect.height();
    }

    QPointF pinPoint = pointRect.center();
    if ( symbol.isPinPointEnabled() )
        pinPoint = symbol.pinPoint();

    const QTransform transform = painter->transform();

    for ( int i = 0; i < numPoints; i++ )
    {
        QTransform tr = transform;
        tr.translate( points[i].x(), points[i].y() );
        tr.scale( sx, sy );
        tr.translate( -pinPoint.x(), -pinPoint.y() );

        painter->setTransform( tr );

        graphic.render( painter );
    }

    painter->setTransform( transform );
}

static inline void qwtDrawEllipseSymbols( QPainter *painter,
    const QPointF *points, int numPoints, const QwtSymbol &symbol )
{
    painter->setBrush( symbol.brush() );
    painter->setPen( symbol.pen() );

    const QSize size = symbol.size();

    if ( QwtPainter::roundingAlignment( painter ) )
    {
        const int sw = size.width();
        const int sh = size.height();
        const int sw2 = size.width() / 2;
        const int sh2 = size.height() / 2;

        for ( int i = 0; i < numPoints; i++ )
        {
            const int x = qRound( points[i].x() );
            const int y = qRound( points[i].y() );

            const QRectF r( x - sw2, y - sh2, sw, sh );
Loading
Loading full blame...