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.
578 lines
16 KiB
578 lines
16 KiB
13 years ago
|
/***************************************************************************
|
||
|
qsgattr.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 "qsgattr.h"
|
||
|
#include "qstringlist.h"
|
||
|
#include<math.h>
|
||
|
|
||
|
//-------------------------------------------------------------//
|
||
|
//-------------------------------------------------------------//
|
||
|
//-------------------------------------------------------------//
|
||
|
//-------------------------------------------------------------//
|
||
|
//-------------------------------------------------------------//
|
||
|
|
||
|
QSGColor::QSGColor()
|
||
|
: r(0U), g(0U), b(0U), a(255U)
|
||
|
{
|
||
|
}
|
||
|
|
||
|
//-------------------------------------------------------------//
|
||
|
|
||
|
QSGColor::QSGColor( unsigned char red,
|
||
|
unsigned char green,
|
||
|
unsigned char blue,
|
||
|
unsigned char alpha )
|
||
|
: r(red), g(green), b(blue), a(alpha)
|
||
|
{
|
||
|
}
|
||
|
|
||
|
//-------------------------------------------------------------//
|
||
|
|
||
|
const QSGColor &QSGColor::set( unsigned char red,
|
||
|
unsigned char green,
|
||
|
unsigned char blue,
|
||
|
unsigned char alpha )
|
||
|
{
|
||
|
r = red; g = green; b = blue; a = alpha;
|
||
|
return *this;
|
||
|
}
|
||
|
|
||
|
//-------------------------------------------------------------//
|
||
|
|
||
|
bool operator==( const QSGColor& c1, const QSGColor& c2 )
|
||
|
{
|
||
|
return c1.r == c2.r &&
|
||
|
c1.g == c2.g &&
|
||
|
c1.b == c2.b &&
|
||
|
c1.a == c2.a;
|
||
|
}
|
||
|
|
||
|
//-------------------------------------------------------------//
|
||
|
|
||
|
bool operator!=( const QSGColor& c1, const QSGColor& c2 )
|
||
|
{
|
||
|
return !(c1 == c2);
|
||
|
}
|
||
|
|
||
|
//-----------------------------------------------------------//
|
||
|
|
||
|
QString toQString( const QSGColor& c )
|
||
|
{
|
||
|
QString s;
|
||
|
return s.sprintf("%.2x%.2x%.2x%.2x", c.a, c.r, c.g, c.b );
|
||
|
}
|
||
|
|
||
|
//-----------------------------------------------------------//
|
||
|
|
||
|
QSGColor toQSGColor( const QString& s )
|
||
|
{
|
||
|
unsigned long value = s.toULong( NULL, 16 );
|
||
|
QSGColor c;
|
||
|
c.a = (unsigned char )((value & 0xFF000000 ) >> 24 );
|
||
|
c.r = (unsigned char )((value & 0x00FF0000 ) >> 16 );
|
||
|
c.g = (unsigned char )((value & 0x0000FF00 ) >> 8 );
|
||
|
c.b = (unsigned char )((value & 0x000000FF ) );
|
||
|
return c;
|
||
|
}
|
||
|
|
||
|
//-------------------------------------------------------------//
|
||
|
|
||
|
/*
|
||
|
ostream& operator<<( ostream& s, QSGColor &color )
|
||
|
{
|
||
|
s << "(" << int(color.r) << "," << int(color.g) << "," << int(color.b) << "," << int(color.a) << ")";
|
||
|
return s;
|
||
|
}
|
||
|
*/
|
||
|
|
||
|
//-------------------------------------------------------------//
|
||
|
//-------------------------------------------------------------//
|
||
|
//-------------------------------------------------------------//
|
||
|
//-------------------------------------------------------------//
|
||
|
|
||
|
const QSGFill QSGFill::transparentFill = QSGFill(QSGFill::Transparent);
|
||
|
|
||
|
QSGFill::QSGFill()
|
||
|
{
|
||
|
// default fill
|
||
|
style = Solid;
|
||
|
color = QSGColor( 255, 255, 255 );
|
||
|
}
|
||
|
|
||
|
//-------------------------------------------------------------//
|
||
|
|
||
|
QSGFill::QSGFill( Style init_style )
|
||
|
{
|
||
|
style = init_style;
|
||
|
}
|
||
|
|
||
|
//-------------------------------------------------------------//
|
||
|
|
||
|
bool operator==( const QSGFill& f1, const QSGFill& f2 )
|
||
|
{
|
||
|
return f1.style == f2.style && f1.color == f2.color;
|
||
|
}
|
||
|
|
||
|
//-------------------------------------------------------------//
|
||
|
|
||
|
bool operator!=( const QSGFill& f1, const QSGFill& f2 )
|
||
|
{
|
||
|
return !(f1 == f2);
|
||
|
}
|
||
|
|
||
|
//-------------------------------------------------------------//
|
||
|
|
||
|
QString toQString( const QSGFill& fill )
|
||
|
{
|
||
|
return QString::number(fill.style) + "; " + toQString(fill.color) + ";";
|
||
|
}
|
||
|
|
||
|
//-------------------------------------------------------------//
|
||
|
|
||
|
QSGFill toQSGFill( const QString& string )
|
||
|
{
|
||
|
QStringList args = QStringList::split( ";", string, TRUE );
|
||
|
QSGFill result;
|
||
|
result.style = (QSGFill::Style )args[0].toInt();
|
||
|
result.color = toQSGColor(args[1]);
|
||
|
return result;
|
||
|
}
|
||
|
|
||
|
//-------------------------------------------------------------//
|
||
|
/*
|
||
|
ostream& operator<<( ostream& s, QSGFill &fill )
|
||
|
{
|
||
|
s << "(" << int(fill.style) << "," << fill.color << ")";
|
||
|
return s;
|
||
|
}
|
||
|
*/
|
||
|
|
||
|
//-------------------------------------------------------------//
|
||
|
//-------------------------------------------------------------//
|
||
|
//-------------------------------------------------------------//
|
||
|
//-------------------------------------------------------------//
|
||
|
|
||
|
QSGFont::QSGFont()
|
||
|
:family("helvetica"), size(10), bold(false), italic(false)
|
||
|
{
|
||
|
color = QSGColor( 0, 0, 0 );
|
||
|
}
|
||
|
|
||
|
//-------------------------------------------------------------//
|
||
|
|
||
|
QSGFont::QSGFont( const QSGFont& f )
|
||
|
{
|
||
|
operator=( f );
|
||
|
}
|
||
|
|
||
|
//-------------------------------------------------------------//
|
||
|
|
||
|
void QSGFont::operator=( const QSGFont& f )
|
||
|
{
|
||
|
family = f.family;
|
||
|
color = f.color;
|
||
|
size = f.size;
|
||
|
bold = f.bold;
|
||
|
italic = f.italic;
|
||
|
}
|
||
|
|
||
|
//-------------------------------------------------------------//
|
||
|
|
||
|
bool operator==( const QSGFont& f1, const QSGFont& f2 )
|
||
|
{
|
||
|
return f1.size == f2.size &&
|
||
|
f1.bold == f2.bold &&
|
||
|
f1.italic == f2.italic &&
|
||
|
f1.color == f2.color &&
|
||
|
f1.family == f2.family ;
|
||
|
}
|
||
|
|
||
|
//-------------------------------------------------------------//
|
||
|
|
||
|
bool operator!=( const QSGFont& f1, const QSGFont& f2 )
|
||
|
{
|
||
|
return !(f1 == f2);
|
||
|
}
|
||
|
|
||
|
//-------------------------------------------------------------//
|
||
|
|
||
|
QString toQString( const QSGFont& font )
|
||
|
{
|
||
|
return font.family + "; " + QString::number(font.size) + "; " + QString::number(font.bold) + "; " +
|
||
|
QString::number(font.italic) + "; " + toQString(font.color) + ";";
|
||
|
}
|
||
|
|
||
|
//-------------------------------------------------------------//
|
||
|
|
||
|
QSGFont toQSGFont( const QString& string )
|
||
|
{
|
||
|
QSGFont result;
|
||
|
QStringList args = QStringList::split( ";", string, TRUE );
|
||
|
result.family = args[0].stripWhiteSpace();
|
||
|
result.size = args[1].toInt();
|
||
|
result.bold = (bool )args[2].toInt();
|
||
|
result.italic = (bool )args[3].toInt();
|
||
|
result.color = toQSGColor(args[4]);
|
||
|
return result;
|
||
|
}
|
||
|
|
||
|
//-------------------------------------------------------------//
|
||
|
|
||
|
/*
|
||
|
ostream& operator<<( ostream& s, QSGFont &font )
|
||
|
{
|
||
|
s << "(" << font.family << "," << font.size << "," << font.bold << "," << font.italic << "," << font.color << ")";
|
||
|
return s;
|
||
|
}
|
||
|
*/
|
||
|
|
||
|
//-------------------------------------------------------------//
|
||
|
//-------------------------------------------------------------//
|
||
|
//-------------------------------------------------------------//
|
||
|
//-------------------------------------------------------------//
|
||
|
|
||
|
const QSGLine QSGLine::invisibleLine = QSGLine(QSGLine::Invisible);
|
||
|
|
||
|
QSGLine::QSGLine()
|
||
|
{
|
||
|
// default fill
|
||
|
style = Solid;
|
||
|
width = 0;
|
||
|
// color = QSGColor( 0, 0, 0 );
|
||
|
}
|
||
|
|
||
|
//-------------------------------------------------------------//
|
||
|
|
||
|
QSGLine::QSGLine( Style init_style )
|
||
|
{
|
||
|
style = init_style;
|
||
|
width = 0;
|
||
|
}
|
||
|
|
||
|
//-------------------------------------------------------------//
|
||
|
|
||
|
bool operator==( const QSGLine& l1, const QSGLine& l2 )
|
||
|
{
|
||
|
return l1.color == l2.color &&
|
||
|
l1.style == l2.style &&
|
||
|
l1.width == l2.width ;
|
||
|
}
|
||
|
|
||
|
//-------------------------------------------------------------//
|
||
|
|
||
|
bool operator!=( const QSGLine& l1, const QSGLine& l2 )
|
||
|
{
|
||
|
return !(l1 == l2);
|
||
|
}
|
||
|
|
||
|
//-------------------------------------------------------------//
|
||
|
|
||
|
QString toQString( const QSGLine& line )
|
||
|
{
|
||
|
return QString::number(line.style) + "; " + QString::number(line.width) + "; " + toQString(line.color)+";";
|
||
|
}
|
||
|
|
||
|
//-------------------------------------------------------------//
|
||
|
|
||
|
QSGLine toQSGLine( const QString& string )
|
||
|
{
|
||
|
QStringList args = QStringList::split( ";", string, TRUE );
|
||
|
QSGLine result;
|
||
|
result.style = (QSGLine::Style )args[0].toInt();
|
||
|
result.width = args[1].toInt();
|
||
|
result.color = toQSGColor(args[2]);
|
||
|
return result;
|
||
|
}
|
||
|
|
||
|
//-------------------------------------------------------------//
|
||
|
|
||
|
/*
|
||
|
ostream& operator<<( ostream& s, QSGLine &line )
|
||
|
{
|
||
|
s << "(" << int(line.style) << "," << line.width << "," << line.color << ")";
|
||
|
return s;
|
||
|
}
|
||
|
*/
|
||
|
|
||
|
//-------------------------------------------------------------//
|
||
|
//-------------------------------------------------------------//
|
||
|
//-------------------------------------------------------------//
|
||
|
//-------------------------------------------------------------//
|
||
|
|
||
|
QSGPoint::QSGPoint()
|
||
|
{
|
||
|
style = Invisible;
|
||
|
fill = Transparent;
|
||
|
size = 9;
|
||
|
}
|
||
|
|
||
|
//-------------------------------------------------------------//
|
||
|
|
||
|
bool operator==( const QSGPoint& p1, const QSGPoint& p2 )
|
||
|
{
|
||
|
return p1.style == p2.style && p1.fill == p2.fill && p1.size == p2.size && p1.color == p2.color;
|
||
|
}
|
||
|
|
||
|
//-------------------------------------------------------------//
|
||
|
|
||
|
bool operator!=( const QSGPoint& p1, const QSGPoint& p2 )
|
||
|
{
|
||
|
return !operator==(p1,p2);
|
||
|
}
|
||
|
|
||
|
//-------------------------------------------------------------//
|
||
|
|
||
|
QString toQString( const QSGPoint& point )
|
||
|
{
|
||
|
return QString::number(point.style) + "; " + QString::number(point.fill) + "; " + QString::number(point.size) + "; " + toQString(point.color) + ";";
|
||
|
}
|
||
|
|
||
|
//-------------------------------------------------------------//
|
||
|
|
||
|
QSGPoint toQSGPoint( const QString& string )
|
||
|
{
|
||
|
QStringList args = QStringList::split( ";", string, TRUE );
|
||
|
QSGPoint result;
|
||
|
result.style = (QSGPoint::Style )args[0].toInt();
|
||
|
result.fill = (QSGPoint::Fill )args[1].toInt();
|
||
|
result.size = args[2].toInt();
|
||
|
result.color = toQSGColor(args[3]);
|
||
|
return result;
|
||
|
}
|
||
|
|
||
|
//-------------------------------------------------------------//
|
||
|
//-------------------------------------------------------------//
|
||
|
//-------------------------------------------------------------//
|
||
|
//-------------------------------------------------------------//
|
||
|
|
||
|
QSGArrow::QSGArrow()
|
||
|
{
|
||
|
style = None;
|
||
|
size = 3;
|
||
|
}
|
||
|
|
||
|
//-------------------------------------------------------------//
|
||
|
|
||
|
bool operator==( const QSGArrow& a1, const QSGArrow& a2 )
|
||
|
{
|
||
|
return a1.style == a2.style && a1.size == a2.size;
|
||
|
}
|
||
|
|
||
|
//-------------------------------------------------------------//
|
||
|
|
||
|
bool operator!=( const QSGArrow& a1, const QSGArrow& a2 )
|
||
|
{
|
||
|
return !(a1 == a2);
|
||
|
}
|
||
|
|
||
|
//-------------------------------------------------------------//
|
||
|
|
||
|
QString toQString( const QSGArrow& arrow )
|
||
|
{
|
||
|
return QString::number(arrow.style) + "; " + QString::number(arrow.size) + "; ";
|
||
|
}
|
||
|
|
||
|
//-------------------------------------------------------------//
|
||
|
|
||
|
QSGArrow toQSGArrow( const QString& string )
|
||
|
{
|
||
|
QSGArrow result;
|
||
|
QStringList args = QStringList::split( ";", string, TRUE );
|
||
|
result.style = (QSGArrow::Style )args[0].toInt();
|
||
|
result.size = args[1].toInt();
|
||
|
return result;
|
||
|
|
||
|
}
|
||
|
|
||
|
//-------------------------------------------------------------//
|
||
|
|
||
|
//-----------------------------------------------------------//
|
||
|
//-----------------------------------------------------------//
|
||
|
//-----------------------------------------------------------//
|
||
|
//-----------------------------------------------------------//
|
||
|
|
||
|
|
||
|
//-------------------------------------------------------------//
|
||
|
|
||
|
QString toQString( const QSGGradient& gradient )
|
||
|
{
|
||
|
return QString::number(gradient.t) + "| " +
|
||
|
toQString(gradient.f[0])+"| " +
|
||
|
toQString(gradient.f[1])+"| " +
|
||
|
toQString(gradient.f[2])+"| " +
|
||
|
toQString(gradient.f[3])+"| " +
|
||
|
toQString(gradient.f[4])+"| ";
|
||
|
}
|
||
|
|
||
|
//-------------------------------------------------------------//
|
||
|
|
||
|
QSGGradient toQSGGradient( const QString& string )
|
||
|
{
|
||
|
QStringList args = QStringList::split( "|", string, TRUE );
|
||
|
QSGGradient result;
|
||
|
result.t = (QSGGradient::Type )args[0].toInt();
|
||
|
result.f[0] = toQSGFill(args[1]);
|
||
|
result.f[1] = toQSGFill(args[2]);
|
||
|
result.f[2] = toQSGFill(args[3]);
|
||
|
result.f[3] = toQSGFill(args[4]);
|
||
|
result.f[4] = toQSGFill(args[5]);
|
||
|
return result;
|
||
|
}
|
||
|
|
||
|
//-----------------------------------------------------------//
|
||
|
|
||
|
bool operator==( const QSGGradient& g1, const QSGGradient& g2 )
|
||
|
{
|
||
|
return g1.isEqualTo( g2 );
|
||
|
}
|
||
|
|
||
|
//-----------------------------------------------------------//
|
||
|
|
||
|
bool operator!=( const QSGGradient& g1, const QSGGradient& g2 )
|
||
|
{
|
||
|
return !g1.isEqualTo( g2 );
|
||
|
}
|
||
|
|
||
|
|
||
|
//-------------------------------------------------------------//
|
||
|
|
||
|
QSGGradient::QSGGradient( Type init_t )
|
||
|
{
|
||
|
t = init_t;
|
||
|
set_default_colors();
|
||
|
}
|
||
|
|
||
|
//-------------------------------------------------------------//
|
||
|
|
||
|
QSGGradient::QSGGradient( const QSGFill& f0, const QSGFill& f4 )
|
||
|
{
|
||
|
f[0] = f0;
|
||
|
f[4] = f4;
|
||
|
t = GTwoColors;
|
||
|
}
|
||
|
|
||
|
//-------------------------------------------------------------//
|
||
|
|
||
|
QSGGradient::QSGGradient( const QSGFill& f0, const QSGFill& f1, const QSGFill& f2, const QSGFill& f3, const QSGFill& f4, Type init_t )
|
||
|
{
|
||
|
t = init_t;
|
||
|
set_default_colors();
|
||
|
if ( t == GFiveColors || t == GTwoColors ) {
|
||
|
f[0] = f0;
|
||
|
f[1] = f1;
|
||
|
f[2] = f2;
|
||
|
f[3] = f3;
|
||
|
f[4] = f4;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
//-------------------------------------------------------------//
|
||
|
|
||
|
QSGGradient::~QSGGradient()
|
||
|
{
|
||
|
}
|
||
|
|
||
|
//-------------------------------------------------------------//
|
||
|
|
||
|
QSGFill& QSGGradient::fill( double level, QSGFill& result ) const
|
||
|
{
|
||
|
level = QMAX( level, 0.0 );
|
||
|
level = QMIN( level, 1.0 );
|
||
|
|
||
|
if ( t == GTwoColors || t == GGray ) {
|
||
|
result.style = level < 0.5 ? f[0].style : f[4].style;
|
||
|
result.color.r = (unsigned char )(f[0].color.r + level * ( f[4].color.r - f[0].color.r ));
|
||
|
result.color.g = (unsigned char )(f[0].color.g + level * ( f[4].color.g - f[0].color.g ));
|
||
|
result.color.b = (unsigned char )(f[0].color.b + level * ( f[4].color.b - f[0].color.b ));
|
||
|
result.color.a = (unsigned char )(f[0].color.a + level * ( f[4].color.a - f[0].color.a ));;
|
||
|
} else {
|
||
|
int temp = (int )floor( level * 4.0 * 256.0 + 0.5 );
|
||
|
|
||
|
unsigned int level = (unsigned int )QMIN( QMAX(temp, 0), 4*256 );
|
||
|
unsigned int col_num = level >> 8; // divide by 256
|
||
|
unsigned int col_rem = level & 0x0ff; // remainder 0-255
|
||
|
|
||
|
result.style = f[col_num].style;
|
||
|
const QSGColor& c0 = f[col_num].color;
|
||
|
const QSGColor& c1 = f[QMIN(col_num+1,4)].color;
|
||
|
|
||
|
// interpolate colors
|
||
|
result.color.r = ( c0.r * (256U - col_rem) + c1.r * col_rem ) >> 8;
|
||
|
result.color.g = ( c0.g * (256U - col_rem) + c1.g * col_rem ) >> 8;
|
||
|
result.color.b = ( c0.b * (256U - col_rem) + c1.b * col_rem ) >> 8;
|
||
|
result.color.a = ( c0.a * (256U - col_rem) + c1.a * col_rem ) >> 8;
|
||
|
}
|
||
|
|
||
|
return result;
|
||
|
}
|
||
|
|
||
|
//-------------------------------------------------------------//
|
||
|
|
||
|
bool QSGGradient::isEqualTo( const QSGGradient& gradient ) const
|
||
|
{
|
||
|
if ( gradient.fill(0) == f[0] &&
|
||
|
gradient.fill(1) == f[1] &&
|
||
|
gradient.fill(2) == f[2] &&
|
||
|
gradient.fill(3) == f[3] &&
|
||
|
gradient.fill(4) == f[4] &&
|
||
|
gradient.type() == t ) return true;
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
//-------------------------------------------------------------//
|
||
|
|
||
|
void QSGGradient::set_default_colors()
|
||
|
{
|
||
|
if ( t == GTwoColors || t == GGray ) {
|
||
|
f[0].color.set( 128, 128, 128 );
|
||
|
f[4].color.set( 240, 240, 240 );
|
||
|
}
|
||
|
else if ( t == GFiveColors || t == GDefault ) {
|
||
|
f[0].color.set( 0, 0, 128 );
|
||
|
f[1].color.set( 0, 128, 0 );
|
||
|
f[2].color.set( 255, 0, 0 );
|
||
|
f[3].color.set( 255, 160, 0 );
|
||
|
f[4].color.set( 255, 255, 196 );
|
||
|
}
|
||
|
else if ( t == GStrange ) {
|
||
|
f[0].color.set( 128, 0, 128 );
|
||
|
f[1].color.set( 128, 128, 0 );
|
||
|
f[2].color.set( 0, 255, 0 );
|
||
|
f[3].color.set( 0, 255, 255 );
|
||
|
f[4].color.set( 255, 255, 255 );
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
//-------------------------------------------------------------//
|
||
|
/**
|
||
|
* Gradient
|
||
|
* @author Kamil Dobkowski
|
||
|
|
||
|
class QSGGradient : public QSGAttr {
|
||
|
public:
|
||
|
QSGGradient() {}
|
||
|
virtual ~QSGGradient() {};
|
||
|
virtual QSGFill& fill( double level, QSGFill& fill ) const;
|
||
|
virtual bool isEqualTo( const QSGGradient& gradient ) const;
|
||
|
friend bool operator==( const QSGGradient&, const QSGGradient& );
|
||
|
friend bool operator!=( const QSGGradient&, const QSGGradient& );
|
||
|
};
|
||
|
*/
|
||
|
|