/*************************************************************************** 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 #include #include #include #include "imgprintdialog.h" #include #include 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"