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.
480 lines
11 KiB
480 lines
11 KiB
/*
|
|
* Copyright (C) 2000-2001 theKompany.com & Dave Marotti
|
|
*
|
|
* 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.
|
|
*
|
|
* This program is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with this program; if not, write to the Free Software
|
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|
*/
|
|
#include "qsruler.h"
|
|
#include <stdlib.h>
|
|
#include <math.h>
|
|
|
|
//------------------------------------------------------------//
|
|
|
|
/*
|
|
* Functions for converting
|
|
* Point <-> Inch <-> Millimeter<-> Pica <-> Centimetre <-> Didot <-> Cicero
|
|
* 1 Inch = 72 pt = 6 pica = 25.4 mm = 67.54151050 dd = 5.628459208 cc
|
|
*/
|
|
|
|
float cvtPtToMm(float value)
|
|
{
|
|
return 25.4 * value / 72.0;
|
|
}
|
|
//------------------------------------------------------------//
|
|
float cvtPtToCm(float value)
|
|
{
|
|
return 2.54 * value / 72.0;
|
|
}
|
|
//------------------------------------------------------------//
|
|
float cvtPtToPica(float value)
|
|
{
|
|
return value / 12.0;
|
|
}
|
|
//------------------------------------------------------------//
|
|
float cvtPicaToPt(float value)
|
|
{
|
|
return value * 12.0;
|
|
}
|
|
//------------------------------------------------------------//
|
|
float cvtPtToInch(float value)
|
|
{
|
|
return value / 72.0;
|
|
}
|
|
//------------------------------------------------------------//
|
|
|
|
float cvtPtToDidot(float value)
|
|
{
|
|
return value * 1238.0 / 1157.0; // 1157 dd = 1238 pt
|
|
}
|
|
|
|
//------------------------------------------------------------//
|
|
|
|
float cvtPtToCicero(float value)
|
|
{
|
|
return value * 1238.0 / (1157.0 * 12.0); // 1 cc = 12 dd
|
|
}
|
|
|
|
//------------------------------------------------------------//
|
|
|
|
float cvtInchToPt(float value)
|
|
{
|
|
return value * 72.0;
|
|
}
|
|
|
|
//------------------------------------------------------------//
|
|
|
|
float cvtMmToPt(float value)
|
|
{
|
|
return value / 25.4 * 72.0;
|
|
}
|
|
|
|
//------------------------------------------------------------//
|
|
|
|
float cvtCmToPt(float value)
|
|
{
|
|
return value / 2.54 * 72.0;
|
|
}
|
|
|
|
//------------------------------------------------------------//
|
|
|
|
float cvtDidotToPt(float value)
|
|
{
|
|
return value * 1157.0 / 1238.0;
|
|
}
|
|
|
|
//------------------------------------------------------------//
|
|
|
|
float cvtCiceroToPt(float value)
|
|
{
|
|
return value * (1157.0 * 12.0) / 1238.0;
|
|
}
|
|
|
|
//------------------------------------------------------------//
|
|
|
|
float cvtPtToUnit(int unit, float value)
|
|
{
|
|
switch (unit) {
|
|
case UnitMillimeter:
|
|
return cvtPtToMm (value);
|
|
break;
|
|
case UnitPica:
|
|
return cvtPtToPica (value);
|
|
break;
|
|
case UnitInch:
|
|
return cvtPtToInch (value);
|
|
break;
|
|
case UnitCentimeter:
|
|
return cvtPtToCm (value);
|
|
break;
|
|
case UnitDidot:
|
|
return cvtPtToDidot (value);
|
|
break;
|
|
case UnitCicero:
|
|
return cvtPtToCicero (value);
|
|
break;
|
|
default:
|
|
return value;
|
|
}
|
|
}
|
|
|
|
//------------------------------------------------------------//
|
|
|
|
float cvtUnitToPt(int unit, float value)
|
|
{
|
|
switch (unit) {
|
|
case UnitMillimeter:
|
|
return cvtMmToPt (value);
|
|
break;
|
|
case UnitInch:
|
|
return cvtInchToPt (value);
|
|
break;
|
|
case UnitCentimeter:
|
|
return cvtCmToPt (value);
|
|
break;
|
|
case UnitDidot:
|
|
return cvtDidotToPt (value);
|
|
break;
|
|
case UnitPica:
|
|
return cvtPicaToPt (value);
|
|
break;
|
|
case UnitCicero:
|
|
return cvtCiceroToPt (value);
|
|
break;
|
|
default:
|
|
return value;
|
|
}
|
|
}
|
|
|
|
//------------------------------------------------------------//
|
|
|
|
#define MARKER_WIDTH 1
|
|
#define MARKER_HEIGHT 20
|
|
|
|
#define RULER_SIZE 20
|
|
|
|
QSRuler::QSRuler(Orientation o, QWidget *parent, const char *name)
|
|
: QFrame(parent, name, WRepaintNoErase | WResizeNoErase )
|
|
{
|
|
setBackgroundMode(NoBackground);
|
|
setFrameStyle(Box | Sunken/*Raised*/);
|
|
setLineWidth(1);
|
|
setMidLineWidth(0);
|
|
orientation = o;
|
|
munit = UnitPoint;
|
|
m_pZoom = 1.0;
|
|
firstVisible = 0;
|
|
buffer = 0L;
|
|
currentPosition = -1;
|
|
|
|
if (orientation == Horizontal) {
|
|
setFixedHeight(RULER_SIZE);
|
|
initMarker(MARKER_WIDTH, MARKER_HEIGHT);
|
|
} else {
|
|
setFixedWidth(RULER_SIZE);
|
|
initMarker(MARKER_HEIGHT, MARKER_WIDTH);
|
|
}
|
|
|
|
const char* nums[] = {
|
|
"70 7 2 1",
|
|
" c Black",
|
|
"X c None",
|
|
"XX XXXXXX XXXX XXXX XXXXXX XXX XXXX XXX XXX XXXX XX",
|
|
"X XXX XXXX XXX XXX XX XXX XXXX XXX XXXXXXX XXXXXXXXX XX XXX XX XXX X",
|
|
"X XXX XXXXX XXXXXXX XXXXXX XXX X XXX XXXXXX XXXXXXXXX XXX XXX XX XXX X",
|
|
"X XXX XXXXX XXXXX XXXXX XXX XX XXX XXX XXXXXX XXXX XXXX X",
|
|
"X XXX XXXXX XXXX XXXXXXXXX XX XXXXXX XX XXX XXXX XXXX XXX XXXXXX X",
|
|
"X XXX XXXXX XXX XXXXXX XXX XXXXX XXXXXXX XX XXX XXXX XXXX XXX XXXXX XX",
|
|
"XX XXXXXX XXX XXX XXXXXX XXX XXXX XXXXX XXXXX XXXX XXX"
|
|
};
|
|
m_pNums = new QPixmap(nums);
|
|
}
|
|
|
|
QSRuler::~QSRuler()
|
|
{
|
|
if (buffer)
|
|
delete buffer;
|
|
|
|
delete marker;
|
|
delete m_pNums;
|
|
}
|
|
|
|
void QSRuler::initMarker(int w, int h)
|
|
{
|
|
QPainter p;
|
|
marker = new QPixmap(w,h);
|
|
p.begin(marker);
|
|
p.setPen(blue);
|
|
p.eraseRect(0, 0, w, h);
|
|
p.drawLine(0,0,w-1,h-1);
|
|
p.end();
|
|
}
|
|
|
|
void QSRuler::recalculateSize(QResizeEvent*)
|
|
{
|
|
if (buffer) {
|
|
delete buffer;
|
|
buffer = 0L;
|
|
}
|
|
|
|
int w, h;
|
|
|
|
if (orientation == Horizontal) {
|
|
w = width();
|
|
h = RULER_SIZE;
|
|
} else {
|
|
w = RULER_SIZE;
|
|
h = height();
|
|
}
|
|
buffer = new QPixmap(w, h);
|
|
drawQSRuler();
|
|
updatePointer(currentPosition,currentPosition);
|
|
}
|
|
|
|
int QSRuler::unit()
|
|
{
|
|
return munit;
|
|
}
|
|
|
|
void QSRuler::setUnit(int u)
|
|
{
|
|
munit = u;
|
|
drawQSRuler();
|
|
updatePointer(currentPosition,currentPosition);
|
|
repaint();
|
|
}
|
|
|
|
void QSRuler::setZoom(float zoom)
|
|
{
|
|
if ( m_pZoom != zoom ) {
|
|
m_pZoom = zoom;
|
|
recalculateSize(0L);
|
|
//drawQSRuler();
|
|
update();
|
|
//updatePointer(currentPosition, currentPosition);
|
|
//repaint();
|
|
}
|
|
}
|
|
|
|
void QSRuler::updatePointer(int x, int y )
|
|
{
|
|
if (! buffer)
|
|
return;
|
|
|
|
if (orientation == Horizontal) {
|
|
if (currentPosition != -1) {
|
|
repaint(QRect(currentPosition, 1, MARKER_WIDTH, MARKER_HEIGHT));
|
|
}
|
|
if (x != -1) {
|
|
bitBlt(this, x, 1, marker, 0, 0, MARKER_WIDTH, MARKER_HEIGHT);
|
|
currentPosition = x;
|
|
}
|
|
} else {
|
|
if (currentPosition != -1) {
|
|
repaint(QRect (1, currentPosition, MARKER_HEIGHT, MARKER_WIDTH));
|
|
}
|
|
if (y != -1) {
|
|
bitBlt(this, 1, y, marker, 0, 0, MARKER_HEIGHT, MARKER_WIDTH);
|
|
currentPosition = y;
|
|
}
|
|
}
|
|
}
|
|
|
|
void QSRuler::updateVisibleArea( int xpos, int ypos )
|
|
{
|
|
if (orientation == Horizontal && firstVisible != xpos ) {
|
|
firstVisible = xpos;
|
|
drawQSRuler();
|
|
//repaint();
|
|
update();
|
|
}
|
|
else
|
|
if (orientation == Vertical && firstVisible != ypos ) {
|
|
firstVisible = ypos;
|
|
drawQSRuler();
|
|
update(); //repaint();
|
|
}
|
|
}
|
|
|
|
void QSRuler::paintEvent( QPaintEvent* e )
|
|
{
|
|
if (!buffer)
|
|
return;
|
|
|
|
const QRect& rect = e->rect();
|
|
|
|
if (orientation == Horizontal) {
|
|
bitBlt(this, rect.topLeft(), buffer, rect);
|
|
} else {
|
|
bitBlt(this, rect.topLeft(), buffer, rect);
|
|
}
|
|
|
|
QFrame::paintEvent(e);
|
|
}
|
|
|
|
void QSRuler::drawQSRuler()
|
|
{
|
|
QPainter p;
|
|
QString buf;
|
|
|
|
int st1 = 0;
|
|
int st2 = 0;
|
|
int st3 = 0;
|
|
int st4 = 0;
|
|
int stt = 0;
|
|
|
|
if (!buffer)
|
|
return;
|
|
|
|
p.begin(buffer);
|
|
p.setPen(QColor(0x70,0x70,0x70));
|
|
p.setBackgroundColor(colorGroup().background());
|
|
p.eraseRect(0, 0, buffer->width(), buffer->height());
|
|
|
|
switch (munit) {
|
|
case UnitPoint:
|
|
case UnitMillimeter:
|
|
case UnitDidot:
|
|
case UnitCicero:
|
|
st1 = 1;
|
|
st2 = 5;
|
|
st3 = 10;
|
|
st4 = 25;
|
|
stt = 5;
|
|
break;
|
|
case UnitCentimeter:
|
|
case UnitPica:
|
|
case UnitInch:
|
|
st1 = 1;
|
|
st2 = 2;
|
|
st3 = 5;
|
|
st4 = 10;
|
|
stt = 1;
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
|
|
if (orientation == Horizontal) {
|
|
int pos = 0;
|
|
bool s1 = cvtUnitToPt(munit,st1)*m_pZoom > 3.0;
|
|
bool s2 = cvtUnitToPt(munit,st2)*m_pZoom > 3.0;
|
|
bool s3 = cvtUnitToPt(munit,st3)*m_pZoom > 3.0;
|
|
bool s4 = cvtUnitToPt(munit,st4)*m_pZoom > 3.0;
|
|
|
|
float cx = cvtPtToUnit(munit,7*4)/m_pZoom;
|
|
int step = ((int)(cx/(float)stt)+1)*stt;
|
|
int start = (int)(cvtPtToUnit(munit,firstVisible)/m_pZoom);
|
|
|
|
do {
|
|
pos = (int)(cvtUnitToPt(munit,start)*m_pZoom - firstVisible);
|
|
|
|
if ( !s3 && s4 && start % st4 == 0 )
|
|
p.drawLine(pos,RULER_SIZE-9,pos,RULER_SIZE);
|
|
|
|
if ( s3 && start % st3 == 0 )
|
|
p.drawLine(pos,RULER_SIZE-9,pos,RULER_SIZE);
|
|
|
|
if ( s2 && start % st2 == 0 )
|
|
p.drawLine(pos,RULER_SIZE-7,pos,RULER_SIZE);
|
|
|
|
if ( s1 && start % st1 == 0 )
|
|
p.drawLine(pos,RULER_SIZE-5,pos,RULER_SIZE);
|
|
|
|
if ( start % step == 0 ) {
|
|
buf.setNum(abs(start));
|
|
drawNums(&p,pos,4,buf,true);
|
|
}
|
|
|
|
start++;
|
|
} while (pos < buffer->width());
|
|
|
|
} else {
|
|
int pos = 0;
|
|
bool s1 = cvtUnitToPt(munit,st1)*m_pZoom > 3.0;
|
|
bool s2 = cvtUnitToPt(munit,st2)*m_pZoom > 3.0;
|
|
bool s3 = cvtUnitToPt(munit,st3)*m_pZoom > 3.0;
|
|
bool s4 = cvtUnitToPt(munit,st4)*m_pZoom > 3.0;
|
|
|
|
float cx = cvtPtToUnit(munit,8*4)/m_pZoom;
|
|
int step = ((int)(cx/(float)stt)+1)*stt;
|
|
int start = (int)(cvtPtToUnit(munit,firstVisible)/m_pZoom);
|
|
|
|
do {
|
|
pos = (int)(cvtUnitToPt(munit,start)*m_pZoom - firstVisible);
|
|
|
|
if ( !s3 && s4 && start % st4 == 0 )
|
|
p.drawLine(RULER_SIZE-9,pos,RULER_SIZE,pos);
|
|
|
|
if ( s3 && start % st3 == 0 )
|
|
p.drawLine(RULER_SIZE-9,pos,RULER_SIZE,pos);
|
|
|
|
if ( s2 && start % st2 == 0 )
|
|
p.drawLine(RULER_SIZE-7,pos,RULER_SIZE,pos);
|
|
|
|
if ( s1 && start % st1 == 0 )
|
|
p.drawLine(RULER_SIZE-5,pos,RULER_SIZE,pos);
|
|
|
|
if ( start % step == 0 ) {
|
|
buf.setNum(abs(start));
|
|
drawNums(&p,4,pos,buf,false);
|
|
}
|
|
|
|
start++;
|
|
} while (pos < buffer->height());
|
|
}
|
|
p.end();
|
|
}
|
|
|
|
void QSRuler::resizeEvent(QResizeEvent* e)
|
|
{
|
|
recalculateSize(e);
|
|
}
|
|
|
|
void QSRuler::show()
|
|
{
|
|
if (orientation == Horizontal) {
|
|
setFixedHeight(RULER_SIZE);
|
|
initMarker(MARKER_WIDTH,MARKER_HEIGHT);
|
|
} else {
|
|
setFixedWidth(RULER_SIZE);
|
|
initMarker(MARKER_HEIGHT,MARKER_WIDTH);
|
|
}
|
|
QWidget::show();
|
|
}
|
|
|
|
void QSRuler::hide()
|
|
{
|
|
if (orientation == Horizontal)
|
|
setFixedHeight(1);
|
|
else
|
|
setFixedWidth(1);
|
|
}
|
|
|
|
void QSRuler::drawNums(QPainter* p, int x, int y, QString& num, bool orientationHoriz)
|
|
{
|
|
if (orientationHoriz)
|
|
x -= 7;
|
|
else
|
|
y -= 8;
|
|
|
|
for ( uint k = 0; k < num.length(); k++ ) {
|
|
int st = num.at(k).digitValue()*7;
|
|
p->drawPixmap(x,y,*m_pNums,st,0,7,7);
|
|
if (orientationHoriz)
|
|
x += 7;
|
|
else
|
|
y += 8;
|
|
}
|
|
}
|