You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
702 lines
21 KiB
702 lines
21 KiB
/***************************************************************************
|
|
qsdrv.cpp
|
|
-------------------
|
|
begin : 01-January-2000
|
|
copyright : (C) 2000 by Kamil Dobkowski
|
|
email : kamildobk@poczta.onet.pl
|
|
***************************************************************************/
|
|
|
|
/***************************************************************************
|
|
* *
|
|
* This program is free software; you can redistribute it and/or modify *
|
|
* it under the terms of the GNU General Public License as published by *
|
|
* the Free Software Foundation; either version 2 of the License, or *
|
|
* (at your option) any later version. *
|
|
* *
|
|
***************************************************************************/
|
|
|
|
|
|
#include "qsdrv.h"
|
|
#include <qwmatrix.h>
|
|
#include <math.h>
|
|
#include <iostream>
|
|
|
|
//-------------------------------------------------------------//
|
|
|
|
QSCanvasDrv::QSCanvasDrv()
|
|
{
|
|
dpi = 72.0;
|
|
}
|
|
|
|
//-------------------------------------------------------------//
|
|
|
|
QSCanvasDrv::~QSCanvasDrv()
|
|
{
|
|
stopDrawing();
|
|
}
|
|
|
|
//-------------------------------------------------------------//
|
|
|
|
void QSCanvasDrv::startDrawing()
|
|
{
|
|
}
|
|
|
|
//-------------------------------------------------------------//
|
|
|
|
void QSCanvasDrv::stopDrawing()
|
|
{
|
|
}
|
|
|
|
//-------------------------------------------------------------//
|
|
|
|
void QSCanvasDrv::drawPoint( const QSPt2f& pos, const QSGPoint& point )
|
|
{
|
|
if ( point.style != QSGPoint::Invisible ) {
|
|
double size = toPixels(point.size);
|
|
QSPt2f p1( pos.x - size/2.0, pos.y - size/2.0 );
|
|
QSPt2f p2( p1.x + size, p1.y + size );
|
|
|
|
QSGLine cl = currentLine();
|
|
QSGFill cf = currentFill();
|
|
QSGLine l; l.color = point.color; l.width = int(floor(size/15.0+0.5));
|
|
QSGFill f;
|
|
if ( point.fill == QSGPoint::Filled ) f.color = point.color;
|
|
if ( point.fill == QSGPoint::Transparent ) f.style = QSGFill::Transparent;
|
|
|
|
if ( cf != f ) setFill( f );
|
|
if ( cl != l ) setLine( l );
|
|
|
|
QSPt2f p[4];
|
|
switch( point.style ) {
|
|
case QSGPoint::Circle:
|
|
drawEllipse(p1,p2);
|
|
break;
|
|
|
|
case QSGPoint::Rect:
|
|
drawRect( p1, p2 );
|
|
break;
|
|
|
|
case QSGPoint::Triangle
|
|
: p[0].set( pos.x, p1.y );
|
|
p[1].set( p2.x, p2.y );
|
|
p[2].set( p1.x, p2.y );
|
|
drawPoly( p, 3 );
|
|
break;
|
|
|
|
case QSGPoint::Diamond:
|
|
p[0].set( pos.x, p1.y );
|
|
p[1].set( p2.x, pos.y );
|
|
p[2].set( pos.x, p2.y );
|
|
p[3].set( p1.x, pos.y );
|
|
drawPoly( p, 4 );
|
|
break;
|
|
|
|
case QSGPoint::Cross:
|
|
drawLine( p1, p2 );
|
|
drawLine( p[0].set(p2.x,p1.y), p[1].set(p1.x,p2.y) );
|
|
break;
|
|
|
|
case QSGPoint::Plus:
|
|
drawLine( p[0].set(p1.x,pos.y), p[1].set(p2.x,pos.y) );
|
|
drawLine( p[0].set(pos.x,p1.y), p[1].set(pos.x,p2.y) );
|
|
break;
|
|
|
|
case QSGPoint::HLine:
|
|
drawLine( p[0].set(p1.x,pos.y), p[1].set(p2.x,pos.y) );
|
|
break;
|
|
|
|
case QSGPoint::VLine:
|
|
drawLine( p[0].set(pos.x,p1.y), p[1].set(pos.x,p2.y) );
|
|
break;
|
|
default: break;
|
|
}
|
|
}
|
|
}
|
|
|
|
//-------------------------------------------------------------//
|
|
|
|
/* { number_of_vertices, x1, y1, x2, y2, ... } */
|
|
|
|
// arrow
|
|
static const double arrow_A[] = { 4, 0, 0, -2, -1, -1, 0, -2, 1 };
|
|
// filled arrow
|
|
static const double arrow_FA[] = { 3, 0, 0, -2, -1, -2, 1 };
|
|
// narrow arrow
|
|
static const double arrow_NA[] = { 3, 0, 0, -3, -1, -3, 1 };
|
|
// reversed arrow
|
|
static const double arrow_RA[] = { 4, 0, 0, 2, -1, 1, 0, 2, 1 };
|
|
// reversed filled arrow
|
|
static const double arrow_RFA[] = { 3, 0, 0, 2, -1, 2, 1 };
|
|
// reversed narrow arrow
|
|
static const double arrow_RNA[] = { 3, 0, 0, 3, -1, 3, 1 };
|
|
// rectangle
|
|
static const double arrow_R[] = { 4, -1, -1, 1, -1, 1, 1, -1, 1 };
|
|
// diamond
|
|
static const double arrow_D[] = { 4, -1, 0, 0, -1, 1, 0, 0, 1 };
|
|
// line
|
|
static const double arrow_L[] = { 2, 0, -1, 0, 1 };
|
|
// fdiag line
|
|
static const double arrow_F[] = { 2, -1,-1, 1, 1 };
|
|
// bdiag line
|
|
static const double arrow_B[] = { 2, -1, 1, 1, -1 };
|
|
|
|
static const double *arrows[] = { NULL,
|
|
arrow_A,
|
|
arrow_FA,
|
|
arrow_NA,
|
|
arrow_RA,
|
|
arrow_RFA,
|
|
arrow_RNA,
|
|
arrow_R,
|
|
arrow_D,
|
|
NULL,
|
|
arrow_L,
|
|
arrow_F,
|
|
arrow_B };
|
|
|
|
//-------------------------------------------------------------//
|
|
|
|
void QSCanvasDrv::drawDart( const QSPt2f& pos, double angle, const QSGArrow& arrow )
|
|
{
|
|
if ( arrow.style == QSGArrow::None ) return;
|
|
|
|
double scale = toPixels( arrow.size );
|
|
|
|
QSGLine cl = currentLine();
|
|
QSGLine l; l.color = cl.color; setLine( l );
|
|
QSGFill f; f.color = cl.color; setFill( f );
|
|
|
|
if ( arrow.style == QSGArrow::Circle ) {
|
|
double size = scale;;
|
|
QSPt2f p1( pos.x - size, pos.y - size );
|
|
QSPt2f p2( pos.x + size, pos.y + size );
|
|
drawEllipse( p1, p2 );
|
|
return;
|
|
}
|
|
|
|
QSPt2f p[4]; QWMatrix m;
|
|
m.translate( pos.x, pos.y ); m.rotate( angle ); m.scale( scale, scale );
|
|
for( int i=0; i<arrows[arrow.style][0]; i++ ) m.map( arrows[arrow.style][i*2+1],
|
|
arrows[arrow.style][i*2+2],
|
|
&p[i].x, &p[i].y );
|
|
if (arrows[arrow.style][0] > 2 ) drawPoly( p, (int )arrows[arrow.style][0] );
|
|
else drawLine( p[0], p[1] );
|
|
}
|
|
|
|
//-------------------------------------------------------------//
|
|
|
|
void QSCanvasDrv::drawArrow( const QSPt2f& p1, const QSPt2f& p2, const QSGArrow& p1style, const QSGArrow& p2style )
|
|
{
|
|
double angle = ( p1 == p2 ) ? 0.0 : atan2(p2.y-p1.y,p2.x-p1.x)*180.0/3.141592;
|
|
|
|
drawLine( p1, p2 );
|
|
drawDart( p1, angle+180.0, p1style );
|
|
drawDart( p2, angle+ 0.0, p2style );
|
|
}
|
|
|
|
//-------------------------------------------------------------//
|
|
|
|
void QSCanvasDrv::drawRTextBox( const QSPt2f &pos, int angle, const QString& text, int align )
|
|
{
|
|
QSPt2f text_size = rTextSize( angle, text );
|
|
QSPt2f text_pos = pos;
|
|
if ( align & AlignLeft ) text_pos.x += text_size.x/2.0;
|
|
if ( align & AlignRight ) text_pos.x -= text_size.x/2.0;
|
|
if ( align & AlignTop ) text_pos.y += text_size.y/2.0;
|
|
if ( align & AlignBottom ) text_pos.y -= text_size.y/2.0;
|
|
drawRText( text_pos, angle, text, AlignVCenter | AlignHCenter );
|
|
}
|
|
|
|
//-------------------------------------------------------------//
|
|
|
|
QSPt2f QSCanvasDrv::rTextSize( int angle, const QString& text )
|
|
{
|
|
QSPt2f pts[4];
|
|
getRTextBoundingPoly( pts, QSPt2f(0,0), angle, text );
|
|
QSPt2f min;
|
|
QSPt2f max;
|
|
min.x = QMIN(pts[0].x,pts[1].x); min.x = QMIN(min.x,pts[2].x); min.x = QMIN(min.x,pts[3].x);
|
|
min.y = QMIN(pts[0].y,pts[1].y); min.y = QMIN(min.y,pts[2].y); min.y = QMIN(min.y,pts[3].y);
|
|
max.x = QMAX(pts[0].x,pts[1].x); max.x = QMAX(max.x,pts[2].x); max.x = QMAX(max.x,pts[3].x);
|
|
max.y = QMAX(pts[0].y,pts[1].y); max.y = QMAX(max.y,pts[2].y); max.y = QMAX(max.y,pts[3].y);
|
|
return QSPt2f( max.x-min.x+1.0, max.y-min.y+1.0 );
|
|
}
|
|
|
|
|
|
//-------------------------------------------------------------//
|
|
/*
|
|
void QSCanvasDrv::drawRText( const QSPt2f&, int, const QString&, int )
|
|
{
|
|
}
|
|
|
|
//-------------------------------------------------------------//
|
|
|
|
void QSCanvasDrv::getRTextBoundingPoly( QSPt2f [4], const QSPt2f&, int, const QString&, int )
|
|
{
|
|
}
|
|
|
|
//-------------------------------------------------------------//
|
|
|
|
void QSCanvasDrv::beginPolyline( const QSPt2f& )
|
|
{
|
|
}
|
|
|
|
//-------------------------------------------------------------//
|
|
|
|
void QSCanvasDrv::drawPolylineTo( const QSPt2f& )
|
|
{
|
|
}
|
|
*/
|
|
|
|
//-------------------------------------------------------------//
|
|
|
|
void QSCanvasDrv::getPixmapBuffer( PixmapBuffer *buff, int, int )
|
|
{
|
|
buff->ptr = NULL;
|
|
}
|
|
|
|
//-------------------------------------------------------------//
|
|
|
|
void QSCanvasDrv::drawPixmap( const QSPt2f&, PixmapBuffer * )
|
|
{
|
|
}
|
|
|
|
|
|
|
|
//-------------------------------------------------------------//
|
|
//-------------------------------------------------------------//
|
|
//-------------------------------------------------------------//
|
|
//-------------------------------------------------------------//
|
|
//-------------------------------------------------------------//
|
|
//-------------------------------------------------------------//
|
|
|
|
QSDrv::QSDrv()
|
|
:QSCanvasDrv()
|
|
{
|
|
m_t = NULL;
|
|
m_clipping = false;
|
|
m_pts = NULL;
|
|
m_cpts2 = NULL;
|
|
m_cpts3 = NULL;
|
|
m_cedges = NULL;
|
|
m_ncpts2 = 0;
|
|
m_ncpts3 = 0;
|
|
m_max_cedges = 0;
|
|
m_max_pts = 0;
|
|
m_max_cpts2 = 0;
|
|
m_max_cpts3 = 0;
|
|
m_top_bottom = false;
|
|
m_category = -1;
|
|
m_element = -1;
|
|
}
|
|
|
|
//-------------------------------------------------------------//
|
|
|
|
QSDrv::~QSDrv()
|
|
{
|
|
}
|
|
|
|
//-------------------------------------------------------------//
|
|
|
|
void QSDrv::setProjection( const QSProjection *t )
|
|
{
|
|
m_t = t;
|
|
}
|
|
|
|
//-------------------------------------------------------------//
|
|
|
|
void QSDrv::setCurrentElement( int category, int element )
|
|
{
|
|
m_category = category;
|
|
m_element = element;
|
|
}
|
|
|
|
//-------------------------------------------------------------//
|
|
|
|
void QSDrv::setClipping( bool enabled )
|
|
{
|
|
m_clipping = enabled;
|
|
}
|
|
|
|
//-------------------------------------------------------------//
|
|
|
|
void QSDrv::setTopBottom( bool enabled )
|
|
{
|
|
m_top_bottom = enabled;
|
|
}
|
|
|
|
//-------------------------------------------------------------//
|
|
|
|
void QSDrv::setBottomFill( const QSGFill& f )
|
|
{
|
|
m_bottom_fill = f;
|
|
}
|
|
|
|
//-------------------------------------------------------------//
|
|
|
|
void QSDrv::startDrawing()
|
|
{
|
|
QSCanvasDrv::startDrawing();
|
|
}
|
|
|
|
//-------------------------------------------------------------//
|
|
|
|
void QSDrv::stopDrawing()
|
|
{
|
|
delete[] m_pts; m_pts = NULL; m_max_pts = 0;
|
|
delete[] m_cpts2; m_cpts2 = NULL; m_ncpts2 = 0; m_max_cpts2 = 0;
|
|
delete[] m_cpts3; m_cpts3 = NULL; m_ncpts3 = 0; m_max_cpts3 = 0;
|
|
m_category = -1;
|
|
m_element = -1;
|
|
QSCanvasDrv::stopDrawing();
|
|
}
|
|
|
|
//-------------------------------------------------------------//
|
|
//-------------------------------------------------------------//
|
|
//-------------------------------------------------------------//
|
|
//-------------------------------------------------------------//
|
|
//-------------------------------------------------------------//
|
|
|
|
void QSDrv::drawPoly3( const QSPt3f pts3[], int npoints, const QSPt3f *norm, const QSGFill *fills, const bool edges[], int edgeAutoColor )
|
|
// if driver uses something else except norm[0], colors[0] you must
|
|
// reimplement this function to clipVertexColors and clipVertexNormals
|
|
{
|
|
const bool *in_edges = NULL;
|
|
const QSPt3f *in_pts3 = NULL;
|
|
int in_npts3 = 0;
|
|
if ( m_clipping ) {
|
|
QSProjection::ClipResult clip = clip_poly( pts3, npoints, edges );
|
|
if ( clip == QSProjection::Accepted ) { in_pts3 = pts3; in_npts3 = npoints; in_edges = edges; }
|
|
else
|
|
if ( clip == QSProjection::Clipped ) { in_pts3 = m_cpts3; in_npts3 = m_ncpts3; in_edges = m_cedges; }
|
|
else
|
|
if ( clip == QSProjection::Rejected ) return;
|
|
} else {
|
|
in_pts3 = pts3; in_npts3 = npoints;
|
|
}
|
|
|
|
map_to_screen( in_pts3, in_npts3 );
|
|
// if ( m_stage > 0 ) {
|
|
QSGFill f = fills[0];
|
|
m_t->shade( f, norm[0], m_pts, in_npts3, (m_top_bottom?&m_bottom_fill:NULL) );
|
|
setFill( f );
|
|
drawPoly( m_pts, in_npts3, in_edges, edgeAutoColor );
|
|
}
|
|
|
|
/*
|
|
if ( cNormals() == VertexNormals || 1 ) {
|
|
QSPt3f no_norm[2];
|
|
for( int i=0; i<npoints; i++ ) {
|
|
QSPt3f n( norm[i+1].x/5.0, norm[i+1].y/5.0, norm[i+1].z/5.0 );
|
|
drawLine3( pts3[i], pts3[i]+n, no_norm );
|
|
}
|
|
}
|
|
*/
|
|
//-------------------------------------------------------------//
|
|
|
|
void QSDrv::drawLine3( const QSPt3f& pos1, const QSPt3f& pos2, const QSPt3f [2] )
|
|
{
|
|
if ( m_clipping ) {
|
|
QSPt3f p1 = pos1; QSPt3f p2 = pos2;
|
|
if ( m_t->clipLine3(&p1,&p2) ) drawLine( m_t->world3DToCanvas(p1), m_t->world3DToCanvas(p2) );
|
|
} else {
|
|
drawLine( m_t->world3DToCanvas(pos1), m_t->world3DToCanvas(pos2) );
|
|
}
|
|
}
|
|
|
|
//-------------------------------------------------------------//
|
|
|
|
void QSDrv::drawText3( const QSPt3f& pos, const QString& text, int align )
|
|
{
|
|
if ( !m_clipping || (m_clipping && m_t->clipPoint3(pos)) )
|
|
drawText( m_t->world3DToCanvas(pos), text, align );
|
|
}
|
|
|
|
//-------------------------------------------------------------//
|
|
|
|
void QSDrv::drawPoint3( const QSPt3f& pos, const QSGPoint& point )
|
|
{
|
|
if ( !m_clipping || (m_clipping && m_t->clipPoint3(pos)) )
|
|
drawPoint( m_t->world3DToCanvas(pos), point );
|
|
}
|
|
|
|
//-------------------------------------------------------------//
|
|
|
|
void QSDrv::clearCanvas( const QSGFill&, const QSPt2f&, const QSPt2f& )
|
|
{
|
|
}
|
|
|
|
//-------------------------------------------------------------//
|
|
|
|
void QSDrv::drawLine2( const QSPt2f &one, const QSPt2f &two )
|
|
{
|
|
if ( m_clipping ) {
|
|
QSPt2f p1 = one;
|
|
QSPt2f p2 = two;
|
|
if ( m_t->clipLine2(&p1,&p2) ) drawLine( m_t->world2DToCanvas(p1), m_t->world2DToCanvas(p2) );
|
|
} else {
|
|
drawLine( m_t->world2DToCanvas(one), m_t->world2DToCanvas(two) );
|
|
}
|
|
}
|
|
|
|
//-------------------------------------------------------------//
|
|
|
|
void QSDrv::drawRect2( const QSPt2f &p1, const QSPt2f &p2 )
|
|
{
|
|
if ( !m_clipping || (m_clipping && (m_t->clipPoint2(p1) || m_t->clipPoint2(p2))) )
|
|
drawRect( m_t->world2DToCanvas(p1), m_t->world2DToCanvas(p2) );
|
|
}
|
|
|
|
//-------------------------------------------------------------//
|
|
|
|
void QSDrv::drawPoly2( const QSPt2f pts[], int npoints, const bool edges[], int edgeAutoColor )
|
|
{
|
|
if ( m_clipping ) {
|
|
QSProjection::ClipResult clip = clip_poly( pts, npoints, edges );
|
|
if ( clip == QSProjection::Accepted ) {
|
|
map_to_screen( pts, npoints );
|
|
drawPoly( m_pts, npoints, edges, edgeAutoColor );
|
|
}
|
|
else
|
|
if ( clip == QSProjection::Clipped ) {
|
|
map_to_screen( m_cpts2, m_ncpts2 );
|
|
drawPoly( m_pts, m_ncpts2, m_cedges, edgeAutoColor );
|
|
}
|
|
} else {
|
|
map_to_screen( pts, npoints );
|
|
drawPoly( m_pts, npoints, edges, edgeAutoColor );
|
|
}
|
|
}
|
|
|
|
//-------------------------------------------------------------//
|
|
|
|
void QSDrv::drawEllipse2( const QSPt2f& p1, const QSPt2f& p2 )
|
|
{
|
|
if ( !m_clipping || (m_clipping && (m_t->clipPoint2(p1) || m_t->clipPoint2(p2))) )
|
|
drawEllipse( m_t->world2DToCanvas(p1), m_t->world2DToCanvas(p2) );
|
|
}
|
|
|
|
//-------------------------------------------------------------//
|
|
|
|
void QSDrv::drawText2( const QSPt2f &pos, const QString& text, int align )
|
|
{
|
|
if ( !m_clipping || (m_clipping && m_t->clipPoint2(pos)) )
|
|
drawText( m_t->world2DToCanvas(pos), text, align );
|
|
}
|
|
|
|
//-------------------------------------------------------------//
|
|
|
|
void QSDrv::drawRText2( const QSPt2f &pos, int angle, const QString& text, int align )
|
|
{
|
|
if ( !m_clipping || (m_clipping && m_t->clipPoint2(pos)) )
|
|
drawRText( m_t->world2DToCanvas(pos), angle, text, align );
|
|
}
|
|
|
|
//-------------------------------------------------------------//
|
|
|
|
void QSDrv::drawRTextBox2( const QSPt2f &pos, int angle, const QString& text, int align )
|
|
{
|
|
if ( !m_clipping || (m_clipping && m_t->clipPoint2(pos)) )
|
|
drawRTextBox( m_t->world2DToCanvas(pos), angle, text, align );
|
|
}
|
|
|
|
//-------------------------------------------------------------//
|
|
|
|
void QSDrv::drawPoint2( const QSPt2f& pos, const QSGPoint& style )
|
|
{
|
|
if ( !m_clipping || (m_clipping && m_t->clipPoint2(pos)) )
|
|
drawPoint( m_t->world2DToCanvas(pos), style );
|
|
}
|
|
|
|
//-------------------------------------------------------------//
|
|
|
|
void QSDrv::drawDart2( const QSPt2f& pos, double angle, const QSGArrow& style )
|
|
{
|
|
drawDart( m_t->world2DToCanvas(pos), angle, style );
|
|
}
|
|
|
|
//-------------------------------------------------------------//
|
|
|
|
void QSDrv::drawArrow2( const QSPt2f& pos1, const QSPt2f& pos2, const QSGArrow& p1style, const QSGArrow& p2style )
|
|
{
|
|
if ( m_clipping ) {
|
|
QSPt2f p1 = pos1;
|
|
QSPt2f p2 = pos2;
|
|
QSGArrow s1 = p1style;
|
|
QSGArrow s2 = p2style;
|
|
if (m_t->clipLine2(&p1,&p2)) {
|
|
if ( p1 != pos1 ) s1.style = QSGArrow::None;
|
|
if ( p2 != pos2 ) s2.style = QSGArrow::None;
|
|
drawArrow( m_t->world2DToCanvas(p1), m_t->world2DToCanvas(p2), s1, s2 );
|
|
}
|
|
} else {
|
|
drawArrow( m_t->world2DToCanvas(pos1), m_t->world2DToCanvas(pos2), p1style, p2style );
|
|
}
|
|
}
|
|
|
|
//-------------------------------------------------------------//
|
|
|
|
void QSDrv::beginPolyline2( const QSPt2f& pos )
|
|
{
|
|
m_curr_polyline_pos = pos;
|
|
beginPolyline( m_t->world2DToCanvas(pos) );
|
|
}
|
|
|
|
//-------------------------------------------------------------//
|
|
|
|
void QSDrv::drawPolylineTo2( const QSPt2f& pos )
|
|
{
|
|
if ( m_clipping ) {
|
|
QSPt2f p1 = m_curr_polyline_pos;
|
|
QSPt2f p2 = pos;
|
|
if (m_t->clipLine2(&p1,&p2)) {
|
|
|
|
QSPt2f canvas_p1 = m_t->world2DToCanvas(p1);
|
|
QSPt2f canvas_p2 = m_t->world2DToCanvas(p2);
|
|
if (p1!=m_curr_polyline_pos) {
|
|
endPolyline();
|
|
beginPolyline(canvas_p1);
|
|
}
|
|
|
|
// leave a place for a label
|
|
QSPt2f label_p1 = canvas_p1;
|
|
QSPt2f label_p2 = canvas_p2;
|
|
QSProjection::ClipResult clip_result = m_t->clipLine( &label_p1, &label_p2, m_polyline_label_pos, m_polyline_label_size );
|
|
// skip
|
|
if ( clip_result == QSProjection::Accepted ) {
|
|
endPolyline();
|
|
beginPolyline( canvas_p2 );
|
|
}
|
|
else
|
|
// draw normal line
|
|
if ( clip_result == QSProjection::Rejected ) {
|
|
drawPolylineTo( canvas_p2 );
|
|
}
|
|
else
|
|
// draw clipped line
|
|
if ( clip_result == QSProjection::Clipped ) {
|
|
if ( canvas_p1 != label_p1 &&
|
|
canvas_p2 != label_p2 ) {
|
|
drawPolylineTo( label_p1 );
|
|
endPolyline(); beginPolyline( label_p2 );
|
|
drawPolylineTo( canvas_p2 );
|
|
}
|
|
else
|
|
if ( canvas_p1 != label_p1 ) {
|
|
drawPolylineTo( label_p1 );
|
|
}
|
|
else
|
|
if ( canvas_p2 != label_p2 ) {
|
|
endPolyline(); beginPolyline( label_p2 );
|
|
drawPolylineTo( canvas_p2 );
|
|
}
|
|
}
|
|
|
|
}
|
|
} else {
|
|
drawPolylineTo( m_t->world2DToCanvas(pos) );
|
|
}
|
|
|
|
m_curr_polyline_pos = pos;
|
|
}
|
|
|
|
//-------------------------------------------------------------//
|
|
|
|
void QSDrv::endPolyline2()
|
|
{
|
|
endPolyline();
|
|
}
|
|
|
|
//-------------------------------------------------------------//
|
|
|
|
QSPt2f QSDrv::currPolylinePos2()
|
|
{
|
|
return m_curr_polyline_pos;
|
|
}
|
|
|
|
//-------------------------------------------------------------//
|
|
|
|
void QSDrv::setPolylineLabelPlace2( const QString& label, const QSPt2f& label_place, int angle )
|
|
{
|
|
if ( !label.isEmpty() ) {
|
|
QSPt2f size = rTextSize( angle, label );
|
|
m_polyline_label_size = size;
|
|
m_polyline_label_pos = m_t->world2DToCanvas( label_place );
|
|
m_polyline_label_pos.x -= size.x/2.0;
|
|
m_polyline_label_pos.y -= size.y/2.0;
|
|
} else {
|
|
m_polyline_label_size = QSPt2f();
|
|
}
|
|
}
|
|
|
|
//-------------------------------------------------------------//
|
|
|
|
QSProjection::ClipResult QSDrv::clip_poly( const QSPt2f *pts, int npoints, const bool edges[] )
|
|
{
|
|
int clip_buff_size = npoints<<2;
|
|
if ( clip_buff_size > m_max_cpts2 ) { delete[] m_cpts2; m_max_cpts2 = clip_buff_size; m_cpts2 = new QSPt2f[m_max_cpts2]; }
|
|
if ( clip_buff_size > m_max_cedges ) { delete[] m_cedges; m_max_cedges = clip_buff_size; m_cedges = new bool[m_max_cedges]; }
|
|
|
|
return m_t->clipPoly2( pts, npoints, m_cpts2, &m_ncpts2, m_max_cpts2, m_cedges, edges );
|
|
}
|
|
|
|
//-------------------------------------------------------------//
|
|
|
|
QSProjection::ClipResult QSDrv::clip_poly( const QSPt3f *pts, int npoints, const bool edges[] )
|
|
{
|
|
int clip_buff_size = npoints<<2;
|
|
if ( clip_buff_size > m_max_cpts3 ) { delete[] m_cpts3; m_max_cpts3 = clip_buff_size; m_cpts3 = new QSPt3f[m_max_cpts3]; }
|
|
if ( clip_buff_size > m_max_cedges ) { delete[] m_cedges; m_max_cedges = clip_buff_size; m_cedges = new bool[m_max_cedges]; }
|
|
|
|
QSPt3f bbox[2]; m_t->getPoly3Cube( pts, npoints, bbox );
|
|
return m_t->clipPoly3( pts, npoints, m_cpts3, &m_ncpts3, m_max_cpts3, bbox, m_cedges, edges );
|
|
}
|
|
|
|
//-------------------------------------------------------------//
|
|
|
|
void QSDrv::map_to_screen( const QSPt2f *pts, int npoints )
|
|
{
|
|
if ( npoints > m_max_pts ) { delete[] m_pts; m_max_pts = npoints; m_pts = new QSPt2f[m_max_pts]; }
|
|
for( int i=0; i<npoints; i++ ) m_pts[i] = m_t->world2DToCanvas( pts[i] );
|
|
}
|
|
|
|
//-------------------------------------------------------------//
|
|
|
|
void QSDrv::map_to_screen( const QSPt3f *pts, int npoints )
|
|
{
|
|
if ( npoints > m_max_pts ) { delete[] m_pts; m_max_pts = npoints; m_pts = new QSPt2f[m_max_pts]; }
|
|
for( int i=0; i<npoints; i++ ) m_pts[i] = m_t->world3DToCanvas( pts[i] );
|
|
}
|
|
|
|
//-------------------------------------------------------------//
|
|
|
|
void QSDrv::copySettingsFrom( const QSDrv *drv )
|
|
{
|
|
setProjection( drv->projection() );
|
|
}
|
|
|
|
|
|
/**
|
|
* Converts points (1/72 inch) to pixels - "pixels = points*dpi/72".
|
|
* All fixed sizes must be converted by this function.
|
|
* There must not be fixed pixel-sizes !
|
|
* ( all legend sizes, spaces, shadows shifts etc must have its fixed size in points )
|
|
*/
|
|
//inline int toPixels( int points ) { return int(QSCoord::pointsToPixels(points,dpi)+0.5); }
|
|
|
|
|
|
/*
|
|
|
|
//if ( cl != l ) setLine( cl );
|
|
//if ( cf != f ) setFill( cf );
|
|
|
|
//if ( cf != f ) setFill( cf );
|
|
//if ( cl != l ) setLine( cl );
|
|
|
|
|
|
//if ( cl != l ) setLine( l );
|
|
//if ( cf != f ) setFill( f );
|
|
|
|
// QSGFill cf = currentFill();
|
|
*/
|