|
|
|
/***************************************************************************
|
|
|
|
kookaprint.cpp - Printing from the gallery
|
|
|
|
-------------------
|
|
|
|
begin : Tue May 13 2003
|
|
|
|
copyright : (C) 1999 by Klaas Freitag
|
|
|
|
email : freitag@suse.de
|
|
|
|
***************************************************************************/
|
|
|
|
|
|
|
|
/***************************************************************************
|
|
|
|
* *
|
|
|
|
* This file may be distributed and/or modified under the terms of the *
|
|
|
|
* GNU General Public License version 2 as published by the Free Software *
|
|
|
|
* Foundation and appearing in the file COPYING included in the *
|
|
|
|
* packaging of this file. *
|
|
|
|
*
|
|
|
|
* As a special exception, permission is given to link this program *
|
|
|
|
* with any version of the KADMOS ocr/icr engine of reRecognition GmbH, *
|
|
|
|
* Kreuzlingen and distribute the resulting executable without *
|
|
|
|
* including the source code for KADMOS in the source distribution. *
|
|
|
|
*
|
|
|
|
* As a special exception, permission is given to link this program *
|
|
|
|
* with any edition of TQt, and distribute the resulting executable, *
|
|
|
|
* without including the source code for TQt in the source distribution. *
|
|
|
|
* *
|
|
|
|
***************************************************************************/
|
|
|
|
|
|
|
|
#include "kookaprint.h"
|
|
|
|
#include "kookaimage.h"
|
|
|
|
#include <kprinter.h>
|
|
|
|
#include <tqpainter.h>
|
|
|
|
#include <tqpaintdevicemetrics.h>
|
|
|
|
#include <tqfontmetrics.h>
|
|
|
|
#include "imgprintdialog.h"
|
|
|
|
#include <kdebug.h>
|
|
|
|
#include <klocale.h>
|
|
|
|
|
|
|
|
KookaPrint::KookaPrint( KPrinter *printer )
|
|
|
|
:TQObject(),
|
|
|
|
m_printer(printer),
|
|
|
|
m_extraMarginPercent(10)
|
|
|
|
{
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
bool KookaPrint::printImage( KookaImage *img )
|
|
|
|
{
|
|
|
|
bool result = true;
|
|
|
|
if( ! m_printer || !img) return false;
|
|
|
|
|
|
|
|
TQString psMode = m_printer->option( OPT_PSGEN_DRAFT );
|
|
|
|
kdDebug(28000) << "User setting for quality: " << psMode << endl;
|
|
|
|
|
|
|
|
#if 0
|
|
|
|
if( psMode == "1" )
|
|
|
|
m_printer->setResolution( 75 );
|
|
|
|
else
|
|
|
|
m_printer->setResolution( 600 );
|
|
|
|
#endif
|
|
|
|
|
|
|
|
/* Create painter _after_ setting Resolution */
|
|
|
|
TQPainter painter(m_printer);
|
|
|
|
m_painter = &painter;
|
|
|
|
KookaImage tmpImg;
|
|
|
|
TQPoint pt(0, 0); // the top-left corner (image will be centered)
|
|
|
|
|
|
|
|
// We use a TQPaintDeviceMetrics to know the actual page size in pixel,
|
|
|
|
// this gives the real painting area
|
|
|
|
TQPaintDeviceMetrics printermetrics( m_painter->device() );
|
|
|
|
|
|
|
|
int screenRes = m_printer->option( OPT_SCREEN_RES ).toInt();
|
|
|
|
// int printerRes = printermetrics.logicalDpiX();
|
|
|
|
int printerRes = m_printer->resolution();
|
|
|
|
|
|
|
|
TQString scale = m_printer->option( OPT_SCALING );
|
|
|
|
|
|
|
|
int reso = screenRes;
|
|
|
|
|
|
|
|
if( scale == "scan" )
|
|
|
|
{
|
|
|
|
/* Scale to original size */
|
|
|
|
reso = m_printer->option( OPT_SCAN_RES ).toInt();
|
|
|
|
}
|
|
|
|
else if( scale == "custom" )
|
|
|
|
{
|
|
|
|
// kdDebug(28000) << "Not yet implemented: Custom scale" << endl;
|
|
|
|
double userWidthInch = (m_printer->option( OPT_WIDTH ).toDouble() / 25.4 );
|
|
|
|
reso = int( double(img->width()) / userWidthInch );
|
|
|
|
|
|
|
|
kdDebug(28000) << "Custom resolution: " << reso << endl;
|
|
|
|
|
|
|
|
}
|
|
|
|
else if( scale == "fitpage" )
|
|
|
|
{
|
|
|
|
kdDebug(28000) << "Printing using maximum space on page" << endl;
|
|
|
|
printFittingToPage( img );
|
|
|
|
reso = 0; // to skip the printing on this page.
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Scale the image for printing */
|
|
|
|
kdDebug(28000) << "Printer-Resolution: " << printerRes << " and scale-Reso: " << reso << endl;
|
|
|
|
TQSize margins = m_printer->margins();
|
|
|
|
kdDebug(28000) << "Printer-Margins left: " << margins.width() << " and top " << margins.height()
|
|
|
|
<< endl;
|
|
|
|
if( reso > 0)
|
|
|
|
{
|
|
|
|
double sizeInch = double(img->width()) / double(reso);
|
|
|
|
int newWidth = int(sizeInch * printerRes);
|
|
|
|
|
|
|
|
printerRes = printermetrics.logicalDpiY();
|
|
|
|
sizeInch = double(img->height()) / double(reso);
|
|
|
|
int newHeight = int(sizeInch * printerRes );
|
|
|
|
|
|
|
|
kdDebug(28000) << "Scaling to printer size " << newWidth << " x " << newHeight << endl;
|
|
|
|
|
|
|
|
tmpImg = img->smoothScale(newWidth, newHeight, TQ_ScaleFree);
|
|
|
|
|
|
|
|
TQSize sz = tmpImg.size(); // the current image size
|
|
|
|
TQSize maxOnPage = maxPageSize(); // the maximum space on one side
|
|
|
|
|
|
|
|
int maxRows, maxCols;
|
|
|
|
int subpagesCnt = tmpImg.cutToTiles( maxOnPage, maxRows, maxCols );
|
|
|
|
|
|
|
|
kdDebug(28000) << "Subpages count: " << subpagesCnt <<
|
|
|
|
" Columns:" << maxCols << " Rows:" << maxRows << endl;
|
|
|
|
|
|
|
|
int cnt = 0;
|
|
|
|
|
|
|
|
for( int row = 0; row < maxRows; row++ )
|
|
|
|
{
|
|
|
|
for( int col = 0; col < maxCols; col++ )
|
|
|
|
{
|
|
|
|
const TQRect part = tmpImg.getTileRect( row, col );
|
|
|
|
const TQSize imgSize = part.size();
|
|
|
|
|
|
|
|
kdDebug(28000) << "Printing part from " << part.x() << "/" << part.y()
|
|
|
|
<< " width:"<< part.width() << " and height " << part.height() << endl;
|
|
|
|
TQImage tileImg = tmpImg.copy( part );
|
|
|
|
|
|
|
|
m_painter->drawImage( printPosTopLeft(imgSize), tileImg );
|
|
|
|
drawCornerMarker( imgSize, row, col, maxRows, maxCols );
|
|
|
|
cnt++;
|
|
|
|
if( cnt < subpagesCnt )
|
|
|
|
m_printer->newPage();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
m_painter = 0; // no, this is not a memory leak.
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
|
|
|
void KookaPrint::printFittingToPage(KookaImage *img)
|
|
|
|
{
|
|
|
|
if( ! img || ! m_painter ) return;
|
|
|
|
|
|
|
|
KookaImage tmpImg;
|
|
|
|
|
|
|
|
TQString psMode = m_printer->option( OPT_RATIO );
|
|
|
|
bool maintainAspect = (psMode == "1");
|
|
|
|
|
|
|
|
TQSize s = maxPageSize();
|
|
|
|
|
|
|
|
double wAspect = double(s.width()) / double(img->width());
|
|
|
|
double hAspect = double(s.height()) / double(img->height());
|
|
|
|
|
|
|
|
// take the smaller one.
|
|
|
|
double aspect = wAspect;
|
|
|
|
if( hAspect < wAspect ) aspect = hAspect;
|
|
|
|
|
|
|
|
// default: maintain aspect ratio.
|
|
|
|
int newWidth = int( double( img->width() ) * aspect );
|
|
|
|
int newHeight = int( double( img->height()) * aspect );
|
|
|
|
|
|
|
|
if( ! maintainAspect )
|
|
|
|
{
|
|
|
|
newWidth = int( double( img->width() ) * wAspect );
|
|
|
|
newHeight = int( double( img->height() ) * hAspect );
|
|
|
|
}
|
|
|
|
|
|
|
|
tmpImg = img->smoothScale(newWidth, newHeight, TQ_ScaleFree);
|
|
|
|
|
|
|
|
m_painter->drawImage( 0,0, tmpImg );
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void KookaPrint::drawMarkerAroundPoint( const TQPoint& p )
|
|
|
|
{
|
|
|
|
if( ! m_painter ) return;
|
|
|
|
const int len = 10;
|
|
|
|
|
|
|
|
m_painter->drawLine( p-TQPoint(len,0), p+TQPoint(len,0));
|
|
|
|
m_painter->drawLine( p-TQPoint(0,len), p+TQPoint(0,len));
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void KookaPrint::drawCutSign( const TQPoint& p, int num, MarkerDirection dir )
|
|
|
|
{
|
|
|
|
TQBrush saveB = m_painter->brush();
|
|
|
|
int start = 0;
|
|
|
|
const int radius=20;
|
|
|
|
|
|
|
|
TQColor brushColor( TQt::red );
|
|
|
|
int toffX=0;
|
|
|
|
int toffY=0;
|
|
|
|
TQString numStr = TQString::number(num);
|
|
|
|
|
|
|
|
TQFontMetrics fm = m_painter->fontMetrics();
|
|
|
|
int textWidth = fm.width( numStr )/2;
|
|
|
|
int textHeight = fm.width( numStr )/2;
|
|
|
|
int textYOff = 0;
|
|
|
|
int textXOff = 0;
|
|
|
|
switch( dir )
|
|
|
|
{
|
|
|
|
case SW:
|
|
|
|
start = -90;
|
|
|
|
brushColor = TQt::green;
|
|
|
|
toffX =-1;
|
|
|
|
toffY = 1;
|
|
|
|
textXOff = -1*textWidth;
|
|
|
|
textYOff = textHeight;
|
|
|
|
break;
|
|
|
|
case NW:
|
|
|
|
start = -180;
|
|
|
|
brushColor = TQt::blue;
|
|
|
|
toffX =-1;
|
|
|
|
toffY =-1;
|
|
|
|
textXOff = -1*textWidth;
|
|
|
|
textYOff = textHeight;
|
|
|
|
break;
|
|
|
|
case NO:
|
|
|
|
start = -270;
|
|
|
|
brushColor = TQt::yellow;
|
|
|
|
toffX = 1;
|
|
|
|
toffY = -1;
|
|
|
|
textXOff = -1*textWidth;
|
|
|
|
textYOff = textHeight;
|
|
|
|
|
|
|
|
break;
|
|
|
|
case SO:
|
|
|
|
start = 0;
|
|
|
|
brushColor = TQt::magenta;
|
|
|
|
toffX = 1;
|
|
|
|
toffY = 1;
|
|
|
|
textXOff = -1*textWidth;
|
|
|
|
textYOff = textHeight;
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
start = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* to draw around the point p, subtraction of the half radius is needed */
|
|
|
|
int x = p.x()-radius/2;
|
|
|
|
int y = p.y()-radius/2;
|
|
|
|
|
|
|
|
// m_painter->drawRect( x, y, radius, radius ); /* debug !!! */
|
|
|
|
const int tAway = radius*3/4;
|
|
|
|
|
|
|
|
TQRect bRect = fm.boundingRect( TQString::number(num));
|
|
|
|
int textX = p.x()+ tAway * toffX + textXOff;
|
|
|
|
int textY = p.y()+ tAway * toffY + textYOff;
|
|
|
|
|
|
|
|
// m_painter->drawRect( textX, textY, bRect.width(), bRect.height() );
|
|
|
|
kdDebug(28000) << "Drawing to position " << textX << "/" << textY << endl;
|
|
|
|
m_painter->drawText( textX,
|
|
|
|
textY,
|
|
|
|
TQString::number(num));
|
|
|
|
TQBrush b( brushColor, NoBrush /* remove this to get debug color*/ );
|
|
|
|
|
|
|
|
|
|
|
|
m_painter->setBrush( b );
|
|
|
|
m_painter->drawPie( x, y, radius, radius, 16*start, -16*90 );
|
|
|
|
|
|
|
|
m_painter->setBrush( saveB );
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
* draws the circle and the numbers that indicate the pages to glue to the side
|
|
|
|
*/
|
|
|
|
void KookaPrint::drawCornerMarker( const TQSize& imgSize, int row, int col, int maxRows, int maxCols )
|
|
|
|
{
|
|
|
|
TQPoint p;
|
|
|
|
|
|
|
|
kdDebug(28000) << "Marker: Row: " << row << " and col " << col <<" from max "
|
|
|
|
<< maxRows << "x" << maxCols << endl;
|
|
|
|
|
|
|
|
// Top left.
|
|
|
|
p = printPosTopLeft( imgSize );
|
|
|
|
drawMarkerAroundPoint( p );
|
|
|
|
int indx = maxCols*row+col+1;
|
|
|
|
if( maxRows > 1 || maxCols > 1 )
|
|
|
|
{
|
|
|
|
if( col > 0 )
|
|
|
|
drawCutSign( p, indx-1, SW );
|
|
|
|
if( row > 0 )
|
|
|
|
drawCutSign( p, indx-maxCols, NO );
|
|
|
|
|
|
|
|
if( row > 0 && col > 0 )
|
|
|
|
drawCutSign( p, indx-maxCols-1, NW );
|
|
|
|
}
|
|
|
|
|
|
|
|
// Top Right
|
|
|
|
p = printPosTopRight( imgSize );
|
|
|
|
drawMarkerAroundPoint( p );
|
|
|
|
if( maxRows > 1 || maxCols > 1 )
|
|
|
|
{
|
|
|
|
if( col < maxCols-1 )
|
|
|
|
drawCutSign( p, indx+1, SO );
|
|
|
|
if( row > 0 )
|
|
|
|
drawCutSign( p, indx-maxCols, NW );
|
|
|
|
if( row > 0 && col < maxCols-1 )
|
|
|
|
drawCutSign( p, indx-maxCols+1, NO );
|
|
|
|
}
|
|
|
|
|
|
|
|
// Bottom Right
|
|
|
|
p = printPosBottomRight( imgSize );
|
|
|
|
if( maxRows > 1 || maxCols > 1 )
|
|
|
|
{
|
|
|
|
if( col < maxCols-1 )
|
|
|
|
drawCutSign( p, indx+1, NO );
|
|
|
|
if( row < maxRows-1 )
|
|
|
|
drawCutSign( p, indx+maxCols, SW );
|
|
|
|
if( row < maxRows -1 && col < maxCols-1 )
|
|
|
|
drawCutSign( p, indx+maxCols, SO );
|
|
|
|
}
|
|
|
|
|
|
|
|
// p += TQPoint( 1, 1 );
|
|
|
|
drawMarkerAroundPoint( p ); /* at bottom right */
|
|
|
|
|
|
|
|
/* Bottom left */
|
|
|
|
p = printPosBottomLeft( imgSize );
|
|
|
|
// p += TQPoint( -1, 1 );
|
|
|
|
if( maxRows > 1 || maxCols > 1 )
|
|
|
|
{
|
|
|
|
if( col > 0 )
|
|
|
|
drawCutSign( p, indx-1, NW );
|
|
|
|
if( row < maxRows-1 )
|
|
|
|
drawCutSign( p, indx+maxCols, SO );
|
|
|
|
if( row < maxRows -1 && col > 0 )
|
|
|
|
drawCutSign( p, indx+maxCols-1, SW );
|
|
|
|
}
|
|
|
|
drawMarkerAroundPoint( p ); /* at bottom left */
|
|
|
|
}
|
|
|
|
|
|
|
|
TQSize KookaPrint::maxPageSize( int extraShrinkPercent ) const
|
|
|
|
{
|
|
|
|
if( ! m_painter ) return TQSize();
|
|
|
|
TQPaintDeviceMetrics printermetrics( m_painter->device() );
|
|
|
|
|
|
|
|
double extraShrink = double(100-extraShrinkPercent)/100.0;
|
|
|
|
|
|
|
|
TQSize retSize( printermetrics.width(), printermetrics.height() );
|
|
|
|
|
|
|
|
if( extraShrinkPercent > 0 )
|
|
|
|
retSize = TQSize( int(double(printermetrics.width())* extraShrink) ,
|
|
|
|
int(double(printermetrics.height())* extraShrink ));
|
|
|
|
return retSize;
|
|
|
|
}
|
|
|
|
|
|
|
|
int KookaPrint::extraMarginPix() const
|
|
|
|
{
|
|
|
|
TQSize max = maxPageSize();
|
|
|
|
/* take the half extra margin */
|
|
|
|
return int(double(max.width())*double(m_extraMarginPercent) / 100.0 / 2.0);
|
|
|
|
}
|
|
|
|
|
|
|
|
TQPoint KookaPrint::printPosTopLeft( const TQSize& imgSize ) const
|
|
|
|
{
|
|
|
|
TQSize max = maxPageSize();
|
|
|
|
/* take the half extra margin */
|
|
|
|
int eMargin = extraMarginPix();
|
|
|
|
|
|
|
|
return TQPoint( eMargin + (max.width() - imgSize.width())/2,
|
|
|
|
eMargin + (max.height() - imgSize.height())/2 );
|
|
|
|
}
|
|
|
|
|
|
|
|
TQPoint KookaPrint::printPosTopRight(const TQSize& imgSize) const
|
|
|
|
{
|
|
|
|
TQSize max = maxPageSize();
|
|
|
|
/* take the half extra margin */
|
|
|
|
int eMargin = extraMarginPix();
|
|
|
|
|
|
|
|
return TQPoint( eMargin + (max.width() - imgSize.width())/2+imgSize.width(),
|
|
|
|
eMargin + (max.height() - imgSize.height())/2 );
|
|
|
|
}
|
|
|
|
|
|
|
|
TQPoint KookaPrint::printPosBottomLeft(const TQSize& imgSize) const
|
|
|
|
{
|
|
|
|
TQSize max = maxPageSize();
|
|
|
|
int eMargin = extraMarginPix();
|
|
|
|
/* take the half extra margin */
|
|
|
|
return TQPoint( eMargin+(max.width() - imgSize.width())/2,
|
|
|
|
eMargin+(max.height() - imgSize.height())/2 + imgSize.height() );
|
|
|
|
}
|
|
|
|
|
|
|
|
TQPoint KookaPrint::printPosBottomRight(const TQSize& imgSize) const
|
|
|
|
{
|
|
|
|
TQSize max = maxPageSize();
|
|
|
|
/* take the half extra margin */
|
|
|
|
int eMargin = extraMarginPix();
|
|
|
|
|
|
|
|
return TQPoint( eMargin+(max.width() - imgSize.width())/2 + imgSize.width(),
|
|
|
|
eMargin+(max.height() - imgSize.height())/2 + imgSize.height() );
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#include "kookaprint.moc"
|